首页 新闻 会员 周边

System.Web.Services.Protocols.SoapHeader用法求解

0
悬赏园豆:20 [已解决问题] 解决于 2014-09-22 17:07

目标服务是https://svcs.paypal.com/RiskAssessment/SetTransactionContext?wsdl

里面的SetTransactionContext方法要求添加SOAPheader

三个参数分别是

X-PAYPAL-SECURITY-USERID

X-PAYPAL-SECURITY-PASSWORD

X-PAYPAL-SECURITY-SIGNATURE

看了好多例子都是直接设置属性名然后赋值就可以了

可是这三参数里面带破折号。C#的属性名称不允许出现破折号。

现在想的是可不可以用二维数组或者Dictionary<string,string>添加key和value来实现?

我这边查了资料没有发现这样的例子。求大家帮帮忙!

问题补充:

主要问题是属性名不允许出现 - 破折号,可是文档里面要求的header标签是带 - 破折号的。想怎么避开解决这个问题!

lpyedge的主页 lpyedge | 菜鸟二级 | 园豆:330
提问于:2014-09-16 17:18
< >
分享
最佳答案
0

header本身就是一个字典,直接对字典赋值就好。

从你的需求看,问题应该也是要求给http请求数据的header添加内容的。

收获园豆:20
519740105 | 大侠五级 |园豆:5810 | 2014-09-16 18:40

header的设置,是不是用属性名的方式设置的,可以用字典来控制,字典,难道不允许用破折号?

519740105 | 园豆:5810 (大侠五级) | 2014-09-17 12:34

@519740105: 就是不知道怎么用字典来控制呢。。。

没找到相关的例子

可以给出示例么。麻烦你了!

lpyedge | 园豆:330 (菜鸟二级) | 2014-09-17 13:02

@lpyedge: 把你的贴出来,我看看。

519740105 | 园豆:5810 (大侠五级) | 2014-09-17 13:43

@519740105: 

