2

我在 ASP.NET MVC4 中调用第 3 方 SOAP 服务(Magento 网上商店)。导入 Web 服务引用时,所有服务方法都由 Visual Studio 自动实现,例如 login 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)

此标头告诉第 3 方用户代理是 IE6。许多网站会自动阻止 IE6,并显示“我们不支持 IE6。去换个真正的浏览器再试一次”的消息。

所以肥皂电话中断,但只是因为第 3 方网站认为我们正在使用 IE6,而不是因为肥皂电话有任何问题。如果我们可以更改此标头以模仿现代 Web 浏览器的 UA 字符串,那么此问题将不存在。

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

编辑:

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]));
    }

但是,这是自动生成的代码,并且会在第 3 方更新他们的服务时被覆盖(对于 Magento,它非常频繁),我必须手动将它添加到每个自动生成的函数(很多)中。所以只写在这里是不切实际的this.UserAgent = "not IE6",它需要一个更有用的解决方案。

4

2 回答 2

2

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

public class SuperWs: MyGeneratedWebService
{
    public SuperWs()
    {
        UserAgent = "Mozilla/5.0 (Killroy was here)";
    }
}
于 2014-06-08T07:45:18.873 回答
1

自动生成的类是部分类吗?

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

  • 公共部分类“GENERATEDCLASSNAME”{}

    并定义/覆盖构造函数。在此您可以设置您的 UserAgent。这是更新保存。

这段代码未经测试,是由我的大脑编写的。我现在不知道您是否必须从 SoapHttpClientProtocol 进行内击(请参阅评论)

例如

文件名:WsClass_partial.cs

public partial class WsClass /* :SoapHttpClientProtocol */ {
  public WsClass(string useragent):this(){
     this.UserAgent = useragent;
  }
}
于 2014-06-05T11:21:26.383 回答