【问题标题】:WCF Streaming issue with ASP.NETASP.NET 的 WCF 流问题
【发布时间】:2011-09-29 09:03:14
【问题描述】:

我在 ASP.NET 应用程序中托管了 WCF 服务,并尝试使用流模式从另一个客户端 ASP.NET 应用程序上传文件。 我不断收到以下错误:

远程服务器返回一个 意外响应:(400)坏 请求。

我已经浏览了网络寻求帮助,但无济于事。

主机配置:

    <bindings>
      <basicHttpBinding>
        <binding name="FileTransferServicesBinding"
          transferMode="Streamed"
          messageEncoding="Mtom"
          sendTimeout="01:05:00"
          maxReceivedMessageSize="10067108864">
        </binding>
      </basicHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="FileTransferServiceBehavior" name="WebServiceHost.TransferService">
        <clear />
        <endpoint address="" binding="basicHttpBinding"
          bindingConfiguration="FileTransferServicesBinding" contract="WebServiceHost.ITransferService">
          <identity>
            <dns value="localhost"/>
            <certificateReference storeName="My" storeLocation="LocalMachine"
                x509FindType="FindBySubjectDistinguishedName" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange">
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:11291/TransferService.svc" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="FileTransferServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

合同代码:

[ServiceContract]
public interface ITransferService
{
    [OperationContract]
    RemoteFileInfo DownloadFile(DownloadRequest request);

    [OperationContract]
    void UploadFile(RemoteFileInfo request);

    [OperationContract]
    string TestMethod();
}

[MessageContract]
public class DownloadRequest
{
    [MessageBodyMember]
    public string FileName;
}

[MessageContract]
public class RemoteFileInfo : IDisposable
{
    [MessageHeader(MustUnderstand = true)]
    public string FileName;

    [MessageHeader(MustUnderstand = true)]
    public long Length;

    [MessageBodyMember(Order = 1)]
    public System.IO.Stream FileByteStream;

    public void Dispose()
    {
        if (FileByteStream != null)
        {
            FileByteStream.Close();
            FileByteStream = null;
        }
    }
}

客户端配置:

<bindings>
  <basicHttpBinding>
    <binding name="FileTransferServicesBinding" sendTimeout="01:05:00"
        maxReceivedMessageSize="10067108864" messageEncoding="Mtom"
        transferMode="Streamed" />
  </basicHttpBinding>
</bindings>
<client>
  <endpoint address="http://localhost:11291/TransferService.svc/"
      binding="basicHttpBinding" bindingConfiguration="FileTransferServicesBinding"
      contract="TransferServiceReference.ITransferService" name="FileTransferService"
      kind="">
    <identity>
      <dns value="localhost" />
      <certificateReference storeName="My" storeLocation="LocalMachine"
          x509FindType="FindBySubjectDistinguishedName" />
    </identity>
  </endpoint>
</client>
<behaviors>
  <serviceBehaviors>
    <behavior>
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>

客户端代码:

ITransferService clientUpload = new TransferServiceClient();

string datetime = clientUpload.TestMethod();

var uploadRequestInfo = new RemoteFileInfo();

uploadRequestInfo.FileName = FileUpload1.FileName;
uploadRequestInfo.Length = FileUpload1.PostedFile.ContentLength;
uploadRequestInfo.FileByteStream = FileUpload1.PostedFile.InputStream;
clientUpload.UploadFile(uploadRequestInfo);

clientUpload.TestMethod() 和 clientUpload.UploadFile(uploadRequestInfo) 的调用均失败。在缓冲模式下调用 clientUpload.TestMethod(),所以问题在于流模式下的配置。

如果能就此事找到任何帮助,我将不胜感激。谢谢。

【问题讨论】:

  • 我看不出配置有任何明显错误。您可能需要在服务上Enable Tracing 才能更深入地挖掘

标签: c# asp.net wcf streaming wcf-binding


【解决方案1】:

问题在于您的数据合同 - public System.IO.Stream FileByteStream;。从数据合约中删除该成员并在您的操作合约中使用stream - 例如:

[OperationContract(OneWay=true)]
void UploadFile(RemoteFileInfo request, System.IO.Stream fileData);

引自Large Data and Streaming(MSDN):

你不应该使用 System.IO.Stream里面的派生类型 的数据合同。流数据应该 使用流媒体进行通信 型号,说明如下 “流数据”部分。

来自同一链接的流数据部分对此进行了详细说明。

问题在于您的数据合同 - public System.IO.Stream FileByteStream;。从数据合约中删除该成员并在您的操作合约中使用stream - 例如:

[OperationContract(OneWay=true)]
void UploadFile(RemoteFileInfo request, System.IO.Stream fileData);

引自Large Data and Streaming(MSDN):

你不应该使用 System.IO.Stream里面的派生类型 的数据合同。流数据应该 使用流媒体进行通信 型号,说明如下 “流数据”部分。

来自同一链接的流数据部分对此进行了详细说明。

编辑: 道歉 - 我忽略了限制。您有两种方法可以解决此问题 - 使用 MessageContract 或对单个事务使用多个操作。使用多个操作的示例将是

[OperationContract]
Token UploadFile(System.IO.Stream fileData);

[OperationContract]
void ProvideFileInfo(Token token,  RemoteFileInfo request);

首先将数据上传到服务器,服务器会颁发一个token(例如guid),使用该token更新其他信息。

更可取的方法是使用 MessageContract 并且您已经尝试过。一些解决问题的建议:

  1. 如果您将其托管在 IIS 中,请检查 web.config 中的 maxRequestLength。尝试上传小文件。
  2. 不要直接使用 PostedFile 流,而是将其存储到磁盘并在其上使用流。原因是在上传过程中可能会清理 http 请求流。
  3. 使用诸如 fiddler 之类的工具并查看通过线路传输到服务的消息,这可能会提供线索。

【讨论】:

  • 使用 Stream 时限制很少:流类型只能有一个参数或返回值,如果传递了其他类型参数,则会抛出以下错误:“System.InvalidOperationException: For request在将 UploadFile 操作作为流的操作中,该操作必须有一个类型为 Stream 的参数。"
  • 我还需要传递一些与流相关的数据,例如标识值,因此使用了 MessageContract。同样,当 MessageContract 用于单个参数时是允许的。
  • 仅供参考:当 void UploadFile(RemoteFileInfo request, System.IO.Stream fileData); 时抛出异常;使用:“UploadFile 操作具有参数或返回类型,该参数使用 MessageContractAttribute 属性。为了使用消息合同表示请求消息,该操作必须具有使用 MessageContractAttribute 属性的单个参数。为了表示响应使用 Message Contract 的消息,操作的返回值必须是使用 MessageContractAttribute 属性的类型,并且操作可能没有任何 out 或 ref 参数。"
  • @rageit,抱歉! - 我忽略了限制和您对MessageContract 属性的使用。查看我的编辑 - 看看这些建议是否有帮助。
【解决方案2】:

我遇到了同样的问题,我发现这篇文章解释了解决您的错误。 http://www.c-sharpcorner.com/uploadfile/BruceZhang/stream-operation-in-wcf/.

希望对您有所帮助!

【讨论】:

    猜你喜欢
    • 2011-01-28
    • 1970-01-01
    • 2010-12-18
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 2012-03-30
    • 2011-05-02
    • 1970-01-01
    相关资源
    最近更新 更多