2009-09-08 11 views
12

मेरे पास इस तरह एक अनुबंध परिभाषित किया गया है:क्या डब्लूसीएफ सेवा अनुबंध में एक शून्य इनपुट पैरामीटर हो सकता है?

[OperationContract] 
[WebGet(UriTemplate = "/GetX?myStr={myStr}&myX={myX}", BodyStyle = WebMessageBodyStyle.Wrapped)] 
string GetX(string myStr, int? myX); 

मुझे अपवाद मिलता है: [अवैधऑपरेशन अपवाद: अनुबंध 'आईएमजीजीएटी' में ऑपरेशन 'गेटएक्स' में 'myX' प्रकार 'System.ullable 1[System.Int32]', but type 'System.Nullable 1 नामक एक क्वेरी चर है [System.Int32] 'QueryStringConverter' द्वारा परिवर्तनीय नहीं है। UriTemplate क्वेरी मानों के लिए वेरिएबल्स में ऐसे प्रकार होना चाहिए जिन्हें 'QueryStringConverter' द्वारा परिवर्तित किया जा सके।] Xzx23

निम्न त्रुटि को छोड़कर इस त्रुटि के बारे में कुछ भी नहीं मिला: http://blog.rolpdog.com/2007/07/webget-and-webinvoke-rock.html जो कि थोड़ा पुराना है और समाधान नहीं है।

किसी भी विचार को नल करने योग्य पैरामीटर से छुटकारा पाने के अलावा क्या करना है?

धन्यवाद।

उत्तर

1

हां, आपके पास डब्ल्यूसीएफ के साथ सुस्त पैरामीटर हो सकते हैं। मुझे लगता है कि आपकी समस्या यह है कि QueryStringConverter निरर्थक पैरामीटर के साथ काम नहीं करता है।

क्या करना है? क्या आपको UriTemplate विशेषता का उपयोग करने की आवश्यकता है? यदि आपने इसे 'क्लासिक वेब सेवा' के रूप में प्रकाशित किया है तो आपको यह समस्या नहीं होगी।

दूसरा विकल्प आपके द्वारा प्रदान किए गए लिंक में सलाह का पालन करना है - यानी myX पैरामीटर को स्ट्रिंग के रूप में प्राप्त करें और फिर इसे int में डालें ?, कहां (कहें) "n" शून्य है। सुंदर नहीं।

8

असल में ... आप बिल्कुल शून्य के पैरामीटर, या किसी अन्य प्रकार के पैरामीटर प्राप्त कर सकते हैं जो बॉक्स के बाहर QueryStringConverter द्वारा समर्थित नहीं है। आपको जिस प्रकार की आवश्यकता होगी, उसका समर्थन करने के लिए आपको केवल QueryStringConverter का विस्तार करना होगा। इस पोस्ट ==>

In the WCF web programming model, how can one write an operation contract with an array of query string parameters (i.e. with the same name)?

+0

कि ऊपर renders QueryStringConverter व्युत्पन्न ढांचे 4 में व्यर्थ कक्षाओं यकीन है कि आप इस प्रयास करने से पहले बग पर एक नजर है बनाओ वहाँ कोड संदर्भ में एक बग है। मैंने यह पता लगाने से पहले बहुत समय बर्बाद कर दिया कि यह अभ्यास में काम नहीं करता है। – Jim

32

में स्वीकार किए जाते हैं जवाब देखें इस समस्या है कि किसी भी हैक्स की आवश्यकता नहीं है के लिए एक समाधान है। यह बहुत सारे काम की तरह दिख सकता है लेकिन यह वास्तव में नहीं है और यदि आप इसे पढ़ते हैं तो बहुत समझदारी होती है। समस्या का मूल यह है कि वास्तव में unresolved bug (.NET 4 के रूप में) का अर्थ है कि WebServiceHost कस्टम QueryStringConverters का उपयोग नहीं करता है। तो आपको थोड़ा अतिरिक्त काम करने की आवश्यकता है और समझें कि WebHttpEndpoints के लिए WCF कॉन्फ़िगरेशन कैसे काम करता है। नीचे आपके लिए समाधान बताता है।

सबसे पहले, एक कस्टम QueryStringConverter nulls उन्हें छोड़ते हुए, या एक खाली स्ट्रिंग प्रदान करके क्वेरी स्ट्रिंग में प्रदान किया जा करने की अनुमति देता है कि:

public class NullableQueryStringConverter : QueryStringConverter 
{ 
    public override bool CanConvert(Type type) 
    { 
     var underlyingType = Nullable.GetUnderlyingType(type); 

     return (underlyingType != null && base.CanConvert(underlyingType)) || base.CanConvert(type); 
    } 

    public override object ConvertStringToValue(string parameter, Type parameterType) 
    { 
     var underlyingType = Nullable.GetUnderlyingType(parameterType); 

     // Handle nullable types 
     if (underlyingType != null) 
     { 
      // Define a null value as being an empty or missing (null) string passed as the query parameter value 
      return String.IsNullOrEmpty(parameter) ? null : base.ConvertStringToValue(parameter, underlyingType); 
     } 

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

अब एक कस्टम WebHttpBehavior कि कस्टम सेट हो जाएगा मानक एक के स्थान पर उपयोग करने के लिए QueryStringConverter। ध्यान दें कि WebHttpBehavior से इस व्यवहार derivces जो महत्वपूर्ण है ताकि हम व्यवहार एक REST एंडपॉइंट के लिए आवश्यक वारिस:

public class NullableWebHttpBehavior : WebHttpBehavior 
{ 
    protected override QueryStringConverter GetQueryStringConverter(OperationDescription operationDescription) 
    { 
     return new NullableQueryStringConverter(); 
    } 
} 

अब एक कस्टम ServiceHost कि WebHttpEndpoint करने के लिए कस्टम व्यवहार कहते हैं तो यह है कि कस्टम क्वेरीरींग कनवर्टर का उपयोग करेगा।महत्वपूर्ण बात यह है इस कोड में ध्यान दें, कि यह ServiceHost से निकला है और नहीं WebServiceHost करने के लिए। यह महत्वपूर्ण है क्योंकि अन्यथा बग ऊपर उल्लेख किया है इस्तेमाल किया जा रहा से कस्टम QueryStringConverter पाएगा:

public sealed class NullableWebServiceHost : ServiceHost 
{ 
    public NullableWebServiceHost() 
    { 
    } 

    public NullableWebServiceHost(object singletonInstance, params Uri[] baseAddresses) : base(singletonInstance, baseAddresses) 
    { 
    } 

    public NullableWebServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses) 
    { 
    } 

    protected override void OnOpening() 
    { 
     if (this.Description != null) 
     { 
      foreach (var endpoint in this.Description.Endpoints) 
      { 
       if (endpoint.Binding != null) 
       { 
        var webHttpBinding = endpoint.Binding as WebHttpBinding; 

        if (webHttpBinding != null) 
        { 
         endpoint.Behaviors.Add(new NullableWebHttpBehavior()); 
        } 
       } 
      } 
     } 

     base.OnOpening(); 
    } 
} 

हम से पाने नहीं कर रहे हैं क्योंकि WebServiceHost हम इसे काम है क्या करना है और यकीन है कि हमारे विन्यास के लिए सही है बनाने की जरूरत है सुनिश्चित करें कि आरईएसटी सेवा काम करेगी। आपको निम्न की तरह कुछ चाहिए। इस कॉन्फ़िगरेशन में, मेरे पास एक डब्ल्यूएस HTTP एंडपॉइंट सेटअप भी है क्योंकि मुझे सी # (डब्ल्यूएस HTTP का उपयोग करके अपने निसर के रूप में) और मोबाइल डिवाइस (आरईएसटी का उपयोग करके) दोनों से इस सेवा तक पहुंचने की आवश्यकता है। यदि आपको इसकी आवश्यकता नहीं है तो आप इस एंडपॉइंट के लिए कॉन्फ़िगरेशन को छोड़ सकते हैं। ध्यान देने योग्य एक महत्वपूर्ण बात यह है कि आपको अब कस्टम एंडपॉइंट व्यवहार की आवश्यकता नहीं है। इसका कारण यह है कि अब हम हमारे स्वयं के कस्टम endpoint व्यवहार है कि कस्टम बांधता QueryStringConverter जोड़ रहे है। यह निकला है से WebHttpBehavior है जो विन्यास कहा, अब यह निरर्थक बना रही है।

<system.serviceModel> 
    <services> 
    <service behaviorConfiguration="ServiceBehavior" name="MyNamespace.Service1"> 
     <endpoint binding="webHttpBinding" bindingConfiguration="WebHttpBinding" contract="MyNamespace.IService1" /> 
     <endpoint address="ws" binding="wsHttpBinding" bindingConfiguration="WsHttpBinding" contract="MyNamespace.IService1" /> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 
    </service> 
    </services> 

    <bindings> 
    <webHttpBinding> 
     <binding name="WebHttpBinding"> 
     <security mode="Transport"> 
      <transport clientCredentialType="None" /> 
     </security> 
     </binding> 
    </webHttpBinding> 

    <wsHttpBinding> 
     <binding name="WsHttpBinding"> 
     <security mode="Transport"> 
      <transport clientCredentialType="None" /> 
     </security> 
     </binding> 
    </wsHttpBinding> 
    </bindings> 

    <behaviors> 
    <serviceBehaviors> 
     <behavior name="ServiceBehavior"> 
     <serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" /> 
     <serviceDebug includeExceptionDetailInFaults="true" httpHelpPageEnabled="false" httpsHelpPageEnabled="true" /> 
     <dataContractSerializer maxItemsInObjectGraph="2147483647" /> 
     </behavior> 
    </serviceBehaviors> 
    </behaviors> 
</system.serviceModel> 

करने के लिए आखिरी बात एक कस्टम ServiceHostFactory बना सकते हैं और इसका इस्तेमाल करने के है, जो सभी कस्टम कोड इस्तेमाल किया जा करने का कारण होगा एसवीसी फ़ाइल को बयां करती हैं। बेशक आप भी है कि आप विन्यास में व्यवहार को जोड़ने के लिए अनुमति होगी एक कस्टम तत्व बना सकते हैं, लेकिन मैं इस व्यवहार को एक कोड-आधारित दृष्टिकोण बेहतर है के लिए लगता है, क्योंकि यह संभावना नहीं है आप नल प्रकार प्रक्रिया की क्षमता को दूर करना चाहते हैं, के रूप में यह आपकी सेवा टूट जाएगा:

public sealed class NullableWebServiceHostFactory : ServiceHostFactory 
{ 
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) 
    { 
     return new NullableWebServiceHost(serviceType, baseAddresses); 
    } 
} 

बदलें अपनी Service.svc की मार्कअप निम्नलिखित फ़ाइल:

<%@ ServiceHost Service="MyNamespace..Service1" CodeBehind="Service1.svc.cs" Factory="MyNamespace.NullableWebServiceHostFactory" %> 

अब आप किसी भी मुद्दे के बिना अपने सेवा इंटरफ़ेस में नल प्रकार का उपयोग कर सकते हैं, बस द्वारा पैरामीटर को छोड़कर या इसे खाली स्ट्रिंग पर सेट करना। निम्न संसाधनों आप के लिए सहायता की आवश्यकता हो सकता है:

आशा इस मदद करता है!

+1

मुझे यह समाधान पसंद है। – Sawyer

+4

यह माइक्रोसॉफ्ट द्वारा लागू करने के लिए एक महान व्यक्ति होने के लिए बहुत काम है। – crush

+2

क्या आश्चर्य है, माइक्रोसॉफ्ट कुछ ऐसा करता है जो जटिल पर कुछ दर्दनाक हो सकता है ... अच्छा जवाब हालांकि – Jim

1

हम, त्वरित समाधान (सुंदर नहीं) WCF संबंधित इंटरफेस और सेवा कोड में स्ट्रिंग के रूप नल पैरामीटर स्वीकार करना है।

संबंधित मुद्दे