In dem WCF Web-Programmiermodell, wie kann man einen Betriebsvertrag mit einer Reihe von Query-String-Parametern (dh mit dem gleichen Namen) schreiben?

stimmen
13

Unter Verwendung des WCF Web-Programmiermodell kann man wie so eine Operation Vertrag angeben:

[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Xml, UriTemplate = SomeRequest?qs1={qs1}&qs2={qs2})]
XElement SomeRequest1(string qs1, string qs2);

Nun , wenn wir mussten einen Vertrag machen, der ein Array von Parametern mit dem gleichen Namen akzeptiert (in diesem Fall qs1 Vertrag) wie so ...

[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Xml, UriTemplate = SomeRequest?qs1={qs1}&qs1={qs2})]
 XElement SomeRequest2(string qs1, string qs2);

Wir erhalten die Fehlermeldung zur Laufzeit, wenn wir den Aufruf der Methode machen:

die Abfrage-String muss ‚Name = Wert‘ Paare mit eindeutigen Namen haben. Beachten Sie, dass die Namen Groß- und Kleinschreibung sind. Lesen Sie die Dokumentation für UriTemplate für weitere Details.

Wie macht man einen HTTP-Dienst definieren, der ohne Rückgriff auf einen loosey-goosey Schnittstelle eine Ressource mit einer Reihe von Parametern aussetzt?

Veröffentlicht am 10/12/2008 um 01:24
quelle vom benutzer
In anderen Sprachen...                            


3 antworten

stimmen
28

Ich habe einen einfachen benutzerdefinierten Querystringconverter implementiert , so dass Sie qs1 eine Zeichenfolge [] dann das Query - String - Variable begrenzt wird durch Komma haben machen können (zB http: // server / service / SomeRequest qs1 = val1, val2, val3, val4 )

[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Xml,
        UriTemplate = "SomeRequest?qs1={qs1}")]
XElement SomeRequest2(string[] qs1);

Zuerst müssen Sie eine Klasse, die von WebHttpBehavior erbt, so dass wir unsere eigenen Querystringconverter injizieren können:

public class CustomHttpBehavior : System.ServiceModel.Description.WebHttpBehavior
{
    protected override System.ServiceModel.Dispatcher.QueryStringConverter GetQueryStringConverter(System.ServiceModel.Description.OperationDescription operationDescription)
    {
        return new CustomQueryStringConverter();
    }
}

Dann ist unser CustomQueryStringConverter die Zeichenfolge [] Parameter behandelt:

public class CustomQueryStringConverter : System.ServiceModel.Dispatcher.QueryStringConverter
{
    public override bool CanConvert(Type type)
    {
        if (type == typeof(string[]))
        {
            return true;
        }

        return base.CanConvert(type);
    }

    public override object ConvertStringToValue(string parameter, Type parameterType)
    {
        if (parameterType == typeof(string[]))
        {
            string[] parms = parameter.Split(',');
            return parms;
        }

        return base.ConvertStringToValue(parameter, parameterType);
    }

    public override string ConvertValueToString(object parameter, Type parameterType)
    {
        if (parameterType == typeof(string[]))
        {
            string valstring = string.Join(",", parameter as string[]);
            return valstring;
        }

        return base.ConvertValueToString(parameter, parameterType);
    }
}

Das letzte, was Sie tun müssen, ist ein Verhalten Konfigurationserweiterung zu schaffen, so dass die Laufzeit eine Instanz des CustomWebHttpBehavior bekommen kann:

public class CustomHttpBehaviorExtensionElement : System.ServiceModel.Configuration.BehaviorExtensionElement
{
    protected override object CreateBehavior()
    {
        return new CustomHttpBehavior();
    }

    public override Type BehaviorType
    {
        get { return typeof(CustomHttpBehavior); }
    }
}

