使用 mtom 流式传输二进制数据的 wcf webservice 获取错误 "An error occurred while receiving the HTTP response ***"

标签 wcf web-services serialization mtom

我必须开发一个能够发送带附件的电子邮件的 Web 服务,以及一个使用 wcf 和 mtom 进行序列化的客户端。我在工作中使用以下工具:

Windows 7 专业版 x64 微软 Visual Studio 2012 微软开发服务器/IIS Express 8.0 用户:管理员

每次我尝试在我的客户端中使用来自消息契约(Contract)的自定义类的 web 服务时,我都会收到错误消息“接收到 http://localhost:2364/Service1 的 HTTP 响应时发生错误。 svc。这可能是由于服务端点绑定(bind)未使用 HTTP 协议(protocol)。这也可能是由于 HTTP 请求上下文被服务器中止(可能是由于服务关闭)。请参阅服务器日志以了解更多详情。

现在,我只是尝试设置一个简单的测试服务和一个简单的测试客户端。我尝试了以下操作,但总是遇到相同的错误,而使用仅在请求和响应中使用简单字符串的 Web 服务中的方法运行良好,没有任何错误。

  1. 在来自 Visual Studio 2012 和 IIS Express 8.0 的集成 Microsoft 开发服务器上出现同样的错误

  2. 在客户端和服务的配置中使用 basicHttpBinding 或 wsHttpBinding 时出现同样的错误

  3. 尝试在两台服务器上生成日志文件。 IIS Express 服务器在配置以外的其他文件夹中生成一些日志,但不使用我的配置文件中的设置。 Microsoft 开发服务器不生成任何内容。

  4. 我使用 svctraceviewer.exe 观察了几个生成的日志文件,只看到了一些带有操作码 MODULE_SET_RESPONSE_ERROR_STATUS 的警告。我无法理解这些信息。

  5. 我尝试启用 localService 和 networkService 对指定文件夹的读/写权限,但没有结果。

  6. 我尝试使用 RawCap 嗅探本地主机并使用 wireshark 观察结果,但输出文件有 0 个字节(这一定是另一个问题)。

如果您需要更多信息,请告诉我。

谢谢!

以下是我的服务和客户端的代码和配置(仅用于测试):

服务:IService1.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.IO;

namespace WcfTestService
{

[ServiceContract]
public interface IService1
{

    [OperationContract]
    string GetData(int value);

    /*
    [OperationContract]
    CompositeType GetDataUsingDataContract(CompositeType composite);*/

    // TODO: Hier Dienstvorgänge hinzufügen

    [OperationContract]
    ServiceResponse TestCase(ServiceRequest testRequest);
}

/*
// Verwenden Sie einen Datenvertrag, wie im folgenden Beispiel dargestellt, um Dienstvorgängen zusammengesetzte Typen hinzuzufügen.
[DataContract]
public class CompositeType
{
    bool boolValue = true;
    string stringValue = "Hello ";

    [DataMember]
    public bool BoolValue
    {
        get { return boolValue; }
        set { boolValue = value; }
    }

    [DataMember]
    public string StringValue
    {
        get { return stringValue; }
        set { stringValue = value; }
    }
}*/

[MessageContract]
public class ServiceRequest
{
    [MessageHeader]
    public String Type { get; set; }

    [MessageBodyMember]
    public Stream Contents { get; set; }
}

[MessageContract]
public class ServiceResponse
{
    [MessageHeader]
    public String Type { get; set; }

    [MessageBodyMember]
    public Stream Contents { get; set; }
}
}

服务:web.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>

<system.diagnostics>
<sources>
  <source name="System.ServiceModel.MessageLogging"  switchValue="Ausführlich,ActivityTracing">
    <listeners>
      <add type="System.Diagnostics.DefaultTraceListener" name="Default">
        <filter type="" />
      </add>
      <add name="ServiceModelMessageLoggingListener">
        <filter type="" />
      </add>
    </listeners>
  </source>
  <source propagateActivity="true" name="System.ServiceModel" switchValue="Ausführlich,ActivityTracing">
    <listeners>
      <add type="System.Diagnostics.DefaultTraceListener" name="Default">
        <filter type="" />
      </add>
      <add name="ServiceModelTraceListener">
        <filter type="" />
      </add>
    </listeners>
  </source>
</sources>
<sharedListeners>
  <add initializeData="d:\log\web_messages.svclog"
    type="System.Diagnostics.XmlWriterTraceListener, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
    name="ServiceModelMessageLoggingListener" traceOutputOptions="Timestamp">
    <filter type="" />
  </add>
  <add initializeData="d:\log\web_tracelog.svclog"
    type="System.Diagnostics.XmlWriterTraceListener, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
    name="ServiceModelTraceListener" traceOutputOptions="Timestamp">
    <filter type="" />
  </add>
