2011-12-06 13 views
7

वहां बहुत सारे प्रश्न हैं, लेकिन मैंने उनमें से प्रत्येक में हर समाधान का कोई फायदा नहीं लिया है।WebServiceHostFactory MaxReceivedMessageSize को ओवरराइड कैसे करें?

हमारे पास एक वेब सेवा है जो WebServiceHostFactory के साथ शुरू होती है, लेकिन यदि 64k से अधिक किसी को फेंक दिया जाता है, तो हमें '400 खराब अनुरोध' मिलता है। आम तौर पर, यह MaxReceivedMessageSize, MaxBufferSize और MaxBufferPoolSize को बढ़ाकर हल किया जाएगा। समस्या यह है कि WebServiceHostFactory का उपयोग करके, Web.Config पूरी तरह से अनदेखा किया जाता है। सेवा मॉडल अनुभाग में कोई भी बदलाव सेवा में प्रतिबिंबित नहीं होता है।

वेब सेवा HostFactory को पूरी तरह से डुबोना और स्क्रैच से web.config सेट करना अच्छा होगा, लेकिन हमारी सेवा इसके बिना नहीं चली जाएगी। विधियों में से एक में स्ट्रीम पैरामीटर के साथ-साथ कुछ अन्य स्ट्रिंग पैरा भी हैं। कारखाने के बिना, हमें

System.InvalidOperationException: For request in operation Test to be a stream the operation must have a single parameter whose type is Stream 

तो यह कारखाने को हटाने का विकल्प नहीं है। मैं वास्तव में काम नहीं कर सकता कि फैक्ट्री क्या कर रही है जो इस त्रुटि को हल करती है लेकिन मैंने 4 दिन बिताए और कहीं भी नहीं मिला।

मैं भी प्रोग्राम के MaxReceivedMessageSize अधिभावी की कोशिश की है, कुछ उदाहरण मैं जगह के आसपास पर पाया साथ:

protected override void OnOpening() 
     { 
      base.OnOpening(); 
      foreach (var endpoint in Description.Endpoints) 
      { 

       //var binding = endpoint.Binding as WebHttpBinding; 
       //if (binding != null) 
       //{ 
       // binding.MaxReceivedMessageSize = 20000000; 
       // binding.MaxBufferSize = 20000000; 
       // binding.MaxBufferPoolSize = 20000000; 
       // binding.ReaderQuotas.MaxArrayLength = 200000000; 
       // binding.ReaderQuotas.MaxStringContentLength = 200000000; 
       // binding.ReaderQuotas.MaxDepth = 32; 
       //} 


       //var transport = endpoint.Binding.CreateBindingElements().Find<HttpTransportBindingElement>(); 
       //if (transport != null) 
       //{ 
       // transport.MaxReceivedMessageSize = 20000000; 
       // transport.MaxBufferPoolSize = 20000000; 
       //} 


       var newTransport = new HttpTransportBindingElement(); 
       newTransport.MaxReceivedMessageSize = 20000000; 
       newTransport.MaxBufferPoolSize = 20000000; 
       endpoint.Binding.CreateBindingElements().Add(newTransport); 
      } 
     } 

पहला कारखाना के रूप में काम नहीं करता है एक CustomBinding जो एक WebHttpBinding में ढाला नहीं जा सकता है बनाता है। दूसरा काम नहीं करता है क्योंकि ऐसा लगता है कि बाध्यकारी तत्व केवल पढ़े जाते हैं - इससे कोई फर्क नहीं पड़ता कि मैंने तत्वों को क्या सेट किया है, कुछ भी नहीं बदला है, जिसे मैंने 'बदलते' के बाद मूल्यों को वापस पढ़कर सत्यापित किया है। तीसरा एक नया बाध्यकारी तत्व था जो वहां एक नया बाध्यकारी तत्व फेंकने का प्रयास करता था, लेकिन निश्चित रूप से यह भी असफल रहा।

अब हम पूरी तरह से नुकसान में हैं। हम इस चीज़ को चलाने के लिए कैसे प्राप्त कर सकते हैं? आपको लगता है कि यह इतना आसान होगा!

धन्यवाद लोग

Web.Config

