Set an NSDictionary in HTTPBody and send using POST method
Asked Answered
S

5

6

I want to call a web service with the POST method. I need to post a dictionary with a URL. My web service parameters are given below:

ConversationMessage {
       authorUserId (string, optional),
       subject (string, optional),
       hasAttachment (boolean, optional),
       conversationId (string, optional),
       attachment (DigitalAsset, optional),
       content (string, optional),
       title (string, optional),
       urgency (boolean, optional),
       searchable (Map[String,Object], optional)
}

DigitalAsset {
        id (string, optional),
        assetUrl (string, optional),
        assetContent (string, optional),
        thumbGenerated (boolean, optional),
        fileName (string, optional)
}  

Map[String,Object] {
        empty (boolean, optional)
}

Following is my request:

    NSMutableArray *arr=[[NSMutableArray alloc]init];
    NSMutableDictionary *dict=[[NSMutableDictionary alloc]init];
    [dict setValue:@"test title" forKey:@"title"];
    [dict setValue:@"test message" forKey:@"content"];
    [dict setValue:@"0" forKey:@"urgency"];

    [arr addObject:[NSMutableDictionary dictionaryWithObject:dict forKey:@"ConversationMessage"]];

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ;
    [request setURL:[NSURL URLWithString:strUrl]];
    [request setTimeoutInterval:10.0];
    [request setHTTPMethod:strMethod];

    NSString *boundary = @"---------------------------14737809831466499882746641449";
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
    [request addValue:contentType forHTTPHeaderField: @"Content-Type"];

    NSMutableData *body=[[NSMutableData alloc]init];
    for (NSMutableDictionary *dict in array) {

      NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:NULL];
      [body appendData:jsonData];
}

[request setHTTPBody:body];

But I am getting the following error:

The server refused this request because the request entity is in a format not supported by the requested resource for the requested method

Scolecite answered 26/2, 2014 at 6:52 Comment(0)
S
7

Please find the below code which POST the data to a webservice. Please note this is a sample which i used in one of my application.

//json format to send the data
jsondata = [NSJSONSerialization dataWithJSONObject:"NSDictionary variable name"
                                               options:NSJSONWritingPrettyPrinted
                                                 error:&error];
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 setValue:[NSString stringWithFormat:@"%d", [jsondata length]] forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody:jsondata];

Hope this helps.

From your comments "server refused this request" does the server support JSON or XML format.

Sepia answered 26/2, 2014 at 7:14 Comment(2)
i had tried your code but ite also not working and JSON formate is supporatedScolecite
In your request you are trying to use multi part which i haven't used the code shared. May be this (nthn.me/posts/2012/objc-multipart-forms.html) will help you to overcome the error.Sepia
P
2

Try following code:

NSString *params = [self makeParamtersString:dictData withEncoding:NSUTF8StringEncoding];
NSData *body = [params dataUsingEncoding:NSUTF8StringEncoding]; 
[request setHTTPBody:body];
[request setHTTPMethod:@"POST"];

- (NSString*)makeParamtersString:(NSDictionary*)parameters withEncoding:(NSStringEncoding)encoding
{
    if (nil == parameters || [parameters count] == 0)
        return nil;

    NSMutableString* stringOfParamters = [[NSMutableString alloc] init];
    NSEnumerator *keyEnumerator = [parameters keyEnumerator];
    id key = nil;
    while ((key = [keyEnumerator nextObject]))
    {
        NSString *value = [[parameters valueForKey:key] isKindOfClass:[NSString class]] ?
        [parameters valueForKey:key] : [[parameters valueForKey:key] stringValue];
        [stringOfParamters appendFormat:@"%@=%@&",
         [self URLEscaped:key withEncoding:encoding],
         [self URLEscaped:value withEncoding:encoding]];
    }

    // Delete last character of '&'
    NSRange lastCharRange = {[stringOfParamters length] - 1, 1};
    [stringOfParamters deleteCharactersInRange:lastCharRange];
    return stringOfParamters;
}

- (NSString *)URLEscaped:(NSString *)strIn withEncoding:(NSStringEncoding)encoding
{
    CFStringRef escaped = CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)strIn, NULL, (CFStringRef)@"!*'();:@&=+$,/?%#[]", CFStringConvertNSStringEncodingToEncoding(encoding));
    NSString *strOut = [NSString stringWithString:(__bridge NSString *)escaped];
    CFRelease(escaped);
    return strOut;
}
Placencia answered 26/2, 2014 at 8:23 Comment(0)
S
1

Can you try forming the following format

NSString *parameter = [NSString stringWithFormat:@"title=testtitle&content=testmessage&urgency=0"];

NSData *parameterData = [parameter dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];

And then set it as body

[theRequest setHTTPBody:parameterData];
Sushi answered 10/8, 2015 at 22:27 Comment(0)
B
0

NSMutableURLRequest has a method setHTTPBody: which would take your NSData* jsonData as a parameter. On the surface that appears to be your problem. You never call it in the code above.

Buonomo answered 26/2, 2014 at 7:9 Comment(2)
as listed above the [request setHTTPBody:body]; is beyond the scope of body. If you NSLog body, you'll probably see it is nil.Buonomo
no its not nil i am getting data length 255 and also body dataScolecite
N
0

I hope you are using stream to pass the multipart file.

To pass parameters you should use something like this before passing the multipart data:

NSString *contentDisposition = @"Content-Disposition: form-data; name=\"<name of the parameter with double quotes>\"";

NSString *contentType = @"Content-Type: application/json; charset=UTF-8";

Loop through all the parameters & append contentDisposition & contentType separated by boundary string.

This is how the format looks like:

-----------------------------14737809831466499882746641449
Content-Disposition: form-data; name="title" 
Content-Type: application/json; charset=UTF-8
test title

-----------------------------14737809831466499882746641449
Content-Disposition: form-data; name="content"
Content-Type: application/json; charset=UTF-8
test message

-----------------------------14737809831466499882746641449

Content-Disposition: form-data; name=multipartFile; filename="<fileName>"
Content-Type: text/plain

Convert this string to NSData and append the multipart data of your file and setHttpBody.

Hope it helps.

Nitrosamine answered 26/2, 2014 at 9:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.