</sharedListeners>
<trace autoflush="true" />
</system.diagnostics>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<!--httpRuntime targetFramework="4.5"/>-->
<httpRuntime targetFramework="4.5" maxRequestLength="102400" executionTimeout="7200"/>
</system.web>
<system.serviceModel>
<diagnostics>
  <messageLogging logEntireMessage="true" logKnownPii="true" logMalformedMessages="true"
    logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
  <endToEndTracing propagateActivity="true" activityTracing="true"
    messageFlowTracing="true" />
</diagnostics>
<bindings>
  <basicHttpBinding>
    <binding name="basicHttpMtomBinding" closeTimeout="10:01:00"
      openTimeout="10:01:00" receiveTimeout="10:10:00" sendTimeout="10:01:00"
      transferMode="Streamed" messageEncoding="Mtom">
      <readerQuotas maxDepth="1000" maxStringContentLength="1000" maxArrayLength="1000"
        maxBytesPerRead="1000" maxNameTableCharCount="1000" />
    </binding>
  </basicHttpBinding>
  <wsHttpBinding>
    <binding name="wsHttpMtomBinding" closeTimeout="10:01:00" openTimeout="10:01:00"
      receiveTimeout="10:10:00" sendTimeout="10:01:00" maxBufferPoolSize="999999999"
      maxReceivedMessageSize="1048576" messageEncoding="Mtom"
useDefaultWebProxy="true">
      <readerQuotas maxDepth="100" maxStringContentLength="1000" maxArrayLength="1000"
        maxBytesPerRead="100000" maxNameTableCharCount="1000" />
      <reliableSession inactivityTimeout="10:10:00" />
      <security mode="None" />
    </binding>
  </wsHttpBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior>
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
<protocolMapping>
  <remove scheme="http" />
  <add scheme="http" binding="wsHttpBinding" bindingConfiguration="wsHttpMtomBinding" />
  <add scheme="https" binding="basicHttpsBinding" />
</protocolMapping>    
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
    Um das Stammverzeichnis der Webanwendung beim Debuggen auszuwählen, legen Sie den Wert unten auf "true" fest.
    Legen Sie ihn vor der Bereitstellung auf "false" fest, um die Veröffentlichung von Informationen über den Webanwendungsordner zu vermeiden.
  -->
<directoryBrowse enabled="true"/>
</system.webServer>

</configuration>

客户端:app.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
    <bindings>
        <wsHttpBinding>
            <binding name="WSHttpBinding_IService1" messageEncoding="Mtom">
                <security mode="None" />
            </binding>
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://localhost:2364/Service1.svc" binding="wsHttpBinding"
            bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1"
            name="WSHttpBinding_IService1">
            <identity>
                <userPrincipalName value="Ares\Admin" />
            </identity>
        </endpoint>
    </client>
</system.serviceModel>
</configuration>

客户端:Form1.cs

     ...

        private void button1_Click(object sender, EventArgs e)
    {

        ServiceReference1.IService1 testService = new ServiceReference1.Service1Client();
        ServiceReference1.ServiceRequest testInput = new ServiceReference1.ServiceRequest();
        ServiceReference1.ServiceResponse testOutput = new ServiceReference1.ServiceResponse();

        BinaryFormatter formatter = new BinaryFormatter();
        MemoryStream inoutStream = new MemoryStream();

        testInput.Type = "TestType";
        String test = "TestContent";
        testInput.Contents = new MemoryStream();
        formatter.Serialize(testInput.Contents, test);
        //testInput.Contents.Position = 0;

        testService.TestCase(testInput);


        MessageBox.Show("Done!");

    }

    ...

最佳答案

我在 web.config 中看不到任何服务配置数据(端点等)

    <services>
      <service behaviorConfiguration="..." name="[Namespace].Service1">
        <endpoint address="" binding="basicHttpBinding" bindingNamespace="..." bindingConfiguration="..." contract="[Namespace].IService1">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
             <add baseAddress="http://localhost:5000/Service1"/>
...

您可以在运行时配置端点(主要是在自托管服务中),但对于简单的场景和 IIS 基础架构...?

参见 http://msdn.microsoft.com/en-us/library/ee354381.aspx

关于使用 mtom 流式传输二进制数据的 wcf webservice 获取错误 "An error occurred while receiving the HTTP response ***",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13575240/

相关文章:

c# - Paypal API 和 Paypal 的示例代码?

c# - 是否可以序列化一个数组,使其元素不包含在数组的标签中?

silverlight - 将 WCF 双工轮询与 Silverlight 结合使用时出现死锁

wcf - 运行 fiddler 时得到 "Could not establish trust relationship for the SSL/TLS secure channel with authority"

wcf - 无法使用 SvcUtil.exe 创建 cs 或配置文件

c# - InvalidDataContractException ("Type cannot be serialized") 使用 WCF DataContract 时出错

web-services - 并行运行 EMR 的步骤

java - Java中POST请求体不能包含中文字符

javascript - jquery序列化div内容以发布输入数据

java - 反序列化时动态绑定(bind)JsonProperty