Nun haben wir das Element in unsere Konfiguration Erweiterungen hinzufügen , so dass unser CustomWebHttpBehavior verwendet wird, ich den Namen dieser Erweiterung statt verwenden <webHttp />in unserem Verhalten:

 <system.serviceModel>
   <services>
     <service name="NameSpace.ServiceClass">
       <endpoint address="" behaviorConfiguration="MyServiceBehavior"
        binding="webHttpBinding" contract="NameSpace.ServiceClass" />
     </service>
   </services>
  <behaviors>
   <endpointBehaviors>
    <behavior name="MyServiceBehavior">
      <customWebHttp/>
    </behavior>
   </endpointBehaviors>
  </behaviors>
  <extensions>
    <behaviorExtensions>
      <add name="customWebHttp" type="NameSpace.CustomHttpBehaviorExtensionElement, MyAssemblyName" />
    </behaviorExtensions>
  </extensions>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
 </system.serviceModel>

Sie können nun erweitern auch Ihre CustomQueryStringConverter andere Arten zu behandeln, die eine Standard nicht, wie NULL festlegbare Werttypen.

HINWEIS: Es ist ein Fehler bei Microsoft angemeldet verbinden, die direkt an diesen Code bezieht. Der Code eigentlich nicht in Arbeit fast alle Fälle, in denen Sie konvertieren verschiedene Arten zur Abfrage versuchen.

http://connect.microsoft.com/VisualStudio/feedback/details/616486/bug-with-getquerystringconverter-not-being-called-by-webservicehost#tabs

Bitte stellen Sie sicher, dass Sie diese sorgfältig lesen, bevor Stunden Ihrer Zeit das Erstellen von benutzerdefinierten REST Query-String-Konverter verschwenden, die möglicherweise nicht funktionieren kann. (Gilt für Framework 4.0 und unten).

Beantwortet am 10/12/2008 um 02:21
quelle vom benutzer

stimmen
5

um Ihren Kommentar zu meiner anderen Antwort zu reagieren:

Sie können am Ende des Abfragezeichenfolgeflag einen Platzhalter Parameter gefällt

[WebGet(ResponseFormat = WebMessageFormat.Xml,
        UriTemplate = "SomeRequest?qs1={*qs1}")]
XElement SomeRequest2(string qs1);

Auf diese Weise der qs1 String-Parameter die ganze rohe Abfragezeichenfolgeflag nach dem qs1 sein =, könnten Sie dann, dass analysieren manuell in Ihrem Code.

Die Querystringconverter stützen sich auf der Formatierung des Abfragezeichenfolgeflag so genau, etwas zu tun, wie Sie wollen, ist nicht möglich, ohne möglicherweise Querystringconverter anstelle des wenig überschreibt Umschreiben wir in der anderen Antwort haben.

Von MSDN:

Wildcard Segmente müssen die folgenden Regeln beachten:

  • Es kann höchstens ein Name Wildcard Segment für jede Vorlage Zeichenfolge sein.
  • Ein benannte Wildcard-Segment muss an dem am weitesten rechts stehenden Segment auf dem Weg erscheinen.
  • Ein benannte Wildcard-Segment kann nicht mit einem anonymen Wildcard-Segment innerhalb des gleichen Vorlage Zeichenfolge koexistieren.
  • Der Name eines benannten Wildcard-Segment muss eindeutig sein.
  • Benannt Wildcard Segmente können keine Standardwerte haben.
  • Benannt Wildcard Segmente können nicht mit „/“ enden.
Beantwortet am 11/12/2008 um 00:12
quelle vom benutzer

stimmen
2

Beachten Sie, dass 3.5 in WCF Sie den vollständigen qualifizierten Montagenamen angeben muss:

   <extensions>
    <behaviorExtensions>
      <add name="customWebHttp" type="NameSpace.CustomHttpBehaviorExtensionElement, MyAssemblyName, NOT SUFFICIENT HERE" />
    </behaviorExtensions>
  </extensions>

Genau wie folgt aus : SampleService.CustomBehavior, SampleService, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null

Andernfalls werden Sie Ausnahme erhalten:

Konfigurationsfehler
Beschreibung: ein Fehler bei der Verarbeitung einer Konfigurationsdatei erforderlich , um diese Anforderung zu bedienen. Bitte lesen Sie die unten angegebenen Fehlerinformationen und Ihre Konfigurationsdatei entsprechend modifizieren.

Parser - Fehlermeldung: Ungültige Element in der Konfiguration. Der Erweiterungsname ‚CustomWebHttp‘ ist nicht auf system.serviceModel / extensions / behaviorExtensions in der Sammlung registriert.

Beantwortet am 24/12/2009 um 11:02
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more