Convert an api result set to a c# Object - asp.net

I am calling an API to get a set of assignment data as JSON. I would like to convert that into C# model objects and display the results in my MVC view. Here is my code so far that successfully brings back the results, now I need it converted to an assignment Model (i.e I need API response.content turned into assignment).
[HttpGet]
public async Task<ViewResult> Index()
{
if (!ModelState.IsValid)
{
return View("Error");
}
HttpRequestMessage apiRequest = CreateRequestToService(HttpMethod.Get, "api/Assignment/GetAll");
HttpResponseMessage apiResponse;
Assignment assignment = new Assignment();
try
{
apiResponse = await HttpClient.SendAsync(apiRequest);
}
catch
{
return View("Error");
}
if (!apiResponse.IsSuccessStatusCode)
{
return View("Error");
}
var result = apiResponse.Content.ReadAsStringAsync();
var results = ???
return View( results);
}

I need API response.content turned into assignment
Convert the content of the response to the desired type. Lets assume it is a collection of the models
//...
var assignments = await apiResponse.Content.ReadAsAsync<List<Assignment>>();
//...

Related

ASP.NET Entity Framework return JSON object of all rows inside table

I am trying to return JSON object from PostgreSQL db and currently saving to database works fine, but trying to return result returns nothing this is currently what I have for returning list from db. Keep in mind connection string is fine functionality for creating object to db works fine.
public async Task<IEnumerable<TutorialMake>> ReadTutorialMake()
{
try
{
using (var db = new TutorialContext())
{
response = HttpStatusCode.OK;
return db.TutorialMakes.ToList();
}
} catch
{
response = HttpStatusCode.BadRequest;
return null;
}
}
I've tried with returning only db.TutorialMakes without enumerable still nothings, removing try and catch returns no errors, iqueryable returns nothing and there is data inside table
Code is fine, it was just the way I configured my API I didn't return the list in API.
Because you forget to convert List result to JsonObject
Example :
public async Task<JsonResult> ReadTutorialMake()
{
try
{
using (var db = new TutorialContext())
{
response = HttpStatusCode.OK;
return Json(db.TutorialMakes.ToList()); //Convert result to JsonResult
}
} catch
{
response = HttpStatusCode.BadRequest;
return null;
}
}

How to use Await with LINQ and DTO

I'm just getting to grips with creating a new WebAPI2 project in ASP.NET. I'm trying to get the controller to return data from a DTO I have created rather than the raw object classes that EF created. I've been following a tutorial on Microsoft Docs and have got my method which returns all records to work using the DTO, but I can't figure out how to correctly modify the method which only returns the record with the ID matching the passed parameter using an asynchronous task, like the default method does.
The default method generated by Visual Studio looks like this:
[ResponseType(typeof(Post))]
public async Task<IHttpActionResult> GetPost(int id)
{
Post post = await db.Post.FindAsync(id);
if (post == null)
{
return NotFound();
}
return Ok(post);
}
and I've got my modified method looking like this:
[ResponseType(typeof(PostDTO))]
public async Task<IHttpActionResult> GetPost(int id)
{
var _post = from p in db.Post
where p.PostID == id
select new PostDTO()
{
PostID = p.PostID,
SubmitTime = p.SubmitTime,
SubmitUsername = p.SubmitUsername,
};
if (_post == null)
{
return NotFound();
}
return Ok(_post);
}
This methods works just fine, but as you can see, it doesn't make use of .NET's Await/Async feature to perform the query asynchronously. I'll be honest and admit that I don't actually know if this matters, but I feel like if the default method was asynchronous, so should mine be. I just can't work out where to insert the Async and Await keywords to make this work.
You can use this method as,
[ResponseType(typeof(PostDTO))]
public async Task<IHttpActionResult> GetPost(int id)
{
var _post = await (from p in db.Post
where p.PostID == id
select new PostDTO()
{
PostID = p.PostID,
SubmitTime = p.SubmitTime,
SubmitUsername = p.SubmitUsername,
}).ToListAsync();
if (_post == null)
{
return NotFound();
}
return Ok(_post);
}

