This is a migrated thread and some comments may be shown as answers.

PUT Request from iOS using OpenAccess Web API Service

4 Answers 103 Views
Development (API, general questions)
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Galobart
Top achievements
Rank 1
Galobart asked on 08 Jan 2013, 04:17 PM
regards,

I have a web service API generated by OpenAccess wizard. I can receive data without problems, but I need to update the data from the device.

I have this in my controller.partial.cs.:

public virtual HttpResponseMessage Put(TuPrevencion.Auditoria entity)
{
    Auditoria auditoria = (from c in dbContext.Auditorias where c.Id == entity.Id select c).FirstOrDefault();
    auditoria.Comentarios = entity.Comentarios;
    ...
 
    dbContext.SaveChanges();
 
    return Request.CreateResponse(HttpStatusCode.NoContent);
}

And working perfectly from a windows project using HttpResponseMessage:

var entity = new Auditoria() { Id = 31, Comentarios = "Test", ...};
Uri gizmoUri = null;
 
HttpResponseMessage response = client.PutAsJsonAsync("api/auditorias", entity).Result;
 
 
var resultTask = client.PutAsJsonAsync("api/auditorias", entity).Result.Content.ReadAsStringAsync();
Console.WriteLine("{0} ", resultTask.ToString());
Console.ReadLine();
if (response.IsSuccessStatusCode)
{
    gizmoUri = response.Headers.Location;
}
else
{
    Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
    Console.ReadLine();
}

But i don't know how extract the JSon generated. I need to see it to compose the correct code in iOS, and I cant find documentation about it. May be is not relevant to put iOS code here, but I add it just in case.

NSDictionary *data = [NSDictionary dictionaryWithObjectsAndKeys:
                      @"Test", @"Comentarios", @"31", @"Id",  nil];
NSDictionary *data2 = [NSDictionary dictionaryWithObjectsAndKeys: data, @"entity", nil];
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:data2 options:NSJSONWritingPrettyPrinted error:&error];
 
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(@"JSON Output: %@", jsonString);
 
NSString *_urlString = [NSString  stringWithFormat: @"https://url.com:449/api/auditorias"];
NSURL *_url = [NSURL URLWithString:_urlString];
NSMutableURLRequest* _request = [[Authentication sharedInstance ] _request:_url];
 
NSData *requestData = [NSData dataWithBytes:[jsonString UTF8String] length:[jsonString length]];
 