[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.17929")]
            [System.SerializableAttribute()]
            [System.Diagnostics.DebuggerStepThroughAttribute()]
            [System.ComponentModel.DesignerCategoryAttribute("code")]
            [System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://svcs.paypal.com/services")]
            [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://svcs.paypal.com/services", IsNullable = false)]
            public partial class MyHeader : System.Web.Services.Protocols.SoapHeader
            {
                /// <remarks/>
                public System.Collections.Generic.Dictionary<string,string> headers { get; set; }

            }

 

[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.17929")]
            [System.Diagnostics.DebuggerStepThroughAttribute()]
            [System.ComponentModel.DesignerCategoryAttribute("code")]
            [System.Web.Services.WebServiceBindingAttribute(Name = "RiskAssessmentSOAP11Binding", Namespace = "http://svcs.paypal.com/services")]
            public partial class RiskAssessment : System.Web.Services.Protocols.SoapHttpClientProtocol
            {
                
                public MyHeader shead { get; set; } 

                private System.Threading.SendOrPostCallback SetTransactionContextOperationCompleted;

                /// <remarks/>
                public RiskAssessment()
                {
                    this.Url = "https://svcs.paypal.com/RiskAssessment";
                }

                /// <remarks/>
                public event SetTransactionContextCompletedEventHandler SetTransactionContextCompleted;

                /// <remarks/> 
                [System.Web.Services.Protocols.SoapHeaderAttribute("shead")]
                [System.Web.Services.Protocols.SoapDocumentMethodAttribute("urn:SetTransactionContext", RequestElementName = "SetTransactionContextRequest", RequestNamespace = "http://svcs.paypal.com/types/pt", ResponseNamespace = "http://svcs.paypal.com/types/pt", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
                [return: System.Xml.Serialization.XmlElementAttribute("responseEnvelope", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
                public ResponseEnvelope SetTransactionContext([System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] RequestEnvelope requestEnvelope, [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] ref string trackingId, [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] ref Account senderAccount, [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] ref Account receiverAccount, [System.Xml.Serialization.XmlArrayAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] [System.Xml.Serialization.XmlArrayItemAttribute("subOrder", Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = false)] ref SubOrder[] subOrders, [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] ref Device device, [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] ref IpAddress ipAddress, [System.Xml.Serialization.XmlArrayAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] [System.Xml.Serialization.XmlArrayItemAttribute("pair", Form = System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable = false)] ref Pair[] additionalData)
                {
                    object[] results = this.Invoke("SetTransactionContext", new object[] {
                    requestEnvelope,
                    trackingId,
                    senderAccount,
                    receiverAccount,
                    subOrders,
                    device,
                    ipAddress,
                    additionalData});
                    trackingId = ((string)(results[1]));
                    senderAccount = ((Account)(results[2]));
                    receiverAccount = ((Account)(results[3]));
                    subOrders = ((SubOrder[])(results[4]));
                    device = ((Device)(results[5]));
                    ipAddress = ((IpAddress)(results[6]));
                    additionalData = ((Pair[])(results[7]));
                    return ((ResponseEnvelope)(results[0]));
                }


我用的Dictionary。可是运行的时候报错:

无法序列化 System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] 类型的成员 Payments.PaypalExpress+PaypalSetTransactionContext+MyHeader.headers,因为它实现 IDictionary。

lpyedge | 园豆:330 (菜鸟二级) | 2014-09-17 13:48

@lpyedge: 好久没弄WebService了,这个还真的~~~

我是直接在项目里添加服务引用的,发现代码并非象你这样,因此也没办法验证。

我强制性的把你的部分代码放进去,在调用的时候,也没发现有提交SoapHeader的内容(Fiddler2跟踪)。

给你个建议:

对于属性名为非C#规范的,可以通过强制设置属性名来实现,如:

            [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.17929")]
            [System.SerializableAttribute()]
            [System.Diagnostics.DebuggerStepThroughAttribute()]
            [System.ComponentModel.DesignerCategoryAttribute("code")]
            [System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://svcs.paypal.com/services")]
            [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://svcs.paypal.com/services", IsNullable = false)]
            public partial class MyHeader : System.Web.Services.Protocols.SoapHeader
            {
                /// <remarks/>
                [System.Xml.Serialization.SoapAttribute("X-PAYPAL-SECURITY-USERID")]
                public string X_PAYPAL_SECURITY_USERID { get; set; }

                [System.Xml.Serialization.SoapAttribute("X-PAYPAL-SECURITY-PASSWORD")]
                public string X_PAYPAL_SECURITY_PASSWORD { get; set; }
                [System.Xml.Serialization.SoapAttribute("X-PAYPAL-SECURITY-SIGNATURE")]
                public string X_PAYPAL_SECURITY_SIGNATURE { get; set; }
            }
519740105 | 园豆:5810 (大侠五级) | 2014-09-17 15:00

@519740105: 

还是不行,我用Fiddler2跟踪,发送的SoapHeader内容如下:

<soap:Header>
<MyHeader xmlns="http://svcs.paypal.com/services">
<X_PAYPAL_SECURITY_USERID>*****************</X_PAYPAL_SECURITY_USERID>
<X_PAYPAL_SECURITY_PASSWORD>*****************</X_PAYPAL_SECURITY_PASSWORD>
<X_PAYPAL_SECURITY_SIGNATURE>*****************</X_PAYPAL_SECURITY_SIGNATURE>
</MyHeader>
</soap:Header>


首先多了个MyHeader的标签?然后是序列化的时候强制设置属性名没有效果!

lpyedge | 园豆:330 (菜鸟二级) | 2014-09-17 15:16

@lpyedge: 

1、下划线的问题,可以换其它的特性(system.xml.serialization名称空间里以xml开头的)试下

2、至于myheader节点,这个要看你的实际需求(咨询对方)了,应该定义成什么样子:

2.1、如果你是希望把MyHeader节点的名字换一个,那么在定义MyHeader类的时候可以指定(好像是XmlRoot特性),好像也可以在你定义 MyHeader shead 的地方对这个变量进行指定(这个未验证过)

2.2、如果是希望把x-系列的数据直接放置在soap:Header下,那么:

2.2.1、每个x-参数要单独定义一个变量在调用类里,然后对这个变量(属性)通过2.1的方案指定XML节点名达到目的

2.2.2、至于内容,你可以随意定义一个属性,比如Value、MyValue之类的,把属性的Xml特性定义为XmlContent。

public class MyHeader : SoapHeader
{
    [XmlContent]
    public string Value{get;set;}
}

public class RiskAssement: xx
{
    [XmlProperty("X-aaa-ddd")]
    public X_aaa_ddd{get;set;}
}
519740105 | 园豆:5810 (大侠五级) | 2014-09-17 15:29

@lpyedge: 刚把你的代码复制,实验了一下:

1、如果你希望MyHeader继续出现,只是名字不同的话,可以通过对MyHeader类定义XmlRoot来解决。

2、如果你希望x-系列属性也要放到SoapHeader下,那就~~~需要对每个属性单独定义类,再使用XmlRoot来定义,并且在定义的类里,使用XmlText来只能属性的值是内容。

519740105 | 园豆:5810 (大侠五级) | 2014-09-17 15:51

@519740105: 终于按照我的理解实现功能了

  [System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "4.0.30319.17929")]
            [System.SerializableAttribute()]
            [System.Diagnostics.DebuggerStepThroughAttribute()]
            [System.ComponentModel.DesignerCategoryAttribute("code")]
            [System.Xml.Serialization.XmlTypeAttribute(Namespace = "")]
            [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false, ElementName = "X-PAYPAL-SECURITY-SIGNATURE")]
            public partial class X_PAYPAL_SECURITY_SIGNATURE : System.Web.Services.Protocols.SoapHeader
            {
                [System.Xml.Serialization.XmlText()]
                public string Value { get; set; }
            }

可是结果发送过去还是报错,后来和paypal那边的技术一沟通,那边说是要在SoapHttpClientProtocol的http Header里面加上这三个参数。郁闷死了。

大侠再求助一下,怎么给SoapHttpClientProtocol动态添加http header啊?没有发现对应的方法和属性呢?

lpyedge | 园豆:330 (菜鸟二级) | 2014-09-19 17:11

@lpyedge: 找!在你执行Invoke的时候,想办法获取HTTP请求对象(一般类型是HttpRequest或WebRequest之类的),有了这个,就能发现有一个集合属性Headers了,而这个Headers不过是一个字典而已(至少是一个可以当字典使用的集合)。

519740105 | 园豆:5810 (大侠五级) | 2014-09-19 17:20
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册