WCF WebServiceHostFactory MaxReceivedMessageSize配置

前端之家收集整理的这篇文章主要介绍了WCF WebServiceHostFactory MaxReceivedMessageSize配置前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在我的VS2008解决方案中有一个名为“Palladium”的RESTful WCF Web服务作为项目.它通过名为“Palladium.svc”的页面使用WebServiceHostFactory实现托管在ASP.Net 3.5 Web应用程序中.

我的服务工作方式类似于here解释的方式,服务可以接收POST以及URITemplate中定义的其他参数.

该服务运作良好,我可以收到发布的信息并使用它.
我的问题发生在帖子数据超过65k并且我得到以下错误(使用web.config和Microsoft服务跟踪查看器中的system.diagnostics获得).

The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota,use the MaxReceivedMessageSize property on the appropriate binding element.

由于该服务是通过WebServiceHostFactory实现托管的,因此该服务已为工厂设置了默认绑定.我试图通过在web.config文件中提供绑定设置和端点来覆盖这些绑定.但是,当我这样做时,我收到一条错误消息:

System.InvalidOperationException,mscorlib,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089

For request in operation LogStartingDetails to be a stream the operation must have a single parameter whose type is Stream.

LogStartingDetails是我在RESTful服务中调用方法.

显然,LogStartingDetails方法不需要具有类型为Stream的单个参数,因为当工厂为我创建绑定时,服务响应良好(或者更重要的是,它不需要具有单个参数当工厂为我工作时).

在经过大量研究并打了几个砖墙后,我决定创建自己的类,该类继承自WebServiceHostFactory并覆盖一些实现,以便在绑定上指定MaxReceivedMessageSize属性.
当我通过调试在工厂类中逐步完成服务创建时,我可以看到传输接收到新的MaxReceivedMessageSize和MaxBufferSize值,但它们似乎没有做任何事情,我仍然得到相同的最大消息大小配额已超出传入消息(65536).异常抛出.

以下是我的服务代码示例.如果有人能帮助我弄清楚我在这里做错了什么,我将不胜感激.

Palladium.svc(托管在ASP.Net 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.PalladiumService项目中)

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,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}";
    }
}

解决方法

我设法通过在我的WebServiceHost的Onopening方法中的端点绑定上设置以下3个设置来实现此功能
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;
    }
  }
}

我需要一个大的缓冲区大小,因为我无法启用流式传输.

猜你在找的asp.Net相关文章