<?xml version="1.0" encoding="UTF-8"?> 
<configuration> 
    <system.web> 
    <compilation targetFramework="4.0" /> 
    </system.web> 
    <system.serviceModel> 
    <bindings> 
     <webHttpBinding> 
     <binding name="rest" maxReceivedMessageSize="500000000" /> 
     </webHttpBinding> 
    </bindings> 
    <services> 
     <service name="SCAPIService" behaviorConfiguration="ServiceBehaviour"> 
     <endpoint address="" binding="webHttpBinding" bindingConfiguration="rest" contract="ISCAPIService" behaviorConfiguration="web"> 
     </endpoint> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior name="ServiceBehaviour"> 
      <serviceMetadata httpGetEnabled="true" /> 
      <serviceDebug includeExceptionDetailInFaults="true" /> 
     </behavior> 
     </serviceBehaviors> 
     <endpointBehaviors> 
     <behavior name="web"> 
      <webHttp /> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> 
    </system.serviceModel> 
    <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true" /> 
    </system.webServer> 
</configuration> 

संपादित करें, सुझाव दिया गया समाधान है कि अब तक असफल रहा है का उपयोग करते हुए:

public class MyServiceHost : WebServiceHost 
    { 
     public MyServiceHost() 
     { 
     } 

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

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

     protected override void ApplyConfiguration() 
     { 
      base.ApplyConfiguration(); 
      APIUsers.TestString += "here" + Description.Endpoints.Count.ToString(); 
      foreach (var endpoint in this.Description.Endpoints) 
      { 
       var binding = endpoint.Binding; 
       APIUsers.TestString += binding.GetType().ToString(); 
       if (binding is WebHttpBinding) 
       { 
        var web = binding as WebHttpBinding; 
        web.MaxBufferSize = 2000000; 
        web.MaxBufferPoolSize = 2000000; 
        web.MaxReceivedMessageSize = 2000000; 
       } 
       var myReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas(); 
       myReaderQuotas.MaxStringContentLength = 2000000; 
       myReaderQuotas.MaxArrayLength = 2000000; 
       myReaderQuotas.MaxDepth = 32; 
       binding.GetType().GetProperty("ReaderQuotas").SetValue(binding, myReaderQuotas, null); 
      } 
     } 
    } 

    class MyWebServiceHostFactory : WebServiceHostFactory 
    { 
     protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) 
     { 
      return new MyServiceHost(serviceType, baseAddresses); 
     } 
    } 

उत्तर

3

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

संपादित करें: जोड़ना मेरी servicehost कारखाने कार्यान्वयन

public class MyServiceHost : System.ServiceModel.ServiceHost 
{ 
    public MyServiceHost() { } 

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

    } 

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

    } 

protected override void ApplyConfiguration() 
      { 
       Console.WriteLine("ApplyConfiguration (thread {0})", System.Threading.Thread.CurrentThread.ManagedThreadId); 
       base.ApplyConfiguration(); 
       foreach (ServiceEndpoint endpoint in this.Description.Endpoints) 
       { 
        Binding binding = endpoint.Binding; 
        var binding = endpoint.Binding; 
        if(binding is WebHttpBinding) 
        { 
         var web = binding as WebHttpBinding; 
         web.MaxBufferSize = 2000000; 
         web.MaxReceivedMessageSize = 2000000; 
        } 
        var myReaderQuotas = new XmlDictionaryReaderQuotas(); 
        myReaderQuotas.MaxStringContentLength = 5242880; 
        binding.GetType().GetProperty("ReaderQuotas").SetValue(binding, myReaderQuotas, null); 
       } 
      } 

} 

ऊपर प्रत्येक बंधन के अपने विन्यास को ओवरराइड करता है और MaxStringContentLength सेट।

public sealed class MyServiceHostFactory : System.ServiceModel.Activation.ServiceHostFactory 
    { 
     public override System.ServiceModel.ServiceHostBase CreateServiceHost(string constructorString, Uri[] baseAddresses) 
     { 
      return base.CreateServiceHost(constructorString, baseAddresses); 
     } 

     protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) 
     { 
      return new MyServiceHost(serviceType, baseAddresses); 
     } 
    } 

अब मेरी Service.svc फ़ाइल मार्कअप इस है:

<%@ ServiceHost Language="C#" Debug="true" Factory="Sample.MyServiceHostFactory" Service="Sample.ReaderQuotasService" CodeBehind="ReaderQuotasService.svc.cs" %> 
+0

