Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在SoapHttpClientProtocol中设置用户代理头?_C#_Asp.net Mvc_Soap_User Agent_Soaphttpclientprotocol - Fatal编程技术网

C# 如何在SoapHttpClientProtocol中设置用户代理头?

C# 如何在SoapHttpClientProtocol中设置用户代理头?,c#,asp.net-mvc,soap,user-agent,soaphttpclientprotocol,C#,Asp.net Mvc,Soap,User Agent,Soaphttpclientprotocol,我正在调用ASP.NET MVC4中的第三方SOAP服务(Magento webstore)。导入web服务引用时,所有服务方法都由Visual Studio自动实现,例如登录soap方法实现为 public string login(string username, string apiKey) { object[] results = this.Invoke("login", new object[] { username,

我正在调用ASP.NET MVC4中的第三方SOAP服务(Magento webstore)。导入web服务引用时,所有服务方法都由Visual Studio自动实现,例如登录soap方法实现为

    public string login(string username, string apiKey) {
        object[] results = this.Invoke("login", new object[] {
                    username,
                    apiKey});
        return ((string)(results[0]));
    }
但是当我调用此方法时,
this.Invoke
发送一篇帖子,其中自动添加了此用户代理标题:

User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; 
            MS Web Services Client Protocol 4.0.30319.18444)
此标头告诉第三方用户代理是IE6。许多网站会自动屏蔽IE6,并显示一条消息,大意是“我们不支持IE6。去买一个真正的浏览器,再试一次”

所以soap调用中断,但这只是因为第三方站点认为我们正在使用IE6,而不是因为soap调用有任何问题。如果我们可以改变这个标题来模仿现代web浏览器的UA字符串,那么这个问题就不存在了

那么,如何更改SoapHttpClientProtocol方法调用所使用的UA字符串呢?这一切都发生在.NET核心的
this.Invoke方法内部

编辑:

上面自动生成的代码中的对象
this
SoapHttpClientProtocol
的子类,因此是的,我可以自己在其中手动编写用户代理:

    public string login(string username, string apiKey) {
        this.UserAgent = "something, anything except for IE6";
        object[] results = this.Invoke("login", new object[] {
                    username,
                    apiKey});
        return ((string)(results[0]));
    }

但是,这是自动生成的代码,在第三方更新其服务时会被覆盖(对于Magento来说,这是非常频繁的),我必须手动将其添加到每个自动生成的函数中(很多)。因此,在这里编写
this.UserAgent=“not IE6”
是不实际的,它需要一个更有用的解决方案。

自动生成的类是部分类吗

当它是一个分部类时,您应该为生成的类创建自己的扩展,如“myWebservice_partial.cs”,将该类重命名为:

  • 公共部分类“GENERATEDCLASSNAME”{}

    并定义/重写构造函数。您可以在其中设置UserAgent。这是updatesave

这段代码没有经过测试,是从我的脑子里写出来的。我现在不知道你是否必须从SoapHttpClientProtocol进行innerhit(见评论)

例如

文件名:WsClass_partial.cs

public partial class WsClass /* :SoapHttpClientProtocol */ {
  public WsClass(string useragent):this(){
     this.UserAgent = useragent;
  }
}

生成的Web服务引用类本身派生自SoapHttpClientProtocol,如下所示:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "4.0.30319.18408")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="MyGeneratedWebServiceSoap", Namespace="http://www.killroy.com/webservices/")]
public partial class MyGeneratedWebService : System.Web.Services.Protocols.SoapHttpClientProtocol
{
    ...
}
SoapHttpClientProtocol有一个读/写UserAgent属性,因此您可以再次从该类派生并像这样自定义用户代理(这样您可以自动用新类替换原始类的所有实例创建):


我可能忽略了一些东西,但是SoapHttpClientProtocol有一个读/写UserAgent属性:@SimonMourier抱歉,我没有解释清楚为什么我没有这么做。问题现在更新了为什么在实例化WebService生成的类时不能更改属性,而不对生成的代码进行任何更改?您也可以从类中派生。@SimonMourier我还想避免每次实例化(DRY等)时都必须指定UA字符串,但派生是一个好主意,可以工作-子类可以将UA写入构造函数,最后一个解决方案是使用反射攻击HttpWebClientProtocol,并在任何web服务实例化之前更改默认的用户代理字符串。这当然不受支持:
typeof(HttpWebClientProtocol).GetField(“UserAgentDefault”,bindingsflags.Static | bindingsflags.NonPublic).SetValue(null,“我的用户代理”)
public class SuperWs: MyGeneratedWebService
{
    public SuperWs()
    {
        UserAgent = "Mozilla/5.0 (Killroy was here)";
    }
}