Question

J'utilise une classe dans un projet C # ASP.NET pour permettre un script écrit dans un langage de script aléatoire pour exposer les méthodes de WebService dynamique - en d'autres termes, le script devrait être en mesure d'exposer une méthode d'un nom avec une signature (tant qu'il est valide, de toute façon) au monde extérieur à travers cette interface SOAP (capable d'ajouter et de les supprimer à volonté, sans avoir besoin d'un changement de code dur), et en tant que tel je dois être en mesure de créer une classe WebService en C # tout en étant capable d'ajouter et de supprimer dynamiquement les méthodes à l'exécution.

Maintenant, le meilleur plan que je suis en mesure de trouver est à ce jour (exécution) de génération de code C # pour représenter le webservice, en utilisant System.Reflection.Emit pour compiler et charger ensuite l'ensemble à l'exécution - tout à chaque fois le script ajoute ou supprime une méthode / du service (ne devrait pas se produire très souvent, l'esprit).

Quelqu'un at-il une meilleure idée que cela?

Était-ce utile?

La solution

Vous pouvez modifier WSDL en utilisant SoapExtensionReflector classe. De Kirk Evans Blog :

  

Le SoapExtensionReflector est appelée lorsque le type est réfléchi sur de fournir la définition WSDL pour votre service. Vous pouvez tirer parti de ce type pour intercepter l'appel de réflexion et de modifier la sortie WSDL.

L'exemple suivant supprime la première méthode de deux méthodes de service 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;
   }
}

Créer une classe héritée 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);
         }
      }
   }
}

Ajoutez ceci à la section de configuration / system.web dans web.config:

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

Cela devrait vous donner un point de départ pour la suppression dynamique des méthodes de document WSDL. Vous devez également jeter NotImplementedException de méthode Web si elle est désactivée.

Enfin, vous devez désactiver la documentation de service Web produit en invoquant sans point final .asmx? Paramètre WSDL. Définir l'attribut href de l'élément wsdlHelpGenerator à une URL. Vous pouvez utiliser DefaultWsdlHelpGenerator.aspx comme point de départ pour votre propre gestionnaire de documents. Voir la question sur la documentation de service Web en fichiers, Août 2002 .

Autres conseils

XMLRPC est assez mort, non?

SOAP implique un WSDL. Comment générer le WSDL dynamique?

Vous devriez regarder dans WCF. Je vous attends serez en mesure de prendre le contrôle du processus de génération du WSDL (et autres métadonnées), mais vous devez également être en mesure de prendre le contrôle du traitement des messages entrants. En particulier, vous serez en mesure d'examiner les messages entrants pour déterminer le script à exécuter, quels sont les paramètres à passer, etc.

Vous pouvez créer un service WCF avec un type d'entrée et de sortie de xs:any et de traiter la requête entrante comme Message brut. Cela vous permettra d'accepter tout type de données et renvoyer tout type de données. Vous ne voudriez pas utiliser des contrats de données ou types statiques, juste un Message et un Message sur.

Le problème avec cette approche est que la génération d'un proxy à partir du WSDL n'a vraiment rien pour aider le consommateur autre que de fournir un emballage pour appeler la méthode. Fournir des données qui est acceptable pour la méthode nécessiterait des types de données à rouler, etc qui est pas si difficile, il est tout simplement pas aussi intuitif que d'un disque, le contrat tapé.

Doit-il être une interface SOAP? Cela semble que cela pourrait être plus approprié pour une route / REST / etc API basée. Vous pouvez faire quelque chose dans ASP.NET MVC (avec une méthode IController.Execute personnalisée qui résout l'action à la méthode) assez facilement (en fait, je travaille sur quelque chose de très similaire pour certains de mes propres de code pour le moment).

Par exemple, vous pourriez avoir des itinéraires:

http://myserver/myservice/mymethod

qui accepte (soit dans le corps ou args) la charge utile (paramètres), et renvoie le résultat dans la réponse. En non-MVC, vous devriez être en mesure de faire quelque chose de similaire avec un gestionnaire générique cartographié générique.

Voici une suggestion:

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top