Post JSON to ASP.NET from iOS - ios

I am trying to POST JSON data to my asp.net MVC server from an iPhone app. The method in my server looks like this:
[HttpPost]
public String MyMethod(Stream anUpload) { ... }
And here is the code to POST the JSON from my app:
NSString *theURL = [NSString stringWithFormat:#"http://192.168.1.103/MyServer/MyMethod"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:theURL]];
[theRequest setHTTPMethod:#"POST"];
// Serialize my data.
NSData *theData = [NSJSONSerialization dataWithJSONObject:theList options:kNilOptions error:nil];
[theRequest setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[theRequest setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[theRequest setValue:[NSString stringWithFormat:#"%d", [theData length]] forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPBody:theData];
However, when I send the request, I just get an error message from the server, the MyMethod() never gets called. I am assuming that there is an issue with ASP accepting the POST data. Any ideas?
EDIT: Answer below

I found the answer:
I just needed to change the server-side function to
public String MyMethod(List<string> aList) { ... }
The ModelBinder was trying to deserialize the JSON for me, and it didn't like my parameter being a Stream.

Related

Implement Soap Based Services with wsdl format in iOS?

I have to implement the XML base soap service in my iOS application.i have goggled the things but dint find proper implementation. here is my URL of XML based WSDL service.
http://www.XXX.XX.XX/IntegrationService/MobileAppServicePort?wsdl
following is the response when we call this service in SOA Client
Service name: MobileAppIntegrationService
Description: undefined
Targetnamespace: http://integration.XXX.XXXX.XXX.XX/
Operations: (please choose one of the listed operations)
1. Operation: getNewsDetails
2. Operation: getNewsList
3. Operation: login
4. Operation: getRulesList
now can any one please tell me how can i implement this kind of web-service to post or get the data from above operations as i have never been to this XML based soap service.
we have tried following thing to use one opertaion of CreateUser
soapMessage = #"<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><getCountriesList xmlns=\"http://integration.esi.dtps.gov.ae/\"></getCountriesList></soap:Body></soap:Envelope>";
//Now create a request to the URL
NSURL *url = [NSURL URLWithString:#""]; //<--
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:#"%d", [soapMessage length]];
//ad required headers to the request
[theRequest addValue:#"" forHTTPHeaderField:#"Host"];//<--
[theRequest addValue: #"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[theRequest addValue: #"" forHTTPHeaderField:#"SOAPAction"];//<--
[theRequest addValue: msgLength forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPMethod:#"POST"];
[theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
and we are confused that what to add in "HOST" "SOAPACTION" & "URL". can anyone please guide.

Cannot get correct return message when consuming WCF web-service via NSURLConnection

I have a WCF web-service. If I just put the URL into the browser, I will get the error message: Forbidden. But if I post data through Fetcher(a HTTP Simulator in OS X), I can get the correct return value.
Now, I tried to use NSURLConnection to post data to the web-service and fetch the return value.
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:postURL];
[request setHTTPMethod:#"POST"];
[request setValue:[NSString stringWithFormat:#"%d", postData.length] forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSURLResponse * response = nil;
NSError * error = [[NSError alloc] init];
receivedData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString * receivedStr = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
But all I get is just the html code of the error page I can see from the browser(that forbidden message).
Please help me figure it out. Thanks in advance.
EDIT:
I set up a PHP server and try to do the same thing. I works perfectly. Therefore, I highly doubt it is the WCF problem. Anyone has some good ideas?
if you use generated .svc service you need to :
change
[request setValue:#"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
to
[request addValue:#"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-type"];
also you need to SOAPAction field according to operation you request
What is you postData?

Fields to be set in HTTP header

I am calling a web service in iOS. For this, I need to set the header in NSMutableURLRequest object. My service takes two string parameters and returns data in JSON format.
What are the the fields that I need to set in the header (Both while using GET and POST) using the setValue:forHTTPHeaderField:.
We do not need to use setHTTPBody: while using GET.. right???
I had the same question and I resolved (using some code from Iducool and Ankit Mehta) like this...
NSURL *theURL = [NSURL URLWithString:#"yourURL"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:20.0f];
//Specify method of request(Get or Post)
[theRequest setHTTPMethod:#"GET"];
//Pass some default parameter(like content-type etc.)
[theRequest setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[theRequest setValue:#"application/json; charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
//Now pass your own parameter
[theRequest setValue:yourValue forHTTPHeaderField:theNameOfThePropertyValue];
NSURLResponse *theResponse = NULL;
NSError *theError = NULL;
NSData *theResponseData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&theResponse error:&theError];
//Now you can create a NSDictionary with NSJSONSerialization
NSDictionary *dataDictionaryResponse = [NSJSONSerialization JSONObjectWithData:theResponseData options:0 error:&theError];
NSLog(#"url to send request= %#",theURL);
NSLog(#"%#",dataDictionaryResponse);
Look at this code which i am using to call a web service and thats working for me
+(NSString *)http_post_method_changed:(NSString *)url content:(NSString *)jsonContent{
NSURL *theURL = [NSURL URLWithString:url];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:20.0f];
NSData *requestData = [jsonContent dataUsingEncoding:NSUTF8StringEncoding];
[theRequest setHTTPMethod:#"POST"];
[theRequest setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[theRequest setValue:#"application/json; charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
[theRequest setValue:[NSString stringWithFormat:#"%d", [requestData length]] forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPBody: requestData];
NSURLResponse *theResponse = NULL;
NSError *theError = NULL;
NSData *theResponseData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&theResponse error:&theError];
NSString *data=[[NSString alloc]initWithData:theResponseData encoding:NSUTF8StringEncoding];
NSLog(#"url to send request= %#",url);
NSLog(#"response1111:-%#",data);
return data;
}
Both while using GET and POST We do not need to use setHTTPBody?
setHTTPBody only make sense when you are using POST request. GET don't need it.
For Header parameters do something like below
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:20.0f];
//Specify method of request(Get or Post)
[theRequest setHTTPMethod:#"GET"];
//Pass some default parameter(like content-type etc.)
[theRequest setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[theRequest setValue:#"application/json; charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
//Now pass your own parameter
[theRequest setValue:yourObj forHTTPHeaderField:#"your parameter name"];
setHTTPBody is used when HTTP method POST is being used.
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:theUrl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:120.0];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:data];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
Here the data is nothing but NSData of JSON data that need's to be sent.

setting content-type overwriting httpbody?

I'm having a weird issue calling an API from my ios app. I create a post request
NSMutableURLRequest *request = [NSMutableURLRequest
requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:5.0];
[request setHTTPMethod:#"POST"];
I then create json to send to the request and add it to the body of the request like so:
[request setHTTPBody:encodedData];
Finally, I am adding a few cookies which I then set with:
NSArray* cookieArray = [NSArray arrayWithObjects: sessionCookie, uidCookie, vidCookie, nil];
NSDictionary * headers = [NSHTTPCookie requestHeaderFieldsWithCookies:cookieArray];
[request setAllHTTPHeaderFields:headers];
This all works fine. However, since I am sending json I'm trying to be good and also set the content type with this line of code:
[request setValue:#"application/json; charset=utf-8" forHTTPHeaderField: #"Content-Type"];
As soon as I add this line of code, the data I sent to the body of the request no longer gets passed as part of the request. Does this sound like behavior anyone else has experienced?
I am also using
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
Check this explanation
What does "Content-type: application/json; charset=utf-8" really mean?

iOS: POST where JSON is just one argument of many

I have successfully used JSON as arguments to a POST webservices in my apps by making the data representation of the JSON the HTTP body:
//Prep
NSData *requestData = [NSJSONSerialization dataWithJSONObject:<my JSON> options:0 error:nil];
NSString *apiString = <the webservice>;
//POST
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:apiString]];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setValue:[NSString stringWithFormat:#"%d", [requestData length]] forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:requestData];
//Go
NSURLResponse *response = nil;
queryResultData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
Which works great.
The trouble is, this works for a webservice which is expecting a single JSON argument as the http body.
How can I include JSON as one of many arguments, the way you can use the data encoding of #"arg1=val1&arg2=val2".
For example: image you have a webservice expecting something like
http://mysite.com/api/v1/route/test?data={json:%22true%22}&other=abcdefg
Which must be submitted as a POST.
This, interestingly, has a JSON dictionary as only one argument of many, and not in the body at that. I can't figure out how to add these arguments to the post.
EDIT
Here's the same concept in php. How do you do this in Cocoa?
$data = array('x' => 1, 'name => 'fred');
$json = json_encode($data);
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, array('json_data' => $json));
-- or --
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, 'something=whatever&json_data='.$json);

Resources