如何在WCF Rest Service中传递额外信息和数据流

时间:2014-03-28 09:06:56

标签: c# .net web-services wcf

我想要的是使用文件名和字符串使用wcf service从客户端上传文件到服务器。但是如果我传递文件名我解决方案得到构建没有错误但是当我运行服务时我得到以下错误。但是如果方法只包含stream作为参数它工作正常。我用谷歌搜索但是没有找到运气。下面是我的contrac和配置文件:

合同文件中的

[WebInvoke(UriTemplate = "UploadFile/filename={filename}" ,BodyStyle = WebMessageBodyStyle.Bare)]
        void UploadFile(Stream fileContents,string filename);

配置文件:

<?xml version="1.0"?>
<configuration>
<system.web>
    <compilation debug="true" targetFramework="4.0"/>
  </system.web>
  <system.serviceModel>
    <services>
      <service name="WcfServiceLibrary1.Service1" behaviorConfiguration="ServiceBehaviour">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary1/Service1/"/>
          </baseAddresses>
        </host>
        <endpoint address="soap" binding="wsHttpBinding" contract="WcfServiceLibrary1.IService1">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="rest" binding="webHttpBinding" contract="WcfServiceLibrary1.IService1" behaviorConfiguration="restEndpointBehavior">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehaviour">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
      <behavior name="restEndpointBehavior">
        <webHttp/>
      </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

错误:

System.InvalidOperationException: For request in operation UploadFile to be a stream the operation must have a single parameter whose type is Stream.
   at System.ServiceModel.Dispatcher.StreamFormatter.ValidateAndGetStreamPart(MessageDescription messageDescription, Boolean isRequest, String operationName)
   at System.ServiceModel.Dispatcher.StreamFormatter.Create(MessageDescription messageDescription, String operationName, Boolean isRequest)
   at System.ServiceModel.Dispatcher.OperationFormatter..ctor(OperationDescription description, Boolean isRpc, Boolean isEncoded)
   at System.ServiceModel.Dispatcher.DataContractSerializerOperationFormatter..ctor(OperationDescription description, DataContractFormatAttribute dataContractFormatAttribute, DataContractSerializerOperationBehavior serializerFactory)
   at System.ServiceModel.Description.DataContractSerializerOperationBehavior.GetFormatter(OperationDescription operation, Boolean& formatRequest, Boolean& formatReply, Boolean isProxy)
   at System.ServiceModel.Description.DataContractSerializerOperationBehavior.System.ServiceModel.Description.IOperationBehavior.ApplyDispatchBehavior(OperationDescription description, DispatchOperation dispatch)
   at System.ServiceModel.Description.DispatcherBuilder.BindOperations(ContractDescription contract, ClientRuntime proxy, DispatchRuntime dispatch)
   at System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost)
   at System.ServiceModel.ServiceHostBase.InitializeRuntime()
   at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at Microsoft.Tools.SvcHost.ServiceHostHelper.OpenService(ServiceInfo info)

有没有办法解决这个问题..

提前致谢。

1 个答案:

答案 0 :(得分:1)

如果您的操作合同中有Stream参数,则无法获得其他参数。如果您想添加其他信息,可以添加邮件标题。

将您的频道包含在OperationContextScope中,以便在客户端上添加它们

using (new OperationContextScope((IContextChannel)channel))
{
MessageHeader customMessageHeader = MessageHeader.CreateHeader(<name>, <namespace>, <value>);
OperationContext.Current.OutgoingMessageHeaders.Add(customMessageHeader);
}

您可以在服务器上阅读:

OperationContext.Current.IncomingMessageHeaders.GetHeader<Type>(<name>, <namespace>);