धन्यवाद राजेश। हालांकि यह अभी भी मेरे लिए काफी काम नहीं कर रहा है - किसी कारण से लागू होने पर कोई अंतराल नहीं है कॉन्फ़िगरेशन कहा जाता है - इसलिए यह इसे फ़ोरैच लूप के अंदर भी कभी नहीं बनाता है। चूंकि फैक्ट्री सभी विवरण निर्माण कर रही है, आप आवेदन कॉन्फ़िगरेशन को निकालने से पहले एंडपॉइंट कैसे बना सकते हैं? –

+0

क्या आपके लिए अधिक सहायता प्रदान करने के लिए आपके पास फैक्ट्री कोड पोस्ट करना संभव है। – Rajesh

+0

निश्चित रूप से, मैंने कोड के साथ प्रश्न अपडेट किया है। घोषणापत्र इस तरह दिखता है: <% @ ServiceHost भाषा = "सी #" डीबग = "सत्य" सेवा = "एपिनमेस्पेस। सेवा" कोडबहाइंड = "सेवा.svc.cs" फैक्टरी = "WcfService1.MyWebServiceHostFactory"%> मेरे कोड में , APIUsers.TestString मुद्रित किया गया है, बस यह सुनिश्चित करने के लिए कि यह कोड चल रहा था। नतीजा यहां था 0 (0 = एंडपॉइंट गिनती) –

7

अन्य लोगों के लाभ के लिए, ऊपर जवाब सही रास्ते नीचे चला जाता है, लेकिन यह कई त्रुटियाँ हैं और बदलाव के बिना काम नहीं करेगा (इसलिए ओपी को काम करने का समाधान नहीं मिला)। निम्नलिखित का प्रयोग करें और यह आपके लिए 'बॉक्स से बाहर' काम करेगा।

नोट - यह है अत्यंत सब नीचे कंस्ट्रक्टर्स प्रदान करने के लिए और निर्माता अधिभार कारखाने में प्रदर्शन का उपयोग करें, अन्यथा आप मिल जाएगा निम्न त्रुटि संदेश महत्वपूर्ण:

InitializeRuntime की आवश्यकता है कि विवरण संपत्ति शुरू किया जाना चाहिए। या तो CreateDescription विधि में एक वैध ServiceDescription प्रदान करने या एक विकल्प के कार्यान्वयन

कस्टम ServiceHost कार्यान्वयन प्रदान करने के लिए InitializeRuntime विधि ओवरराइड:

public class CustomServiceHost : ServiceHost 
{ 
    public CustomServiceHost() 
    { 
    } 

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

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

    protected override void OnOpening() 
    { 
     base.OnOpening(); 

     foreach (var endpoint in this.Description.Endpoints) 
     { 
      var binding = endpoint.Binding; 
      var web = binding as WebHttpBinding; 

      if (web != null) 
      { 
       web.MaxBufferSize = 2147483647; 
       web.MaxReceivedMessageSize = 2147483647; 
      } 

      var myReaderQuotas = new XmlDictionaryReaderQuotas { MaxStringContentLength = 2147483647 }; 

      binding.GetType().GetProperty("ReaderQuotas").SetValue(binding, myReaderQuotas, null); 
     } 
    } 
} 

कस्टम ServiceHostFactory कार्यान्वयन:

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

Service1.svc उपरोक्त मार्कअप तब तक काम करेगा जब तक कि प्रकार सही है। मैंने वास्तव में WebServiceHost को ओवरराइड करने के लिए इस तकनीक का उपयोग किया और बड़े JSON प्रतिक्रिया आकारों की अनुमति दी, लेकिन सिद्धांतों को सभी को ServiceHost पर भी लागू होना चाहिए।

+0

के लिए धन्यवाद, मैं बाध्यकारी गुणों में से किसी एक को ओवरराइड करने की कोशिश नहीं कर रहा हूं, लेकिन कन्स्ट्रक्टर और InitializeRuntime त्रुटि के बारे में नोट के लिए +1। यही वह था जिसकी मैं खोज कर रहा था! – AdmSteck

+0

वीबी नेट में, क्या मैं रचनाकारों के लिए .New() कीवर्ड का उपयोग करूंगा? – Thomas

+0

बहुत उपयोगी। मैं एंडपॉइंट व्यवहार जोड़ने के लिए 'ApplyConfiguration() 'का उपयोग करने का प्रयास कर रहा था, लेकिन' WebServiceHost' 'ओपनिंग()' तक अपने एंडपॉइंट्स नहीं बनाता है, इसलिए यह मुझे जा रहा है। – kenchilada

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