Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

this is going to be a question about sending data from the iPhone to a MVC 3 function.

To get into the topic what I'm already doing and what is working, just to see the style how I'm implementing the connections.

Here I have a sample MVC Controller function, running on my IIS 7.0.

The SampleController : Controller

public ActionResult MyFunction(MyObject object) {
    ContentResult result = new ContentResult();
    result.Content = some content from the server encoded as JSON
    return result;
}

On the iPhone I call this function like this.

NSString *urlString = [NSString stringWithFormat:@"https://%@:%d/%@/%@", _host, _port, Sample, MyFunction];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:@"POST"];

[request setHTTPBody:json]; // some json encoded object that fits the MyObject from asp.NET

NSURLResponse *response;
NSError *error;
// synchronous so the sample code is shorter
NSData *data = [NSURLConnection sendSynchronousRequest:request
                                     returningResponse:&response
                                                 error:&error];

// Do some error handling and http status code stuff and finally the json stuff from the NSData object

So this stuff is all working fine, but now I'm at a point where it get's confusing. I need to upload a NSData Object, containing image Data or other stuff. Uploading just the file using mulipart/form-data as shown in this SO answer. But when adding some url parameters it does not work anymore.

____________________________________________________

So now there are two options from here to solve my problem:

The first approach is: How would a NSURLRequest look like for using a Function like this? Or is this even possible?

public ActionResult MyFunction(MyObject object, byte[] binaryData) {
    // Some server stuff ect.
}

Or how would I build my NSURLRequest using my first Function and adding a file attachment?

Edit

Here is how I build my current file upload request. It is basically the same I do in the second code snippet.

NSString *urlString = [NSString stringWithFormat:@"https://%@:%d/%@/%@", _host, _port, Sample, MyFunction];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:@"POST"];

[request setHTTPBody:json];

And finally the file attachment. Note When only using the file attachment without parameters everything works fine, but well yeah the params are missing.

+ (void)attachFile:(NSData *)fileData withFilename:(NSString *)filename toRequest:(NSMutableURLRequest *)request {
NSString *boundary = @"---------------------------94712889831966399282116247425";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
[request addValue:contentType forHTTPHeaderField: @"Content-Type"];

NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"%@\"\r\n", filename]
                  dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:fileData]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

NSData *oldBody = [request HTTPBody];
if (oldBody) {
    [body appendData:oldBody];
}

[request setHTTPBody:body];
}

So my guess is now, that there is some boundary stuff for the parameters missing.

Note

As an addition I use a synchronous NSURLConnection on a background Thread.

NSURLResponse *response;
NSError *error;
NSData *data = [NSURLConnection sendSynchronousRequest:request
                                     returningResponse:&response
                                                 error:&error];
share|improve this question
Posting the relevant code would help to answer your question ;) The most errors occur when encoding the URL string containing params, or when creating the rather error prone multipart/form-data body. – CouchDeveloper Jun 13 at 7:31
You might now check if the server understands the parameters in the URL. Ask the web-service developers, too. If not (likely), wrap each parameter into a part, separated by the correct boundaries. Ideally, each part's value "should" have a Content-Type and Content-Length. This of course will become cumbersome, where you might start thinking of a third party, tool -- or even better: use JSON as transport format. – CouchDeveloper Jun 13 at 20:53
1  
"As an addition I use a synchronous NSURLConnection on a background Thread." As a serious developer creating serious apps, don't use convenient APIs which are for sample and toy apps only. That is, use NSURLConnection in asynchronous mode, implementing the delegates. You need that anyway, later when you have to implement your server trust authentication with a self signed cert. – CouchDeveloper Jun 13 at 20:57
Well no need for that right now, it's for a research project in school about the basic principles of convergent encryption. But thank you for pointing out that the authentication challenge does not work with synchronous connections using NSURLConnection! I guess for production I would use it async with delegate or AFNetworking. +1 – Arndt Bieberstein Jun 13 at 22:14
Server trust authentication will (very likely) work with the convenient API when the root certificate is signed by a Certificate Authority. Self signed certificates will require you to override a delegate message, though. – CouchDeveloper Jun 14 at 4:48

1 Answer

From the given sample (please add more actual code), it is difficult to tell where there is an issue - but there are a few potential culprits.

First off, the request depends on what your server will accept.

A POST request usually embeds "parameters" in the multipart/form-data body. Browsers would not include "parameters" in the URL - and a server may not expect or accept this as well.

share|improve this answer
That's a really helpful question. I didn't know that in multipart-form-data the params are encapsulated in the body. That could actually be the reason. I'll add a detailed Code. – Arndt Bieberstein Jun 13 at 9:26

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.