如何在SoapHttpClientProtocol中设置User-Agent标头?

时间:2014-04-10 02:17:49

标签: 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,
                    apiKey});
        return ((string)(results[0]));
    }

但是当我调用此方法时,this.Invoke发送一个POST,并自动添加此用户代理标头:

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字符串呢?这一切都发生在this.Invoke方法内部,这是.NET核心的一部分。

编辑:

上面自动生成的代码中的对象thisSoapHttpClientProtocol的子类,所以我可以自己手动编写用户代理:

    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"是不切实际的,它需要是一个更有用的解决方案。

2 个答案:

答案 0 :(得分:2)

生成的Web Service引用类从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属性,所以你可以做的是再次从这个类派生并自定义这样的用户代理(这样你就可以自动替换新类的所有实例创建):

public class SuperWs: MyGeneratedWebService
{
    public SuperWs()
    {
        UserAgent = "Mozilla/5.0 (Killroy was here)";
    }
}

答案 1 :(得分:1)

自动生成的类是一个局部类吗?

当它是一个局部类时,你应该为生成的类创建一个自己的扩展,例如" myWebservice_partial.cs",将类重命名为:

  • 公共部分课" GENERATEDCLASSNAME" {}

    并定义/覆盖构造函数。在此范围内,您可以设置UserAgent。这是updatesave。

此代码未经测试并从我的大脑写入。我现在不知道你是否需要从SoapHttpClientProtocol中获取内心(见评论)

E.G。

FileName:WsClass_partial.cs

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