C# 如何自定义WCF XML序列化

C# 如何自定义WCF XML序列化,c#,xml,wcf,serialization,xml-serialization,C#,Xml,Wcf,Serialization,Xml Serialization,我们有一个现有的soapweb服务接口,我们希望使用WCF为新的应用程序实现该接口。除了一个小细节外,这似乎工作得很好。函数返回类型的XML命名空间必须不同于web服务本身的XML命名空间。就我个人而言,我无法让它发挥作用 我用一个小样本项目重新创建了相同的问题。 WCF接口: [XmlSerializerFormat] [ServiceContract(Namespace = "urn:outer-namespace")] public interface IService1 { [O

我们有一个现有的soapweb服务接口,我们希望使用WCF为新的应用程序实现该接口。除了一个小细节外,这似乎工作得很好。函数返回类型的XML命名空间必须不同于web服务本身的XML命名空间。就我个人而言,我无法让它发挥作用

我用一个小样本项目重新创建了相同的问题。 WCF接口:

[XmlSerializerFormat]
[ServiceContract(Namespace = "urn:outer-namespace")]
public interface IService1
{
    [OperationContract]
    MyClass DoStuff(int value);
}

[Serializable]
public class MyClass
{
    [XmlElement(ElementName = "DataString")]
    public string MyString { get; set; }
}
[return:MessageParameter(Name = "whatIWantItNamed")]
web服务实现:

    public class Service1 : IService1
{
    public MyClass DoStuff(int value)
    {
        return new MyClass { MyString = "Wooh!" };
    }
}
然后将此Web服务的响应序列化为: (省略肥皂内容)


哇!
但是我们想要的是xmlns=“urn:内部名称空间”

我曾尝试在接口函数或web服务函数上添加[return:XmlElement(…)],但没有成功。此外,MyClass定义上的[XmlType]或[XmlRoot]也不起作用


有人知道如何更改作为WCF web服务函数返回值的对象的序列化XML命名空间(或元素名称)吗?

使用XML序列化(或更好的)数据协定定义属性定义命名空间

e、 g.使用XML序列化:

[Serializable, XmlRoot(namespace="http://example.com/eg1")]
public class MyClass {
  [XmlElement(ElementName = "DataString")]
  public string MyString { get; set; }
}
[DataContract(Namespace="http://example.com/eg2")]
public class MyClass {
  [DataMember]
  public string MyString { get; set; }
}
e、 g.数据合同序列化:

[Serializable, XmlRoot(namespace="http://example.com/eg1")]
public class MyClass {
  [XmlElement(ElementName = "DataString")]
  public string MyString { get; set; }
}
[DataContract(Namespace="http://example.com/eg2")]
public class MyClass {
  [DataMember]
  public string MyString { get; set; }
}

编辑

根据第一条注释,上面的方法行不通,因为我们希望在消息的SOAP包装器上设置名称空间,而不是在消息本身上

OperationContractAttribute
不提供对名称空间的控制,我在方法级别看不到任何其他WCF属性


有两种可能性:(1)通过降低抽象级别并使用消息契约,您可以拥有足够的控制权。(2) 获取服务的当前WSDL(使用
svcutil.exe
),手动调整它以获得所需的名称空间,然后再次使用
svcutil.exe
生成代码,并查看生成的代码。

经过数天的搜索和尝试几十种推荐解决方案后;我终于能够让WCF停止在web服务方法的名称后面附加
Result
的包装容器名称。诀窍是向web服务接口添加以下decorator属性:

[XmlSerializerFormat]
[ServiceContract(Namespace = "urn:outer-namespace")]
public interface IService1
{
    [OperationContract]
    MyClass DoStuff(int value);
}

[Serializable]
public class MyClass
{
    [XmlElement(ElementName = "DataString")]
    public string MyString { get; set; }
}
[return:MessageParameter(Name = "whatIWantItNamed")]
此属性应直接放置/定位在接口中的
[OperationContract]
属性之后(并且正好位于实际方法存根之前)


(我还需要将
XmlSerializerFormat
属性添加到所有
ServiceContract
OperationContract
属性中。)

就像我在问题中已经说过的那样,我尝试添加一个XmlRoot属性,但它不起作用。它只将名称空间添加到MyClass中的字段,而不添加到MyClass本身。DataContract也不起作用,我更喜欢XmlSerializer,因为重命名和顺序并不重要。我使用了svcutil,但没有指定序列化程序,它使用XmlSerializer生成了MessageContract和ServiceContract的组合。因此,它有一个或两个包装器,我仍然可以使用XML属性来实现这一切。