WebApi and Swagger

I am using asp.net webapi and using swagger to create a RestApi within a WPF app via AutoRest.
I am having problem figuring out how to consume the returned data if there is an error.
My controller is as follows;
// POST: api/Personnel
//[SwaggerResponse(HttpStatusCode.InternalServerError ,Type = typeof(HttpError))]
[SwaggerOperation("AddEditContract")]
[SwaggerResponse(HttpStatusCode.OK, Description = "Add/Edit a Contract", Type =typeof(int))]
public IHttpActionResult Post(ContractDto value)
{
try
{
var _contractsService = new Business.ContractsService();
var contractToSave = _contractsService.GetContractsById(value.CC_Id);
if (contractToSave == null)
{
return NotFound();
}
var ret = _contractsService.SaveContract(value);
if (ret > 0)
{
return Ok(ret);
}
else
{
return BadRequest();
}
}
catch (Exception ex)
{
return InternalServerError(ex);
}
}
I happened to have an error appear within the WebApi based on an error with AutoMapper but it was getting swallowed up. It is returning an error message in the response, which is great.
Here is the current AutoRest code for this call.
public static int? AddEditContract(this IBuxtedConAPI operations, ContractDto value)
{
return Task.Factory.StartNew(s => ((IBuxtedConAPI)s).AddEditContractAsync(value), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult();
}
As you can see its expecting an int. If I uncomment the
//[SwaggerResponse(HttpStatusCode.InternalServerError ,Type = typeof(HttpError))]
The int return type turns to object.
So the real question.
Here is my service call from WPF to the WebApi
public async Task<int> SaveContract(ContractDto entity)
{
using (var db = new BuxtedConAPI())
{
var ret = await db.AddEditContractAsync(entity);
return (int)ret;
}
}
If an object is returned how do I pick up if an error has occurred or if the simple int (with a success) is just returned.
Thanks in advance.
Scott
Can you post the swagger file that you're generating and passing to AutoRest?
The reason return type turns to object (or whatever common base class is shared between all the possible responses), is because AutoRest treats explicitly defined responses as return values. Exceptions are used only for the default response.
We're investigating ways to specify multiple error responses that will generate the appropriate exceptions.

How to deserialize

How to deserialize Task response using Json .
public HttpResponseMessage Put(int id, ModelClass modelbject)
{
if (ModelState.IsValid && id == modelbject.modelbjectID)
{
db.Entry(modelbject).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
return Request.CreateResponse(HttpStatusCode.NotFound);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
I want to derialize this and check the IsSuccessStatusCode in my class where i am calling this put method. How can i achieve ?
I want to derialize this and check the IsSuccessStatusCode in my class where i am calling this put method.
You don't have to "deserialize" anything. The method returns an HttpResponseMessage, which has the property you're looking for.
var result = yourController.Put(someId, someObject);
var success = result.IsSuccessStatusCode;
Perhaps the fact that this is a web application is adding some confusion to how you're picturing it. But if you have a class which directly calls this method, then what you get back is simply an HttpResponseMessage object. Which can be inspected just like any other object. No actual web layer is involved in that interaction.

Return specific HTTP status code in action for GET request

I'm creating REST service using ASP.NET Web API.
How can I return 401 status code from action for GET method...
I don't have problem with returning some status code from e.g. POST method, cause I can set the return type to HttpResponseMessage
public HttpResponseMessage Post(Car car)
{
using (var context = new CarEntities())
{
...
var response = new HttpResponseMessage(HttpStatusCode.Created);
response.Headers.Location = new Uri(Request.RequestUri, path);
return response;
}
}
However, how can I return the status code for GET method, when the method returns different type than HttpResponseMessage:
public Car Get(int id)
{
var context = new CarEntities();
return context.Cars.Where(p => p.id == id).FirstOrDefault();
}
I would like to return e.g. 401 when authorization in this Get method failed
Thanks
You should throw a HttpResponseException, which allows you to specify the response code, for example:
if (authFailed) {
throw new HttpResponseException(HttpStatusCode.Unauthorized);
}

Resources