我有一个在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(),因此问题在于流模式下的配置。
我很感激在这件事上找到任何帮助。感谢。
答案 0 :(得分:2)
问题出在您的数据合同中 - 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);
首先将数据上传到服务器,服务器将发出令牌(例如guid),使用令牌更新其他信息。
更优选的方式是使用MessageContract
并且您已尝试过。几乎没有什么建议可以解决问题:
答案 1 :(得分:2)
我遇到了同样的问题,我发现这篇文章解释了你的错误。 http://www.c-sharpcorner.com/uploadfile/BruceZhang/stream-operation-in-wcf/
希望这有帮助!