Вопрос

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

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

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

Это было полезно?

Решение

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

SoapExtensionReflector вызывается, когда ваш тип отражается, чтобы предоставить определение WSDL для вашего сервиса.Вы можете использовать этот тип для перехвата вызова reflection и изменения выходных данных 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);
         }
      }
   }
}

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

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

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

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

Другие советы

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

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

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

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

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

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

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

http://myserver/myservice/mymethod

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

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

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

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

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

  • После этого службы будут открыты для ваших клиентов, которые смогут загрузить метаданные и вызвать службы.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top