Saturday, May 14, 2011

File upload Service for browser client and problem on passing the fileName

I'm trying to create a File Upload service using WCF for a Browser client, so I'm hosting the service in ASP.Net and using webHttpBinding.
The service contract needs to be something like this:

namespace�FileUpload.Service �
{ �
����[ServiceContract] �
����publicinterface�IFileUploadService �
����{ �
��������[OperationContract] �
��������[WebInvoke(UriTemplate�=�"UploadFile/{fileName}")] �
��������void�UploadFile(string�fileName,�Stream�fileContent); �
����} �
}�

I need the fileName to save the file with the given name and as we know, when using Stream as a parameter, it has to be the only parameter in Message Body.
If I wasn't using webHttpBinding, I could have create a MessageContract and pass the fileName in Message Header, but since I do have to use webHttpBinding, this is not an option.
The only way to have fileName as input parameter is to pass it in Uri as shown above.

Having the contract, I implemented the service like:

namespace�FileUpload.Service �
{ �
����[AspNetCompatibilityRequirements(RequirementsMode�=�AspNetCompatibilityRequirementsMode.Allowed)] �
����publicclass�FileUploadService �
��������:�IFileUploadService �
����{
��������#region�IFileUploadService�Members
��������publicvoid�UploadFile(string�fileName,�Stream�fileContent) �
��������{ �
������������using�(StreamReader�fileContentReader�=�new�StreamReader(fileContent)) �
������������{ �
����������������string�content�=�fileContentReader.ReadToEnd(); �
������������} �
��������}
��������#endregion
����} �
} �

and the web.config like:

<system.serviceModel>
��<behaviors>
����<endpointBehaviors>
������<behavior�name="fileUploadEndpointBehavior"> �
��������<webHttp�/>
������</behavior>
����</endpointBehaviors>
����<serviceBehaviors>
������<behavior�name="fileUploadServiceBehavior"> �
��������<serviceDebug�includeExceptionDetailInFaults="true"/>
��������<serviceMetadata�httpGetEnabled="true"/>
������</behavior>
����</serviceBehaviors>
��</behaviors>
��<serviceHostingEnvironment�aspNetCompatibilityEnabled="true"/>
��<services>
����<service�name="FileUpload.Service.FileUploadService"behaviorConfiguration="fileUploadServiceBehavior"> �
������<endpoint�address=""behaviorConfiguration="fileUploadEndpointBehavior"
��������binding="webHttpBinding"contract="FileUpload.Service.IFileUploadService"/>
����</service>
��</services>
</system.serviceModel>

And the problem is, I get an exception on having fileName as an input parameter beside fileContent by browsing http://localhost/FileUpload.svc:

An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.DataContractSerializerOperationBehavior
�contract: http://tempuri.org/:IFileUploadService ----> 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.Description.MessageContractExporter.ExportMessage(Int32 messageIndex, Object state)
�� at System.ServiceModel.Description.MessageContractExporter.ExportMessageContract()
�� at System.ServiceModel.Description.DataContractSerializerOperationBehavior.System.ServiceModel.Description.IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext contractContext)
�� at System.ServiceModel.Description.WsdlExporter.CallExtension(WsdlContractConversionContext contractContext, IWsdlExportExtension extension)
�� --- End of inner ExceptionDetail stack trace ---
�� at System.ServiceModel.Description.ServiceMetadataBehavior.MetadataExtensionInitializer.GenerateMetadata()
�� at System.ServiceModel.Description.ServiceMetadataExtension.EnsureInitialized()
�� at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.InitializationData.InitializeFrom(ServiceMetadataExtension extension)
�� at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.GetInitData()
�� at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.TryHandleDocumentationRequest(Message httpGetRequest, String[] queries, Message& replyMessage)
�� at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.ProcessHttpRequest(Message httpGetRequest)
�� at System.ServiceModel.Description.ServiceMetadataExtension.HttpGetImpl.Get(Message message)
�� at SyncInvokeGet(Object , Object[] , Object[] )
�� at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
�� at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
�� at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
�� at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
�� at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
�� at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
�� at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
�� at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

I even tried hosting the service as follows, and surprisingly it works: (but I need it to be hosted by ASP.Net)

ServiceHost�host�=�new�ServiceHost(typeof(FileUploadService),�new�Uri("http://localhost/FileUpload")); �
ServiceEndpoint�serviceEndpoint�=�host.AddServiceEndpoint(typeof(IFileUploadService),�new�WebHttpBinding(),�""); �
serviceEndpoint.Behaviors.Add(new�WebHttpBehavior()); �
host.Open();�

Dose anyone have any idea What am I doing wrong?!
I really appreciate your concern.

Source: http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/b2cf07ee-e0b8-4fed-a9ae-2bac06e0c4d6

web services architecture modern architecture network security architecture new orleans architecture architecture tour chicago boat

No comments:

Post a Comment