[_request setHTTPMethod:@"PUT"];
[_request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[_request setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"];
[_request setHTTPBody: requestData];
 
NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:_request delegate:self];
if (connection) {
    receivedData = [NSMutableData data];
}

Thanks in advance!

4 Answers, 1 is accepted

Sort by
0
Hristo Marinov
Telerik team
answered on 10 Jan 2013, 09:22 AM
Hello Galobart,

The Put method from the default generated Web API Service from OpenAccess does not retrieve content when it is invoked. The result is only an HttpResponseMessage containing a status code:

return Request.CreateResponse(HttpStatusCode.NoContent);

In that way on the client side when this method is invoked, the container for the received data will be empty.

In case this doesn't answer your question, could you please describe in further details what do you want to achieve? We will try to provide some guidelines regarding how to extend the generated service to meet your needs.

I am looking forward to your feedback.

Greetings,
Hristo Marinov
the Telerik team
Q3'12 SP1 of OpenAccess ORM packs Multi-Table Entities mapping support. Check it out.
0
Galobart
Top achievements
Rank 1
answered on 10 Jan 2013, 10:19 AM
Thanks for your reply,

I change the service code for receive not empty data in any situation:

public virtual HttpResponseMessage Put(TuPrevencion.Auditoria entity)
{
    if (entity == null)
        throw new HttpResponseException(HttpStatusCode.BadRequest);
 
    try
    {
        Auditoria auditoria = (from c in dbContext.Auditorias where c.Id == entity.Id select c).FirstOrDefault();
        auditoria.Comentarios = entity.Comentarios;
         
        .......
 
        dbContext.SaveChanges();
 
        return Request.CreateResponse(HttpStatusCode.Accepted);
    }
    catch(Exception ex)
    {
        return Request.CreateResponse(HttpStatusCode.InternalServerError);
    }
}


And the response still empty with both json sended:

    NSDictionary *data = [NSDictionary dictionaryWithObjectsAndKeys:
                          @"TestPOST", @"Comentarios", @"31", @"Id",
                          auditoria.empresa, @"EmpresaId", auditoria.cerrada, @"Cerrada", auditoria.visita_periodica, @"VisitaPeriodica",
                          nil];
    NSDictionary *data2 = [NSDictionary dictionaryWithObjectsAndKeys: data, @"entity", nil];
 
------- OUTPUT-------
 {
  "entity" : {
    "Cerrada" : 1,
    "EmpresaId" : 29,
    "Comentarios" : "TestPUT",
    "VisitaPeriodica" : 1,
    "Id" : "31"
  }
}

2013-01-10 10:50:05.610 PRL[1015:11603] data=(null)

And:

    NSDictionary *data = [NSDictionary dictionaryWithObjectsAndKeys:
                          @"TestPOST", @"Comentarios", @"31", @"Id",
                          auditoria.empresa, @"EmpresaId", auditoria.cerrada, @"Cerrada", auditoria.visita_periodica, @"VisitaPeriodica",
                          nil];
 
 
-----OUTPUT-----
 
{
  "Cerrada" : 1,
  "EmpresaId" : 29,
  "Comentarios" : "TestPOST",
  "VisitaPeriodica" : 1,
  "Id" : "31"
}
 
2013-01-10 10:56:55.104 PRL[1042:11603] data=(null)

So, may be the problem is in header.  I send the PUT directly to classController URL:

NSString *_urlString = [NSString  stringWithFormat: @"https://serviceURL:449/api/auditorias"];


Dont know if I should send it to root:
NSString *_urlString = [NSString  stringWithFormat: @"https://serviceURL:449/"]; and append the controller URL in header or body, or maybe I'm forgetting some parameter in body.

Here are all parameters I've been using in request:

Authentication with Basic Authentication (works in GET):
 
NSString *basicAuthCredentials = [NSString stringWithFormat:@"%@:%@", user, password];
    NSString *authValue = [NSString stringWithFormat:@"Basic %@", AFBase64EncodedStringFromString(basicAuthCredentials)];
    [_request setValue:authValue forHTTPHeaderField:@"Authorization"];
    NSDictionary *_headers = [NSDictionary dictionaryWithObjectsAndKeys:@"application/json", @"accept", nil];
    [_request setAllHTTPHeaderFields:_headers];
 
Other parameters:
 
    NSData *requestData = [NSData dataWithBytes:[jsonString UTF8String] length:[jsonString length]]; (jsonString is the output posted before)
     
    [_request setHTTPMethod:@"PUT"];
    [_request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [_request setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"];
    [_request setHTTPBody: requestData];

Thank you for your interest.

0
Hristo Marinov
Telerik team
answered on 11 Jan 2013, 04:41 PM
Hello Galobart,

You are on the right direction - when the HttpStatusCode is set to NoContent in the response - no data is sent from the service. But to send data via the HttpResponseMessage, an overload of the Request.CreateResponse method should be use, in which for the second parameter is passed an object.
For example see Line 12:
01.public virtual HttpResponseMessage Put(WebService.Region entity)
02.{
03.    if (entity == null)
04.    {
05.        HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.BadRequest, "BadRequest");
06.        throw new HttpResponseException(response);
07.    }
08.     
09.    try
10.    {
11.        repository.Update(entity);
12.        return Request.CreateResponse(HttpStatusCode.Accepted, entity);
13.    }
14.    catch
15.    {
16.        string response = "InternalServerError";
17.        return Request.CreateResponse(HttpStatusCode.InternalServerError, response);
18.    }
19.}


Here is a code snippet from a client application which invokes the service:
HttpClient client = new HttpClient();
             
Region region = new Region()
{
       RegionDescription = "TestDescription",
       RegionID = 2
};
 
HttpResponseMessage response = client.PutAsJsonAsync("http://localhost:49298/api/regions/", region).Result;
string responseBody = await response.Content.ReadAsStringAsync();

In this way you will receive data from the service along with the HttpStatusCode.

Let us know whether the proposed solution helps.

Kind regards,
Hristo Marinov
the Telerik team
Q3'12 SP1 of OpenAccess ORM packs Multi-Table Entities mapping support. Check it out.
0
Galobart
Top achievements
Rank 1
answered on 15 Jan 2013, 11:16 PM
It was an ios code problem, and finally I have solved using a third party library.

Thanks Hristo for your support.
Tags
Development (API, general questions)
Asked by
Galobart
Top achievements
Rank 1
Answers by
Hristo Marinov
Telerik team
Galobart
Top achievements
Rank 1
Share this question
or