Pergunta

Eu estou usando uma classe em um projeto C # ASP.NET para permitir que um script escrito em alguma linguagem de script aleatória para expor métodos webservice dinamicamente - em outras palavras, o script deve ser capaz de expor um método de qualquer nome com qualquer assinatura (contanto que ele é válido, pelo menos) para o mundo exterior através desta interface SOAP (capaz de adicionar e remover-los à vontade, sem a necessidade de uma alteração de código rígido), e como tal necessidade I para ser capaz de criar uma classe webservice em C # ao ser capaz de adicionar e dinamicamente métodos remover pelo tempo de execução.

Agora, o melhor plano que eu tenho sido capaz de chegar a até agora é (runtime) gerar código C # para representar o webservice, usando System.Reflection.Emit para compilá-lo e, em seguida, carregar o assembly em tempo de execução - tudo sempre o script adiciona ou remove um método de / para o serviço (não deve acontecer muitas vezes, mente).

Alguém tem uma idéia melhor do que isso?

Foi útil?

Solução

Você pode modificar WSDL usando SoapExtensionReflector classe. De Kirk Evans Blog :

O SoapExtensionReflector é chamado quando o seu tipo está sendo refletido sobre para fornecer a definição WSDL para o seu serviço. Você pode aproveitar este tipo de interceptar a chamada reflexão e modificar a saída WSDL.

O exemplo a seguir remove o primeiro método de métodos de serviço 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;
   }
}

Crie uma classe herdada 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);
         }
      }
   }
}

Adicione isto a seção de configuração / system.web no web.config:

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

Isso deve dar-lhe um ponto de partida para remover dinamicamente os métodos de documento WSDL. Você também precisa jogar NotImplementedException de método web se ele estiver desativado.

Finalmente, você precisa desativar a documentação de serviço web produzido invocando .asmx endpoint sem? WSDL parâmetro. Set atributo href do elemento wsdlHelpGenerator a algum URL. Você pode usar DefaultWsdlHelpGenerator.aspx como um ponto de partida para o seu próprio manipulador de documentação. Veja a pergunta na documentação do serviço web em arquivos XML, agosto de 2002 .

Outras dicas

XMLRPC é bastante morto, não é?

SABÃO implica uma WSDL. Como você gerar o WSDL dinamicamente?

Você deve olhar para usar WCF. Eu espero que você vai ser capaz de assumir o controle do processo de gerar o WSDL (e outros metadados), mas você também deve ser capaz de assumir o controle do processamento de mensagens recebidas. Em particular, você será capaz de examinar as mensagens recebidas para determinar qual script para ser executado, o que parâmetros para passar, etc.

Você pode criar um serviço WCF com um tipo de entrada e saída de xs:any e lidar com a solicitação de entrada como um Message cru. Isso permitiria que você a aceitar qualquer tipo de dados e retornar qualquer tipo de dados. Você não iria usar contratos de dados ou tipos estáticos, apenas um Message e um Message fora.

O problema com esta abordagem é que a geração de um proxy a partir do WSDL realmente não faz nada para ajudar o consumidor que não fornecem um wrapper para chamar o método. Fornecendo dados que seja aceitável para o método exigiria tipos de dados de enrolar, etc, que não é tão difícil, é só não tão intuitivo como um contrato duro, digitado.

Tem que ser uma interface SOAP? Isso soa como ele poderia ser mais adequado para uma rota / REST / etc API baseada. Você poderia fazer algo em ASP.NET MVC (com um método IController.Execute personalizada que resolve a ação para o método) muito facilmente (na verdade, eu estou trabalhando em algo muito similar para alguns dos meus próprios código no momento).

Por exemplo, você pode ter rotas:

http://myserver/myservice/mymethod

que aceita (seja no corpo ou args) a carga útil (parâmetros), e retorna o resultado na resposta. Em não-MVC você deve ser capaz de fazer algo semelhante com um manipulador genérico mapeados-curinga.

Aqui está uma sugestão:

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top