WCF的一个怪异问题,高手请进

6 篇文章 0 订阅

今天遇到一个问题,系统基于WCF框架,不同的服务完全相似的代码,一个就报错,一个成功。而且报错的代码其实际顺利运行完毕所有代码,事务也成功地提交了,只是在返回信息时WCF给了一个错误信息:

<Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none"><Code><Value>Receiver</Value><Subcode><Value xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</Value></Subcode></Code><Reason><Text xml:lang="zh-CN">message 对象已被释放。</Text></Reason><Detail><ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><HelpLink i:nil="true"/><InnerException i:nil="true"/><Message>message 对象已被释放。</Message><StackTrace>   在 System.ServiceModel.Channels.ByteStreamMessage.InternalByteStreamMessage.get_Properties()
↵   在 System.ServiceModel.OperationContext.get_IncomingMessageProperties()
↵   在 System.ServiceModel.Web.IncomingWebRequestContext.get_UriTemplateMatch()
↵   在 System.ServiceModel.Description.WebHttpBehavior.TrySetupJavascriptCallback(String callbackParameterName)
↵   在 System.ServiceModel.Dispatcher.JavascriptCallbackMessageInspector.BeforeSendReply(Message& reply, Object correlationState)
↵   在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.BeforeSendReplyCore(MessageRpc& rpc, Exception& exception, Boolean& thereIsAnUnhandledException)</StackTrace><Type>System.ObjectDisposedException</Type></ExceptionDetail></Detail></Fault>

经过排查,发现是由于Web.Config文件中binging节点的 crossDomainScriptAccessEnabled="true" 属性导致的,去掉后一切正常。微软官方帮助文档说该属性是用来设定是否允许跨域脚本访问,不清楚为何该属性会导致上述问题。只不过我们项目暂时不存在跨域访问问题,故去掉没有大碍。


具体web.config配置文件和代码如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="Service.ServiceBehavior" name="VME.Service.PictureService">
        <endpoint address="" behaviorConfiguration="VME.Service.ServiceAspNetAjaxBehavior"
          binding="webHttpBinding" contract="VME.Contract.IPictureService" bindingConfiguration="webBinding" />
      </service>
      <service behaviorConfiguration="Service.ServiceBehavior" name="VME.Service.ServiceService">
        <endpoint address="" behaviorConfiguration="VME.Service.ServiceAspNetAjaxBehavior"
          binding="webHttpBinding" contract="VME.Contract.IServiceService" bindingConfiguration="serviceBinding" />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="VME.Service.ServiceAspNetAjaxBehavior">
          <enableWebScript />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="Service.ServiceBehavior">
          <serviceThrottling maxConcurrentCalls="50" maxConcurrentSessions="50" maxConcurrentInstances="50"/>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true" />
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
      <add binding="webHttpBinding" scheme="http" />
    </protocolMapping>
    <bindings>
      <webHttpBinding>
        <binding name="webBinding" useDefaultWebProxy="false" crossDomainScriptAccessEnabled="true"
                 maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647"
                 sendTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:01:00" closeTimeout="00:01:00"
                 transferMode="Streamed" hostNameComparisonMode="StrongWildcard">
          <readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647" maxDepth="32" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
          <security mode="None"></security>
        </binding>
        <binding name="serviceBinding" useDefaultWebProxy="false" crossDomainScriptAccessEnabled="true"
                 maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647"
                 sendTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:01:00" closeTimeout="00:01:00"
                 transferMode="Streamed" hostNameComparisonMode="StrongWildcard">
          <readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647" maxDepth="32" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
          <security mode="None"></security>
        </binding>
      </webHttpBinding>
    </bindings>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
</configuration>

[ServiceContract]
public interface IPictureService
{
    [OperationContract]
    [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
    bool SendIdCardPicture(Stream idCardImg);
}

[ServiceContract]
public interface IServiceService
{
    [OperationContract]
    [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
    bool AddService(Stream service);
}
上面IPictureService接口的程序是能正常返回信息,而IServiceService接口的程序就报错。

有高手请给予指点迷津,到底哪里出了问题。



好的,下面是一个简单的 C# WCF 服务的例子: 首先,在 Visual Studio 中创建一个新的 WCF 服务应用程序项目。然后,在服务契约中定义一个简单的操作: ```C# [ServiceContract] public interface IMyService { [OperationContract] string GetMessage(string name); } ``` 这个操作接受一个字符串类型的参数,返回一个字符串类型的消息。 接下来,在服务实现中实现这个操作: ```C# public class MyService : IMyService { public string GetMessage(string name) { return "Hello, " + name + "!"; } } ``` 这个实现接受一个字符串类型的参数,返回一个拼接了该参数的消息。 然后,在配置文件中定义一个终结点: ```XML <system.serviceModel> <services> <service name="MyService"> <endpoint address="http://localhost:8080/MyService" binding="basicHttpBinding" contract="IMyService"/> </service> </services> </system.serviceModel> ``` 这个终结点定义了服务的地址、绑定和契约等信息。 最后,在 host 中启动服务: ```C# ServiceHost host = new ServiceHost(typeof(MyService)); host.Open(); ``` 这个 host 启动了 MyService 类型的服务。 现在,WCF 服务已经启动并且可以接收客户端的请求。在客户端中,你可以使用类似下面的代码来调用服务: ```C# ChannelFactory<IMyService> factory = new ChannelFactory<IMyService>( new BasicHttpBinding(), new EndpointAddress("http://localhost:8080/MyService")); IMyService proxy = factory.CreateChannel(); string message = proxy.GetMessage("World"); Console.WriteLine(message); ``` 这个客户端创建了一个 IMyService 类型的代理对象,并调用了它的 GetMessage 方法,将 "World" 作为参数传递,并将返回的消息打印到控制台上。 这就是一个简单的 C# WCF 服务的例子,它展示了如何定义服务契约、实现服务操作、配置服务终结点和启动服务 host。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值