WCF服务返回的对象层次结构与预期不同 [英] Object hierarchy returned by WCF Service is different than expected
问题描述
我的理解可能是错误的,但我认为一旦你应用了正确的属性,DataContractSerializer就会将完全限定的实例呈现给调用者。
My understanding may be wrong, but I thought once you applied the correct attributes the DataContractSerializer would render fully-qualified instances back to the caller.
代码运行和对象返回。但奇怪的是,一旦我看到返回的对象,我注意到命名空间消失了,通过(Web应用程序)服务引用公开的对象层次似乎变得平坦(不知何故)。现在,我希望这可以来自网络服务......但不是通过WCF。当然,我对WCF可以做什么的理解可能是错误的。
The code runs and the objects return. But oddly enough, once I look at the returned objects I noticed the namespacing disappeared and the object-hierarchy being exposed through the (web applications) service reference seems to become "flat" (somehow). Now, I expect this from a web-service…but not through WCF. Of course, my understanding of what WCF can do may be wrong.
...请记住我还在尝试所有这些。
所以我的问题是...
问:我可以做些什么在WCF服务中强制命名空间通过(服务引用)数据客户端代理呈现?
Q: Can I do something within the WCF Service to force the namespacing to render through the (service reference) data client proxy?
问:或许,我(仅仅)正在消费该服务?
Q: Or perhaps, am I (merely) consuming the service incorrectly?
问:这是否均匀可能吗?
Q: Is this even possible?
服务代码看起来像......
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class DataService : IFishData
{
public C1FE GetC1FE(Int32 key)
{
//… more stuff here …
}
public Project GetProject(Int32 key)
{
//… more stuff here …
}
}
[ServiceContract]
[ServiceKnownType(typeof(wcfFISH.StateManagement.C1FE.New))]
[ServiceKnownType(typeof(wcfFISH.StateManagement.Project.New))]
public interface IFishData
{
[OperationContract]
C1FE GetC1FE(Int32 key);
[OperationContract]
Project GetProject(Int32 key);
}
[DataContract]
[KnownType(typeof(wcfFISH.StateManagement.ObjectState))]
public class Project
{
[DataMember]
public wcfFISH.StateManagement.ObjectState ObjectState { get; set; }
//… more stuff here …
}
[DataContract]
KnownType(typeof(wcfFISH.StateManagement.ObjectState))]
public class C1FE
{
[DataMember]
public wcfFISH.StateManagement.ObjectState ObjectState { get; set; }
//… more stuff here …
}
[DataContract(Namespace = "wcfFISH.StateManagement")]
[KnownType(typeof(wcfFISH.StateManagement.C1FE.New))]
[KnownType(typeof(wcfFISH.StateManagement.Project.New))]
public abstract class ObjectState
{
//… more stuff here …
}
[DataContract(Namespace = "wcfFISH.StateManagement.C1FE", Name="New")]
[KnownType(typeof(wcfFISH.StateManagement.ObjectState))]
public class New : ObjectState
{
//… more stuff here …
}
[DataContract(Namespace = "wcfFISH.StateManagement.Project", Name = "New")]
[KnownType(typeof(wcfFISH.StateManagement.ObjectState))]
public class New : ObjectState
{
//… more stuff here …
}
Web应用程序代码看起来像......
public partial class Fish_Invite : BaseForm
{
protected void btnTest_Click(object sender, EventArgs e)
{
Project project = new Project();
project.Get(base.ProjectKey, base.AsOf);
mappers.Project mapProject = new mappers.Project();
srFish.Project fishProject = new srFish.Project();
srFish.FishDataClient fishService = new srFish.FishDataClient();
mapProject.MapTo(project, fishProject);
fishProject = fishService.AddProject(fishProject, IUser.UserName);
project = null;
}
}
如果我不清楚...
出现的问题是我希望看到(返回)的命名空间与实际返回的命名空间不同。
The issue arises in that the namespacing I expect to see (returned) is different from what is actually returned.
fishProject.ObjectState应该看起来像......
srFish.StateManagement.Project.New
srFish.StateManagement.Project.New
fishC1FE.ObjectState应该看起来像......
srFish.StateManagement.C1FE.New
srFish.StateManagement.C1FE.New
fishProject.ObjectState ACTUALLY看起来像......
srFish.New1
srFish.New1
fishC1FE.ObjectState ACTUALLY看起来像......
srFish.New
srFish.New
推荐答案
确定 - WCF服务的默认行为是:
OK - default behavior for a WCF Service is this:
- 一旦服务启动,您就可以在服务器上定义服务合同,操作和数据合同(例如在命名空间Server.MyService)
- 运行,在您的客户端上,您创建服务引用
- 这样做,Visual Studio或
svcutil.exe
做什么,是询问该服务的元数据(服务方法和数据的描述) - 基于该元数据,生成客户端代理(名称空间Client.MyService)并且它包含服务的副本合同(方法)和数据合同
- you define your service contracts, operations, and data contract on the server (e.g. in namespace "Server.MyService")
- once the service is up and running, on your client, you create a service reference
- when doing so, what Visual Studio or
svcutil.exe
do, is interrogate that service for its metadata (description of service methods and data) - based on that metadata, the client side proxy is generated (namespace "Client.MyService") and it contains replicas of the service contract (the methods) and the data contract
重要提示:它包含那些东西的副本!它们看起来是一样的,它们在线上串行化为相同的XML格式 - 但它们是不同的 - 在不同的命名空间中,最值得注意的是。
Important: it contains replicas of those things! They look the same, and they serialize into the same XML format on the wire - but they are different - in different namespaces, most notably.
这就是它的本质WCF - 您所做的只是在客户端和服务器之间交换序列化消息 - 所有来回的都是文本消息。没有更多 - 没有对象引用,没有远程对象 - 没有这样的东西。把它扔出你的脑海! :-)
This is the very nature of WCF - all you do is exchange serialized messages between client and server - all that goes back and forth are textual messages. Nothing more - no object references, no remote object - nothing like that. Toss that out of your mind! :-)
如果您控制电线的两端,这可能会很痛苦 - 如果您需要更改任何内容,则必须在服务器端更改它,更新客户端引用等等。
If you control both ends of the wire, this can be a pain - if you need to change anything, you have to change it on the server side, update the client references and so forth.
因此,如果您控制线路的两端 - 服务器和客户端 - 并且它们都是基于.NET的,那么您可以执行以下操作:
So if you control both ends of the wire - both the server and the client - and they're both .NET based, you can do the following:
- 将您的服务合同和数据合同(仅合同 - 无实施!)放入单独的程序集中
- 来自您的服务实现,合同程序集的引用
- 将合同程序集复制到您的客户端,并在您的客户项目中引用它
现在,如果添加服务引用,默认情况下,Visual中的添加服务引用
函数Studio将在引用的程序集中重用现有类型 - 因此,如果您引用了常见的Contracts程序集,那么这些类型(完整的荣耀,包括它们的名称空间) )将被重用 - 不会创建额外的副本。
Now, if you add the service reference, by default, the Add Service Reference
function in Visual Studio will reuse existing types in referenced assemblies - so if you have referenced your common "Contracts" assembly, those types (in their full glory, including their namespace) will be reused - no additional copies will be created.
这样,您可以创建服务器端代码使用的单个共享契约程序集,以及您的客户,您不必混淆任何重复的数据结构。但是又一次:只有当你控制线的两端,并且两者都是.NET
That way, you can create a single, shared contracts assembly used by both the server side code, as well as your client, and you don't have to mess with any duplication of data structures. But again: that only works if you are in control of both ends of the wire, and both are .NET
这篇关于WCF服务返回的对象层次结构与预期不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!