ShresthaGanesh
ShresthaGanesh

Reputation: 169

how to pass extra information along with data Stream in WCF Rest Service

What i wanted is to upload a file from client end to the server with the filename and the string using wcf service.But if i pass the filename i solution gets build without error but when i run the service i get the following error.But if the method contain only stream as parameter it works fine.I have googled but could find no luck.below are my contrac and config file:

in contract file

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

config file:

<?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>

error:

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)

Is there a way to solve this problem..

Thanks in advance.

Upvotes: 1

Views: 1482

Answers (1)

flayn
flayn

Reputation: 5322

If you have a Stream parameter in your operation contract you cannot have additional parameters. If you want to add additional information you can add message headers.

Wrap your channel in a OperationContextScope to add them on the client

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

You can read it on the server:

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

Upvotes: 1

Related Questions