使用显式命名空间规范序列化SOAP消息

时间:2018-11-12 13:38:38

标签: c# xml wcf soap .net-core

我有一些非常基本的svcutil自动生成的类。

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
[System.ServiceModel.MessageContractAttribute(IsWrapped=false)]
public partial class YoRequest
{

    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="urn:something:important", Order=0)]
    public YoInner YoInner;

    public YoRequest()
    {
    }

    public YoRequest(YoInner YoInner)
    {
        this.YoInner = YoInner;
    }
}

 [System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:something:important")]
public partial class YoInner
{

    private YoClass contactField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
    public YoClass Contact
    {
        get
        {
            return this.contactField;
        }
        set
        {
            this.contactField = value;
        }
    }
}

 [System.CodeDom.Compiler.GeneratedCodeAttribute("svcutil", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:something:important")]
public partial class YoClass
{

    private string accountIdField;
    // a bunch more fields here 

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, Order=0)]
    public string AccountId
    {
        get
        {
            return this.accountIdField;
        }
        set
        {
            this.accountIdField = value;
        }
    }
}

我尝试使用WCF客户端,但是在Kestrel下,这似乎阻止了所有传入请求,直到完成一项操作为止。此外,在Linux上的性能相当可悲。相反,发送普通的HTTP请求非常快。

所以我的想法是自己将其序列化为SOAP并仅发送到外部服务。

但是,我无法为我的生命解决这个问题。

给出一个这样的实例:

var instance = new YoRequest
        {
            YoInner = new YoInner
            {
                Contact = new YoClass
                {
                    AccountId = "1234"
                }
            }
        };

我需要获取以下XML(并且外部服务非常特殊,它不接受内联xmlns,我需要提供此确切值)

<env:Envelope xmlns:urn="urn:something:important" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
  <env:Header/>
  <env:Body>
    <urn:YoInner>
      <Contact>
        <AccountId>1234</AccountId>
      </Contact>
    </urn:YoInner>
  </env:Body>
</env:Envelope>

我有数百个自动生成的类,例如YoRequest。我无法修改它们的属性。

我可以这样获得XML

<?xml version="1.0"?>
<Envelope xmlns:urn="urn:something:important" xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Header />
  <Body d2p1:type="YoRequest" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance">
    <YoInner xmlns="">
      <Contact>
        <AccountId>1234</AccountId>
      </Contact>
    </YoInner>
  </Body>
</Envelope>

使用以下代码:

 public class Header { }
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
    public class SoapE
    {
        [XmlElement("Header")]
        public Header Header { get; set; }

        [XmlElement("Body")]
        public object Body { get; set; }
    }

        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
        ns.Add("urn", "urn:something:important");
        XmlSerializer mySerializer = new XmlSerializer(typeof(SoapE), new []{typeof(YoRequest)});
        var ms = new MemoryStream();
        var env = new SoapE { Body = instance, Header = new Header() };

        mySerializer.Serialize(ms, env, ns);

        var stuff = Encoding.UTF8.GetString(ms.ToArray());
       //now stuff contains the string i show above

但是,这不是我想要的:/

1 个答案:

答案 0 :(得分:0)

使用msdn工具xsd.exe,自动生成soap头必须来自xml顶部的架构URL才能生成以下类。您必须通过将自定义类放置在anyField或anyAttrField中来添加它们(请注意:这些是数组)。

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.42000
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System.Xml.Serialization;

// 
// This source code was auto-generated by xsd, Version=4.0.30319.33440.
// 


/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://schemas.xmlsoap.org/soap/envelope/", IsNullable=false)]
public partial class Envelope {

    private Header headerField;

    private Body bodyField;

    private System.Xml.XmlElement[] anyField;

    private System.Xml.XmlAttribute[] anyAttrField;

    /// <remarks/>
    public Header Header {
        get {
            return this.headerField;
        }
        set {
            this.headerField = value;
        }
    }

    /// <remarks/>
    public Body Body {
        get {
            return this.bodyField;
        }
        set {
            this.bodyField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAnyElementAttribute()]
    public System.Xml.XmlElement[] Any {
        get {
            return this.anyField;
        }
        set {
            this.anyField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAnyAttributeAttribute()]
    public System.Xml.XmlAttribute[] AnyAttr {
        get {
            return this.anyAttrField;
        }
        set {
            this.anyAttrField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://schemas.xmlsoap.org/soap/envelope/", IsNullable=false)]
public partial class Header {

    private System.Xml.XmlElement[] anyField;

    private System.Xml.XmlAttribute[] anyAttrField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAnyElementAttribute()]
    public System.Xml.XmlElement[] Any {
        get {
            return this.anyField;
        }
        set {
            this.anyField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAnyAttributeAttribute()]
    public System.Xml.XmlAttribute[] AnyAttr {
        get {
            return this.anyAttrField;
        }
        set {
            this.anyAttrField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
public partial class detail {

    private System.Xml.XmlElement[] anyField;

    private System.Xml.XmlAttribute[] anyAttrField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAnyElementAttribute()]
    public System.Xml.XmlElement[] Any {
        get {
            return this.anyField;
        }
        set {
            this.anyField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAnyAttributeAttribute()]
    public System.Xml.XmlAttribute[] AnyAttr {
        get {
            return this.anyAttrField;
        }
        set {
            this.anyAttrField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://schemas.xmlsoap.org/soap/envelope/", IsNullable=false)]
public partial class Body {

    private System.Xml.XmlElement[] anyField;

    private System.Xml.XmlAttribute[] anyAttrField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAnyElementAttribute()]
    public System.Xml.XmlElement[] Any {
        get {
            return this.anyField;
        }
        set {
            this.anyField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAnyAttributeAttribute()]
    public System.Xml.XmlAttribute[] AnyAttr {
        get {
            return this.anyAttrField;
        }
        set {
            this.anyAttrField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://schemas.xmlsoap.org/soap/envelope/", IsNullable=false)]
public partial class Fault {

    private System.Xml.XmlQualifiedName faultcodeField;

    private string faultstringField;

    private string faultactorField;

    private detail detailField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public System.Xml.XmlQualifiedName faultcode {
        get {
            return this.faultcodeField;
        }
        set {
            this.faultcodeField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string faultstring {
        get {
            return this.faultstringField;
        }
        set {
            this.faultstringField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified, DataType="anyURI")]
    public string faultactor {
        get {
            return this.faultactorField;
        }
        set {
            this.faultactorField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public detail detail {
        get {
            return this.detailField;
        }
        set {
            this.detailField = value;
        }
    }
}