Создание и публикация SOAP-сервиса и его WSDL динамически на C # (с помощью специального прослушивателя TCP!)

У меня есть собственный HTTP-сервер, встроенный в C #, который принимает запросы на службы REST и отвечает XML или JSON (в зависимости от того, что нужно клиенту). Службы REST определяются во время выполнения из конфигурации на базе базы данных, широко варьируются по входным параметрам и типам выходных данных, и они прекрасно работают на производстве.

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

  • Публикация WSDL, сгенерированного во время выполнения, из определений методов в базе данных
  • Анализ входящих запросов SOAP, их сопоставление с этими определениями и обеспечение соответствия запросов методу перед их обработкой
  • После того, как ответ будет обработан, создание ответа SOAP, отвечающего WDSL, чтобы вернуть результаты

Документы документации MS (и Google) с использованием Visual Studio для создания веб-сервисов (и WSDL) во время разработки, публикации материалов с использованием WebMethods, ASP.NET MVC и т. Д. Это не то, что я ищу, так как нет метода определения, из которых можно создать привязки во время разработки.

Есть ли у кого-нибудь идеи (например, инструментальные средства для анализа сырых SOAP) и мысли о генерации WSDL из динамически созданных сигнатур методов и т. Д.? Любая идея, как можно строить такие вещи, если нет? Я стараюсь избегать повторного изобретения колеса, если это возможно.

PS: Очевидно, что в .NET Framework есть стандартизированные материалы, поскольку Visual Studio делает это для вас – любые идеи, как получить доступ к этому на более низком уровне во время выполнения?

Чтобы создать wsdl динамически, вы можете использовать ServiceDescriptionReflector

Например: для classа

 public class TestWebService { [WebMethod] public string Hello(string namex) { return "Hello " + namex; } } 

вы можете использовать этот код

 StringWriter wr = new StringWriter(); var r = new System.Web.Services.Description.ServiceDescriptionReflector(); r.Reflect(typeof(TestWebService), "http://somewhere.com"); r.ServiceDescriptions[0].Write(wr); var wsdl = wr.ToString(); 

Но так как вы сказали

Публикация WSDL, сгенерированного во время выполнения, из определений методов в базе данных

вам нужно создать Type во время выполнения

 var asm = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("MyAsm"), AssemblyBuilderAccess.Run); var mod = asm.DefineDynamicModule("MyModule"); TypeBuilder typeBuilder = mod.DefineType("TestWebService"); MethodBuilder mb = typeBuilder.DefineMethod("Hello", MethodAttributes.Public, CallingConventions.Standard, typeof(string), new Type[] { typeof(string) }); var cab = new CustomAttributeBuilder( typeof(WebMethodAttribute).GetConstructor(new Type[]{}), new object[]{} ); mb.SetCustomAttribute(cab); mb.DefineParameter(1, ParameterAttributes.In, "namex"); mb.GetILGenerator().Emit(OpCodes.Ret); Type type = typeBuilder.CreateType(); 

Теперь вы можете использовать type для создания wsdl

 StringWriter wr = new StringWriter(); var r = new System.Web.Services.Description.ServiceDescriptionReflector(); r.Reflect(type, "http://somewhere.com"); r.ServiceDescriptions[0].Write(wr); var wsdl = wr.ToString(); 

Для запроса на чтение и формирования ответа вы можете использовать Linq2Xml. Fiddler может дать вам представление о формате SOAP (xml), посланном между клиентом и сервером

SOAP – это «просто» XML-протокол для обмена информацией. Реализация поддержки с самого начала была бы утомительной, но не очень сложной в принципе, я не думаю.

Официальные спецификации SOAP можно найти здесь .

Не разбирайте SOAP, если вам действительно не нужно, пусть WCF делает тяжелую работу для вас, генерирует сервисы и datacontracts в коде C # из ваших определений и компилируется во время выполнения . Создайте реализацию службы, которая перехватывает ваш «статический» код через хорошо известный интерфейс.

Динамически создавать конечные точки с правильной привязкой к новым контрактам / контрактам на обслуживание. Если привязки не изменяются динамически, это может быть определено в вашем приложении app.config, иначе это также указывается во время выполнения.

добавьте конечную точку Mex, чтобы опубликовать wsdl.

Для «изучения» входящего трафика используйте MessageInspector

самостоятельно разместить службу WCF / SOAP на вашем HTTP-сервере, используя ServiceHost -> Self Hosting WCF

Просто некоторые идеи по другому подходу.