2010-11-03 106 views
1

我有一個稱爲「鈀」在我的VS2008解決方案的一個項目REST風格的WCF Web服務。它使用經由一個名爲「Palladium.svc」頁面WebServiceHostFactory實現一個ASP.Net 3.5 Web應用程序託管。WCF WebServiceHostFactory MaxReceivedMessageSize配置

我的服務的工作方式與here的解釋類似,POST服務可以通過服務接收,以及URITemplate中定義的其他參數。

的服務效果很好,並且可以接收貼出的信息,並使用它。當後數據超過65K,我得到以下錯誤(使用在web.config和Microsoft服務跟蹤查看system.diagnostics獲得)發生
我的問題。

傳入消息的最大消息大小配額(65536)已被超出。要增加配額,請在適當的綁定元素上使用MaxReceivedMessageSize屬性。

由於服務是通過WebServiceHostFactory實現託管的,因此該服務具有由工廠爲其設置的默認綁定。我試圖通過在web.config文件中提供綁定設置和端點來覆蓋這些綁定。當我做這個但是,我得到了一個錯誤信息說:

System.InvalidOperationException,mscorlib程序,版本= 2.0.0.0,文化=中性公鑰= b77a5c561934e089

對於操作LogStartingDetails請求是流操作必須具有類型爲Stream的單個參數。

LogStartingDetails是我在我的RESTful服務中調用的方法。

顯然LogStartingDetails方法並不需要有一個單一的參數,其類型爲Stream,當工廠創建綁定我的服務是在迴應以及(或者更重要的是,它沒有當工廠爲我工作時,需要有一個參數)。

大量的研究和打幾個磚牆後,我決定創建我自己的類,從WebServiceHostFactory繼承並重寫某些實施以指定的綁定MaxReceivedMessageSize財產。
當我通過通過調試我的工廠類的服務創建步驟,我可以看到運輸收到新MaxReceivedMessageSizeMAXBUFFERSIZE值,但他們似乎並沒有做任何事情,我最終仍得到相同The maximum message size quota for incoming messages (65536) has been exceeded.拋出異常。

下面是我的服務代碼示例。如果有人能幫我弄清楚我在這裏做錯了什麼,那將會非常感激。

Palladium.svc(在ASP託管。淨Web應用程序)

<%@ ServiceHost Language="C#" Debug="true" Service="CDS.PalladiumService.Palladium" Factory="CDS.PalladiumService.MyWebServiceHostFactory" %> 

MyWebServiceHostFactory.cs(在CDS.PalladiumService項目)

using System; 
using System.ServiceModel; 
using System.ServiceModel.Activation; 
using System.ServiceModel.Channels; 
using System.ServiceModel.Web; 

namespace CDS.PalladiumService 
{ 
    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 OnOpening() 
     { 
      base.OnOpening(); 

      if (base.Description != null) 
      { 
       foreach (var endpoint in base.Description.Endpoints) 
       { 
        var transport = endpoint.Binding.CreateBindingElements().Find<TransportBindingElement>(); 
        if (transport != null) 
        { 
         transport.MaxReceivedMessageSize = 5242880; 
         transport.MaxBufferPoolSize = 5242880; 
        } 
       } 
      } 
     } 
    } 

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

IPalladium.cs(在CDS.PalladiumService項目)

using System.IO; 
using System.ServiceModel; 
using System.ServiceModel.Web; 

namespace CDS.PalladiumService 
{ 
    // NOTE: If you change the interface name "IPalladium" here, you must also update the reference to "IPalladium" in Web.config. 
    [ServiceContract] 
    public interface IPalladium 
    { 
     [OperationContract] 
     [WebInvoke(Method = "POST", UriTemplate = UriTemplate.LogStartingDetails)] 
     void LogStartingDetails(string truckId, string palladiumId, Stream postData); 
    } 
} 

Palladium.cs(在CDS.Palladium服務項目)

using System.IO; 
using System.ServiceModel.Activation; 

namespace CDS.PalladiumService 
{ 
    // NOTE: If you change the class name "Palladium" here, you must also update the reference to "Palladium" in Web.config. 
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
    public class Palladium : IPalladium 
    { 
     public void LogStartingDetails(string truckId, string palladiumId, Stream postData) 
     { 
      string contents = string.Empty; 
      using (var reader = new StreamReader(postData)) 
      { 
       contents = reader.ReadToEnd(); 
      } 

      StreamWriter sw1 = 
       File.AppendText(@"C:\log.txt"); 
      sw1.WriteLine(contents); 
      sw1.WriteLine(""); 
      sw1.Close(); 

      return; 
     } 
    } 
} 

URITemplate.cs(在CDS.PalladiumService項目)

namespace CDS.PalladiumService 
{ 
    public static class UriTemplate 
    { 
     public const string LogStartingDetails = "/log-starting/{truckId}/{palladiumId}"; 
    } 
} 

回答

2

好的,對於那些正在尋找解決上述問題的人 - 我只是對web.config文件進行了一些更改,並在我的asp.net網站中託管了該服務。

我將我的web配置中的<system.serviceModel>部分更改爲以下內容 - 這允許在配置文件的相應部分中指定帖子的最大長度的「Large Message Binding」。

<system.serviceModel> 
<bindings> 
    <webHttpBinding> 
    <binding name="largeMessageBinding" maxBufferPoolSize="5242880" maxReceivedMessageSize="5242880" transferMode="Buffered"> 
     <readerQuotas maxStringContentLength="5242880" maxArrayLength="5242880" maxBytesPerRead="5242880" /> 
    </binding> 
    </webHttpBinding> 
</bindings> 

<behaviors> 
    <endpointBehaviors> 
    <behavior name="largePostEndpointBehavior"> 
     <webHttp /> 
    </behavior> 
    </endpointBehaviors> 
    <serviceBehaviors> 
    <behavior name="CDS.UI.Resources.Services.PalladiumBehavior"> 
     <serviceMetadata httpGetEnabled="false" /> 
     <serviceDebug includeExceptionDetailInFaults="true" /> 
    </behavior> 
    </serviceBehaviors> 
</behaviors> 

<services> 
    <service behaviorConfiguration="CDS.UI.Resources.Services.PalladiumBehavior" 
    name="CDS.PalladiumService.Palladium"> 
    <endpoint address="" binding="webHttpBinding" behaviorConfiguration="largePostEndpointBehavior" 
       bindingConfiguration="largeMessageBinding" contract="CDS.PalladiumService.IPalladium" /> 
    </service> 
</services> 

</system.serviceModel> 
3

我設法通過設置以下3個設置在端點上的OnOpening方法結合來​​得到這個工作我WebServiceHost的:

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

    foreach (var endpoint in Description.Endpoints) 
    { 
    var binding = endpoint.Binding as WebHttpBinding; 
    if (binding != null) 
    { 
     const int fiveMegaBytes = 5242880; 
     binding.MaxReceivedMessageSize = fiveMegaBytes; 
     binding.MaxBufferSize = fiveMegaBytes; 
     binding.MaxBufferPoolSize = fiveMegaBytes; 
    } 
    } 
} 

我需要一個大的緩衝區的大小,因爲我不能啓用流。

+0

此代碼爲我完美工作..謝謝! – 2012-10-06 08:04:03