Используя отражение для вызова веб-сервиса ASP.NET

Указатель NULL - это тот, который указывает на никуда. Когда вы разыскиваете указатель p, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p является нулевым указателем, местоположение, хранящееся в p, является nowhere, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception.

В общем, это потому, что что-то не было правильно инициализировано.

7
задан Dave Ward 15 September 2008 в 12:32
поделиться

8 ответов

Я не уверен, было ли это лучшим способом пойти об этом. Самый очевидный путь ко мне, состоял бы в том, чтобы сделать Запрос HTTP и звонить, веб-сервис с помощью фактического HTTP ДОБИРАЮТСЯ или POST. Используя Ваш метод, я не совсем уверен, как Вы настроили данные, которые Вы отправляете в веб-сервис. Я добавил некоторый пример кода в VB.Net

Dim HTTPRequest As HttpWebRequest
Dim HTTPResponse As HttpWebResponse
Dim ResponseReader As StreamReader
Dim URL AS String
Dim ResponseText As String

URL = "http://www.example.com/MyWebSerivce/MyMethod?arg1=A&arg2=B"

HTTPRequest = HttpWebRequest.Create(URL)
HTTPRequest.Method = "GET"

HTTPResponse = HTTPRequest.GetResponse()

ResponseReader = New StreamReader(HTTPResponse.GetResponseStream())
ResponseText = ResponseReader.ReadToEnd()
2
ответ дан 7 December 2019 в 10:10
поделиться

// Try this ->

    Type t = System.Web.Compilation.BuildManager.GetType("MyServiceClass", true);
    object act = Activator.CreateInstance(t);                
    object o = t.GetMethod("hello").Invoke(act, null);
2
ответ дан 7 December 2019 в 10:10
поделиться

Вот быстрый ответ, на котором кто-то может, вероятно, подробно остановиться.

При использовании WSDL, обрабатывающего приложение по шаблону (WSDL.exe) к genereate сервисным оберткам это создает класс типа SoapHttpClientProtocol. Можно сделать это вручную, также:

public class MyService : SoapHttpClientProtocol
{
    public MyService(string url)
    {
        this.Url = url;
        // plus set credentials, etc.
    }

    [SoapDocumentMethod("{service url}", RequestNamespace="{namespace}", ResponseNamespace="{namespace}", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
    public int MyMethod(string arg1)
    {
        object[] results = this.Invoke("MyMethod", new object[] { arg1 });
        return ((int)(results[0]));
    }
}

Я не протестировал этот код, но я предполагаю, что он должен работать автономный, не имея необходимость выполнять инструмент WSDL.

Код, который я предоставил, является кодом вызывающей стороны, который сцепляется до веб-сервиса через удаленный вызов (даже если по любой причине, Вы на самом деле не хотите, чтобы он был удаленным.) Вызвать метод заботится об упаковке его как вызов Мыла. код Ward @Dave является правильным, если Вы хотите обойти вызов веб-сервиса через HTTP - пока Вы на самом деле можете сослаться на класс. Возможно, внутренний тип не является "MyService" - необходимо было бы осмотреть код управления для знания наверняка.

1
ответ дан 7 December 2019 в 10:10
поделиться

Хотя я не знаю, почему Отражение не работает на Вас там (я предполагаю, что компилятор мог бы создавать новый класс из Вашего [WebService] аннотации), вот некоторый совет, который мог бы решить Вашу проблему:

Сохраните свой WebService простым, мелким, короче говоря: реализация Шаблона Фасада.

Сделайте своего сервисного делегата вычислением к классу реализации, который должен легко быть вызываемым посредством Отражения. Таким образом, Ваш класс WebService является просто передней стороной для Вашей системы - можно даже добавить обработчик электронной почты, XML-RPC frontend и т.д., так как логика не связана с WebService, но с фактическим бизнес-расположенным на слое объектом.

Думайте о классах WebService как о расположенных на слое объектах UI в Вашей Архитектуре.

1
ответ дан 7 December 2019 в 10:10
поделиться

Хотя я не могу сказать из Вашего сообщения:

Одна вещь иметь в виду состоит в том, что при использовании отражения необходимо создать экземпляр автоматически сгенерированного класса веб-сервиса (тот, созданный из WSDL веб-сервиса). Не создавайте класс, который является responsbile для серверной стороны сервиса.

Таким образом, если у Вас есть веб-сервис

    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    public class WebService1 : System.Web.Services.WebService
    {
     ...
    }

Вы не можете сослаться на тот блок в своем клиенте и сделать что-то как:

WebService1  ws = new WebService1 ();
ws.SomeMethod();
0
ответ дан 7 December 2019 в 10:10
поделиться

@Kibbee: Я должен избежать хита производительности HTTP. Это не будет удаленный вызов, таким образом, все те добавленные издержки должны будут быть ненужными.

@Daren: Я определенно соглашаюсь с теми принципами проектирования. Проблема здесь - то, что я не собираюсь управлять сервисом или его базовой бизнес-логикой.

Это для управления сервером, которое должно будет выполниться против произвольного сервиса/метода, ортогонально к тому, как сам веб-сервис реализован.

0
ответ дан 7 December 2019 в 10:10
поделиться

@Radu: я могу создать экземпляр и назвать метод точно как этот. Например, если у меня есть этот ASMX:

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class MyService : System.Web.Services.WebService
{
  [WebMethod]
  public string HelloWorld()
  {
    return "Hello World";
  }
}

Я могу назвать его от codebehind страницы ASPX как это:

MyService service = new MyService();
Response.Write(service.HelloWorld());

Вы говорите, что это не должно работать?

0
ответ дан 7 December 2019 в 10:10
поделиться

Я оглянулся назад на этот вопрос, и я думаю, с чем Вы сталкиваетесь, то, что код ASMX будет встроен в DLL со случайным именем как часть динамической компиляции Вашего сайта. Ваш код для поиска типа будет, по умолчанию, только искать свой собственный блок (другой DLL App_Code, взглядами ошибки, которую Вы получили), и оперативные библиотеки. Вы могли обеспечить определенную ссылку на сборку "TypeName, AssemblyName" к GetType (), но это не возможно в случае автоматически сгенерированных блоков, которые имеют новые имена после того, как каждый перекомпилировал.

Решение.... Я не сделал этого сам прежде, но я полагаю, что необходимо смочь использовать что-то вроде этого:

System.Web.Compilation.BuildManager.GetType("MyService", true)

поскольку BuildManager знает о DLLs, который он создал и знает, где посмотреть.

Я предполагаю, что это действительно не имеет отношение к веб-сервисам, но если это был Ваш собственный код, Daren прямо о шаблонах Фасада.

0
ответ дан 7 December 2019 в 10:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: