Pregunta

Estoy usando una clase en un proyecto de C # ASP.NET para permitir que un script escrito en algún lenguaje de programación al azar para exponer los métodos de servicio web de forma dinámica - en otras palabras, el guión debe ser capaz de exponer un método para cualquier nombre con cualquier firma (siempre y cuando sea válida, de todos modos) con el mundo exterior a través de esta interfaz SOAP (capaz de agregar y quitar a voluntad, sin necesidad de un cambio de código duro), y como tal tengo que ser capaz de crear una clase de servicio web en C # mientras que ser capaz de añadir y eliminar métodos en tiempo de ejecución de forma dinámica.

Ahora, el mejor plan que he sido capaz de llegar a hasta el momento es (tiempo de ejecución) generar código C # para representar el servicio web, utilizando System.Reflection.Emit compilarlo y luego cargar el ensamblado en tiempo de ejecución - todos siempre el guión añade o elimina un método a / desde el servicio (que no debería ocurrir muy a menudo, la mente).

¿Alguien tiene una idea mejor que esto?

¿Fue útil?

Solución

Puede modificar WSDL mediante el uso de SoapExtensionReflector clase. De Kirk Evans Blog :

  

El SoapExtensionReflector se llama cuando el tipo se está reflejando a proporcionar la definición WSDL para el servicio. Puede aprovechar este tipo de interceptar la llamada reflexión y modificar la salida WSDL.

El ejemplo siguiente elimina el primer método de métodos de servicio 2 web:

[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;
   }
}

Crea una clase heredada de 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);
         }
      }
   }
}

Agregue esto a la sección de configuración / system.web en web.config:

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

Esto debe darle un punto de partida para suprimir dinámicamente métodos de documento WSDL. También habría que tirar NotImplementedException del método web si está desactivado.

Por último, es necesario deshabilitar la documentación de servicio de Internet desarrollado por la invocación de asmx punto final sin parámetro? WSDL. Establecer el atributo href del elemento wsdlHelpGenerator hasta cierto URL. Puede utilizar DefaultWsdlHelpGenerator.aspx como punto de partida para su propio controlador de documentación. Véase la pregunta sobre la documentación servicio web en Archivos de agosto de 2002 .

Otros consejos

XMLRPC es bastante muerto, ¿verdad?

Jabón implica un WSDL. ¿Cómo se genera el WSDL dinámicamente?

Usted debe mirar en el uso de WCF. Espero que usted será capaz de tomar el control del proceso de generación del WSDL (y otros metadatos), sin embargo, también debería ser capaz de tomar el control del procesamiento de mensajes entrantes. En particular, usted será capaz de examinar los mensajes entrantes para determinar qué secuencia de comandos para ejecutar, lo que los parámetros a pasar, etc.

Se puede crear un servicio WCF con un tipo de entrada y salida de xs:any y manejar las peticiones entrantes como Message prima. Eso permitirá aceptar cualquier tipo de datos y devolver cualquier tipo de datos. Que no se usará contratos de datos o tipos estáticos, sólo un Message y un Message a cabo.

El problema con este enfoque es que la generación de un proxy desde el WSDL realmente no hace nada para ayudar al consumidor que no sea proporcionar una envoltura para llamar al método. El suministro de datos que sea aceptable para el método requeriría tipos de datos para liar, etc, que no es tan difícil, simplemente no es tan intuitivo como un contrato dura, a máquina.

¿Tiene que ser una interfaz SOAP? Eso suena como que podría ser más adecuado para una API de ruta / DESCANSO / etc basado. Se podía hacer algo en ASP.NET MVC (con un método IController.Execute a medida que resuelve la acción con el método) con bastante facilidad (de hecho, estoy trabajando en algo muy similar a algunos de mi propio código por el momento).

Por ejemplo, es posible que tenga rutas:

http://myserver/myservice/mymethod

que acepta (ya sea en el cuerpo o args) la carga útil (parámetros), y devuelve el resultado en la respuesta. En MVC no debería ser capaz de hacer algo similar con un manipulador genérico comodín-asignada.

Aquí es una sugerencia:

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top