Reputation: 311
How can I receive multipart form data in a WCF Service? I have uploaded it using the phone gap file transfer plugin upload function.
Below are the two functions that I'm trying to call:
///<summary>
///Method for file upload
///</summary>
[OperationContract]
[WebInvoke(
Method = "POST",
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "Upload")]
string Upload(Stream data);
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "UploadImage")]
string UploadImage();
// TODO: Add your service operations here
I successfully hit the UploadImage function but I don't know how to read a file from the uploaded data.
When I try
HttpPostedFile file = HttpContext.Current.Request.Files["recFile"];
I get the error:
HttpContext.Current.Request.Files 'HttpContext.Current.Request.Files' threw an exception of type 'System.Web.HttpException' System.Web.HttpFileCollection {System.Web.HttpException}
base {"This method or property is not supported after HttpRequest.GetBufferlessInputStream has been invoked."}
This is my web.config file:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<customErrors mode="RemoteOnly"/>
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="CacheFor10Seconds" duration="10"
varyByParam="none" />
</outputCacheProfiles>
</outputCacheSettings>
</caching>
<httpRuntime maxRequestLength="2000000000"/>
</system.web>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="false" />
</appSettings>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingWithJsonP"
crossDomainScriptAccessEnabled="true" maxBufferSize="2000000000"
maxReceivedMessageSize="2000000000"
transferMode="Streamed" />
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="webHttpBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<services>
<service name="Service.Service1">
<endpoint name="mexHttpBinding"
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"
/>
<endpoint address="" behaviorConfiguration="webHttpBehavior"
binding="webHttpBinding"
bindingConfiguration="webHttpBindingWithJsonP"
contract="Service.IService1" />
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
Upvotes: 2
Views: 2420
Reputation: 311
I got the problem it with the Wcf version targetFramework="4.5" issue ,
you have to add below code in web config than the issue get resolve:
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="false" />
<add key="wcf:serviceHostingEnvironment:useClassicReadEntityBodyMode" value="true" />
</appSettings>
my all the other web Config that i post already here is working fine below is the updated web config setting
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<customErrors mode="RemoteOnly"/>
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="CacheFor10Seconds" duration="10"
varyByParam="none" />
</outputCacheProfiles>
</outputCacheSettings>
</caching>
<httpRuntime maxRequestLength="2000000000"/>
</system.web>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="false" />
<add key="wcf:serviceHostingEnvironment:useClassicReadEntityBodyMode" value="true" />
</appSettings>
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingWithJsonP"
crossDomainScriptAccessEnabled="true" maxBufferSize="2000000000"
maxReceivedMessageSize="2000000000"
transferMode="Streamed" />
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="webHttpBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<services>
<service name="Service.Service1">
<endpoint name="mexHttpBinding"
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"
/>
<endpoint address="" behaviorConfiguration="webHttpBehavior"
binding="webHttpBinding"
bindingConfiguration="webHttpBindingWithJsonP"
contract="Service.IService1" />
</service>
</services>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
This is my Service and IService Code:
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "UploadImage")]
string UploadImage();
#region
///<summary>
///Metohd to upload image.
///</summary>
public string UploadImage()
{
string JsonString = string.Empty;
JsonString = AppDomain.CurrentDomain.BaseDirectory;
try {
HttpPostedFile file = HttpContext.Current.Request.Files[0];
;
if (file == null)
{
RC.ErrorLog.LogFileWrite("<Exception>File is null</Exception>" + JsonString);
return JsonString;
}
string targetFilePath = AppDomain.CurrentDomain.BaseDirectory + @"Images\Upload" + Guid.NewGuid() + file.FileName.ToString();
file.SaveAs(targetFilePath);
return file.FileName.ToString();
}
catch(Exception e)
{
string errorMessage = RC.ErrorLog.CreateErrorMessage(e);
RC.ErrorLog.LogFileWrite(errorMessage+JsonString);
return JsonString;
}
}
#endregion
And below is my JqueryMobile code for PhoneGap
// A button will call this function
//
function captureImage() {
// Launch device camera application,
// allowing user to capture up to 2 images
debugger;
navigator.device.capture.captureImage(captureSuccess, captureError, { limit: 2 });
}
function captureSuccess(mediaFiles) {
var i, len;
for (i = 0, len = mediaFiles.length; i < len; i += 1) {
uploadFile(mediaFiles[i]);
}
}
// Called if something bad happens.
//
function captureError(error) {
var msg = 'An error occurred during capture: ' + error.code;
navigator.notification.alert(msg, null, 'Uh oh!');
}
function uploadFile(mediaFile) {
var ft = new FileTransfer();
path = mediaFile.fullPath;
name = mediaFile.name;
debugger;
// below varible contain the Server url name that i created by joining defenrent 3 var of //my application
var objUrl = _ServicesUrl._SecondServicePath + _ServicePage._BaseServicePage + _WcfFunctionUrl._ImageUpload;
alert("uploadImage");
ft.upload(path,
objUrl,
function (result) {
alert('Upload success: ' + result.responseCode);
alert(result.bytesSent + ' bytes sent');
debugger;
var abc = JSON.parse(result.Upload);
alert(abc);
},
function (error) {
alert('Error uploading file ' + path + ': ' + error.code);
},
{ fileName: name });
}
Hope the answer will help the community.
Upvotes: 4