我的理解可能是错误的,但我认为一旦你应用了正确的属性,DataContractSerializer就会将完全限定的实例呈现给调用者。
代码运行,对象返回。但奇怪的是,一旦我看到返回的对象,我注意到命名空间消失了,通过(Web应用程序)服务引用公开的对象层次似乎变得“平坦”(不知何故)。现在,我希望这可以来自网络服务......但不是通过WCF。当然,我对WCF可以做什么的理解可能是错误的。
...请记住我还在尝试所有这些。
所以我的问题是......
问:我可以在WCF服务中做些什么来强制命名空间通过(服务引用)数据客户端代理进行渲染吗? 问:或者,或许,我(仅仅)不正确地使用该服务? 问:这甚至可能吗?服务代码看起来像......
[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;
}
}
如果我不清楚......
出现的问题是我希望看到(返回)的命名空间与实际返回的命名空间不同。
fishProject.ObjectState应该看起来像......
srFish.StateManagement.Project.New
fishC1FE.ObjectState应该看起来像......
srFish.StateManagement.C1FE.New
fishProject.ObjectState ACTUALLY看起来像......
srFish.New1
fishC1FE.ObjectState ACTUALLY看起来像......
srFish.New
答案 0 :(得分:4)
确定 - WCF服务的默认行为是:
svcutil.exe
所做的是询问该服务的元数据(服务方法和数据的描述)重要提示:它包含副本这些内容!它们看起来一样,并且它们在网络上序列化为相同的XML格式 - 但它们是不同的 - 在不同的名称空间中,最值得注意的是。
这就是WCF的本质 - 您所做的就是在客户端和服务器之间交换序列化消息 - 所有来回的都是文本消息。没有更多 - 没有对象引用,没有远程对象 - 没有这样的东西。把它扔出你的脑海! :-)
如果您控制电线的两端,这可能会很痛苦 - 如果您需要更改任何内容,则必须在服务器端更改它,更新客户端引用等等。
因此,如果您控制线路的两端 - 服务器和客户端 - 并且它们都是基于.NET的,您可以执行以下操作:
现在,如果添加服务引用,默认情况下,Visual Studio中的Add Service Reference
函数将重用引用程序集中的现有类型 - 因此,如果您引用了常用的“Contracts”程序集,那么这些类型(在它们的将重用荣耀,包括其命名空间 - 不会创建额外的副本。
这样,您可以创建服务器端代码以及客户端使用的单个共享契约程序集,并且您不必混淆数据结构的任何重复。但同样:只有在控制线的两端并且两者都是.NET
时才有效