Динамический C # .NET Webservice - PullRequest
7 голосов
/ 31 мая 2009

Я использую класс в проекте C # ASP.NET, чтобы позволить сценарию, написанному на каком-либо случайном языке сценариев, динамически предоставлять методы веб-службы - другими словами, сценарий должен иметь возможность предоставлять метод любого имени с любой подписью (если это действительно так, во всяком случае) во внешний мир через этот интерфейс SOAP (возможность добавлять и удалять их по желанию, без необходимости жесткого изменения кода), и поэтому мне нужно иметь возможность создавать класс веб-сервиса в C # будучи в состоянии динамически добавлять и удалять методы во время выполнения.

Теперь лучший план, который я смог до сих пор разработать, - это (во время выполнения) генерировать код C # для представления веб-службы, используя System.Reflection.Emit для его компиляции, а затем загружать сборку во время выполнения - все когда Сценарий добавляет или удаляет метод в / из службы (обратите внимание, это не должно происходить очень часто).

У кого-нибудь есть идея получше, чем эта?

Ответы [ 5 ]

5 голосов
/ 02 июля 2009

Вы можете изменить WSDL, используя SoapExtensionReflector class. От Блог Кирка Эванса :

SoapExtensionReflector вызывается при отражении вашего типа для предоставления определения WSDL для вашей службы. Этот тип можно использовать для перехвата вызова отражения и изменения вывода WSDL.

В следующем примере удаляется первый метод из 2 методов веб-службы:

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

   [WebMethod]
   public int Multiply(int a, int b)
   {
      return a * b;
   }
}

Создать класс, унаследованный от SoapExtensionReflector:

namespace TestWebservice
{
   public class MyReflector : SoapExtensionReflector
   {
      public override void ReflectMethod()
      {
         //no-op
      }

      public override void ReflectDescription()
      {
         ServiceDescription description = ReflectionContext.ServiceDescription;
         if (description.PortTypes[0].Operations.Count == 2)
            description.PortTypes[0].Operations.RemoveAt(0);
         if (description.Messages.Count == 4)
         {
            description.Messages.RemoveAt(0);
            description.Messages.RemoveAt(0);
         }
         foreach (Binding binding in description.Bindings)
         {
            if (binding.Operations.Count == 2)
               binding.Operations.RemoveAt(0);
         }
         if (description.Types.Schemas[0].Items.Count == 4)
         {
            description.Types.Schemas[0].Items.RemoveAt(0);
            description.Types.Schemas[0].Items.RemoveAt(0);
         }
      }
   }
}

Добавьте это в раздел config / system.web в web.config:

<webServices>
   <soapExtensionReflectorTypes>
      <add type="TestWebservice.MyReflector, TestWebservice" />
   </soapExtensionReflectorTypes>
</webServices>

Это должно дать вам отправную точку для динамического удаления методов из документа WSDL. Вам также нужно будет сгенерировать NotImplementedException из веб-метода, если он отключен.

Наконец, вам необходимо отключить документацию веб-службы, созданную путем вызова конечной точки .asmx без параметра? WSDL. Установите атрибут href элемента wsdlHelpGenerator для некоторого URL. Вы можете использовать DefaultWsdlHelpGenerator.aspx в качестве отправной точки для своего собственного обработчика документации. См. Вопрос по документации веб-службы в XML-файлах, август 2002 г. .

2 голосов
/ 31 мая 2009

XMLRPC довольно мертв, не так ли?

SOAP подразумевает WSDL. Как вы генерируете WSDL динамически?

Вы должны изучить использование WCF. Я ожидаю, что вы сможете взять под контроль процесс генерации WSDL (и других метаданных), но вы также сможете взять под контроль обработку входящих сообщений. В частности, вы сможете проверить входящие сообщения, чтобы определить, какой скрипт запустить, какие параметры передать и т. Д.

2 голосов
/ 04 июня 2009

Вы можете создать службу WCF с типом ввода и вывода xs:any и обрабатывать входящий запрос как необработанный Message. Это позволит вам принять любой тип данных и вернуть любой тип данных. Вы не будете использовать контракты данных или статические типы, только Message вход и Message выход.

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

1 голос
/ 31 мая 2009

Должен ли это быть интерфейс SOAP? Это звучит так, как будто это может быть более подходящим для API на основе маршрута / REST / и т.д. Вы можете сделать что-то в ASP.NET MVC (с помощью специального метода IController.Execute, который разрешает действие для метода) довольно легко (на самом деле, я работаю над чем-то очень похожим для моего собственного кода * 1003). * на данный момент).

Например, у вас могут быть маршруты:

http://myserver/myservice/mymethod

, который принимает (в теле или аргументах) полезную нагрузку (параметры) и возвращает результат в ответе. В не-MVC вы должны быть в состоянии сделать что-то похожее с универсальным обработчиком с отображением по шаблону.

0 голосов
/ 06 июля 2009

Вот предложение:

  • Использовать WCF.
  • Создание WSDL из WCF с использованием информация в следующем блоге почта:

    http://www.pluralsight.com/community/blogs/kirillg/archive/2006/06/18/28380.aspx

  • Вы можете опубликовать эту информацию используя MEX.

  • Сервисы открыты для вашего клиенты для загрузки метаданных и позвоните в сервис.

...