Как установить заголовок User-Agent в SoapHttpClientProtocol?

Я звоню стороннему SOAP-сервису (интернет-магазин Magento) в ASP.NET MVC4. При импорте ссылки на веб-службу все методы службы автоматически реализуются Visual Studio, например, метод мыла входа в систему реализуется как

    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. Получите настоящий браузер и попробуйте снова"

Поэтому мыльный вызов прерывается, но только потому, что сторонний сайт считает, что мы используем IE6, а не потому, что с мыльным вызовом что-то не так. Если бы мы могли изменить этот заголовок, чтобы имитировать строку UA современного веб-браузера, такой проблемы не было бы.

Так как же изменить строку UA, используемую при вызове метода SoapHttpClientProtocol? Все это происходит внутри 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]));
    }

НО, это автоматически сгенерированный код, который будет перезаписан в любое время, когда сторонняя сторона обновляет свой сервис (для Magento это довольно часто), и мне пришлось бы вручную добавлять его в каждую автоматически генерируемую функцию (многие из них). Так что не практично просто писать this.UserAgent = "not IE6" здесь должно быть более полезное решение.

2 ответа

Решение

Сгенерированный ссылочный класс веб-службы происходит от 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)";
    }
}

Является ли автоматически сгенерированный класс частичным классом?

Если это частичный класс, то вы должны создать собственное расширение для сгенерированного класса, например "myWebservice_partial.cs", переименовать класс в:

  • открытый частичный класс "GENERATEDCLASSNAME"{}

    и определить / переопределить конструктор. в этом вы можете установить свой UserAgent. Это обновления.

Этот код не проверен и написан из моего мозга. Сейчас я не знаю, нужно ли вам подключаться к нему из SoapHttpClientProtocol (см. Комментарий)

НАПРИМЕР

Имя файла: WsClass_partial.cs

public partial class WsClass /* :SoapHttpClientProtocol */ {
  public WsClass(string useragent):this(){
     this.UserAgent = useragent;
  }
}
Другие вопросы по тегам