Uploading Image from iPhone using .NET JSON RESTful Web Services using Multipart upload with parameters

Hello All!

Yes, I am writing this blog, to help you out step by step in knowing how to upload the images from your iPhone into your Windows File System using RESTful Web Services using Multipart form upload.

You can however, extend the web services, to push the image into your SQL Server table.

The image is converted to Stream and then saved into Windows File System, with a file name as a parameter.

The purpose, of this blog is to show you the core functionality of an image upload to Windows File system using RESTful services.

This blog assumes, that you have basic knowledge on how to create basic .NET RESTful Services, iOS Programming, .Net

OK, Lets get started!

RESTFul Web Services

You will get some useful information on how to create a basic .Net RESTFul Services using any Search Engine.

In the Service Contract of your RESTful web service, copy the following code, to create a contract:

[OperationContract]
[WebInvoke(Method = “POST”,ResponseFormat = WebMessageFormat.Json,RequestFormat = WebMessageFormat.Json,BodyStyle = WebMessageBodyStyle.Wrapped,UriTemplate = “/FileUploaded/?fileName={fileName}”)]
string SendFile(string fileName, System.IO.Stream fileContents);

and then in the Service.svc.cs file, copy the below code:

public string SendFile(string fileName, System.IO.Stream fileContents)
{
try
{

MultipartParser parser = new MultipartParser(fileContents); // You will have to download the MultipartParser class from the link and use it in your Services.svc.cs class.

if (parser.Success)
{

System.IO.MemoryStream ms = new System.IO.MemoryStream(parser.FileContents, 0, parser.FileContents.Length);
System.Drawing.Image image1 = System.Drawing.Image.FromStream(ms, true);
image1.Save(“C:\\inetpub\\wwwroot\\ImageService\\uploads\\” + fileName + “.jpg”);
return “True”;
}
}
catch (Exception ex)
{

// Do some Exception Handling here.
}

return “False”;

}

RESTful Services are done for now, Lets move onto XCode and add a few things to get this working!

In the Xcode, side of things, we will be building two parameters, one for the Image Name and the second Image Stream.

-(void) UploadImages

{

sImageName = @”TESTImage”

UIImage *image = [UIImage imageNamed:@”test.jpg”]; // Ensure that you have some dummy image file in your project added, with the name “test.jpg”.

NSString *sURLString;

sURLString = [NSString stringWithFormat:@”http:////Service.svc/FileUploaded/?fileName=%@”,sImageName];

// NOTE THAT YOUR URI TEMPLATE IN THE OPERATION CONTRACT MATCHES THE JSON URL YOU ARE PASSING. For eg. in the Operation Contract the URITemplate was UriTemplate = “/FileUploaded/?fileName={fileName}”)

NSURL *url = [[NSURL alloc] initWithString:sURLString];

NSMutableURLRequest *urequest = [NSMutableURLRequest requestWithURL:url];

[urequest setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];

[urequest setHTTPShouldHandleCookies:NO];

[urequest setTimeoutInterval:4800];

[urequest setHTTPMethod:@”POST”];

NSString *boundary = @”—————————14737809831466499882746641449″;

NSString *contentType = [NSString stringWithFormat:@”multipart/form-data; boundary=%@”, boundary];

[urequest setValue:contentType forHTTPHeaderField: @”Content-Type”];

NSMutableData *body = [NSMutableData data];

// add image data

NSData *imageData = UIImageJPEGRepresentation(image,0.25); // You can compress the image in the range from 0.01 to 1, I have compressed the image quality to a quarter, to save me from timeouts and storage space problems.

if (imageData) {

[body appendData:[[NSString stringWithFormat:@”–%@\r\n”, boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[[NSString stringWithFormat:@”Content-Disposition: form-data; name=\”%@\”; filename=\”1.jpg\”\r\n”, @”1″] dataUsingEncoding:NSUTF8StringEncoding]]; // I am storing the image in the JPG format.

[body appendData:[@”Content-Type: image/jpeg\r\n\r\n” dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:imageData];

[body appendData:[[NSString stringWithFormat:@”\r\n”] dataUsingEncoding:NSUTF8StringEncoding]];

}

[body appendData:[[NSString stringWithFormat:@”–%@–\r\n”, boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[urequest setHTTPBody:body];

[urequest addValue:[NSString stringWithFormat:@”%d”, [imageData length]] forHTTPHeaderField:@”Content-Length”];

NSData *returnData = [NSURLConnection sendSynchronousRequest:urequest returningResponse:nil error:nil];

//NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];

}

}

You are done? But are some troubleshooting aspects you need to take care of.

Any Web Requests has got two aspects, one is the timeout and the other is the message size. We will have to handle both of these in our web.config file, so that we don’t end up not passing the image to the web service.

Web Service

We will have to a WebHTTPBinding to bail us out of the timeout and the image size problems.

In the system.servicemodel tag, add the below markup

<bindings>
<webHttpBinding>
<binding name=”StreamedRequestWebBinding” bypassProxyOnLocal=”true”
useDefaultWebProxy=”false”
hostNameComparisonMode=”WeakWildcard”
sendTimeout=”00:05:00″
openTimeout=”00:05:00″
receiveTimeout=”00:05:00″
maxReceivedMessageSize=”2147483647″
maxBufferSize=”2147483647″
maxBufferPoolSize=”2147483647″
transferMode=”StreamedRequest”>
<readerQuotas maxArrayLength=”2147483647″ maxStringContentLength=”2147483647″ />
</binding>
</webHttpBinding>
</bindings>

<!–<standardEndpoints>
<webHttpEndpoint>
–><!–
Configure the WCF REST service base address via the global.asax.cs file and the default endpoint
via the attributes on the <standardEndpoint> element below
–>

<services>

<service name=”<YourClassName>.<YourServiceName>” behaviorConfiguration=”ServiceBehaviour”>
<endpoint address=”” binding=”webHttpBinding” bindingConfiguration=”StreamedRequestWebBinding” contract=”<YourClassName>.<YourContractClassName>” behaviorConfiguration=”webBehavior”>
</endpoint>
<host>
<baseAddresses>
<add baseAddress=”http://localhost:8000/&#8221; />
</baseAddresses>
</host>
</service>

</services>

<behaviors>
<serviceBehaviors>
<behavior name=”ServiceBehaviour”>

<!– To avoid disclosing metadata information, set the values below to false before deployment –>
<serviceMetadata httpGetEnabled=”true” httpsGetEnabled=”true”/>

<!– To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information –>
<serviceDebug includeExceptionDetailInFaults=”false”/>

</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name=”webBehavior”>
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>

<protocolMapping>
<add binding=”basicHttpsBinding” scheme=”https” />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled=”true” multipleSiteBindingsEnabled=”true” />

And thats it!, I hope you get this through! It was a lot of hardwork, that I had put into this to make it work. And I hope this helps you!

Just drop in your comments, in case, you face any difficulty in the above steps!

-Good Luck!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s