How to deserialize - asp.net

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.

Related

Entity Framework API Put method, only update one column

I am using Entity Framework API and I am trying to update just one column using the Put method...
[ResponseType(typeof(void))]
[Authorize]
public IHttpActionResult PutLCTimeSlots(int id, LCTimeSlots lCTimeSlots)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != lCTimeSlots.id)
{
return BadRequest();
}
db.Entry(lCTimeSlots).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!LCTimeSlotsExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
My question, what do I need to change in this method to only update one column?
I have tried replacing db.Entry(lCTimeSlots).State = EntityState.Modified; with db.Entry(lCTimeSlots).Property(x => x.taken).IsModified = true; But that didn't work....anyone have any ideas?
You shouldn't use the default PUT for such an operation as it implies a client should be able to update more than a single property. I'd suggest a PUT operation using a route that describes the property being updated w/ parameter of the property's type instead of an LCTimeSlots object:
[HttpPut( "{id}/yourProperty" )]
[Authorize]
public IHttpActionResult YourProperty( int id, TypeOfProperty yourProperty )
{
// validate value of `yourProperty` if you can before loading entity from DB
// load entity from DB
var loadedEntity = dbContext.Set<LCTimeSlots>().Find( id );
// if not found, 404 it
// update property, e.g.:
loadedEntity.YourProperty = yourProperty;
// validate entity in its entirety if necessary
// save changes
}
I'll start by suggesting use of the PATCH verb if you only want to modify certain properties.
Also, it's not a great idea to accept an entity object from the client, instead accept a model object that only has the properties that you aim to modify with this method.
Lastly, verify that the entity exists before attempting to make any change.
Now, do something like this:
var timeSlot = db.LCTimeSlots.SingleOrDefault(e => e.Id == model.Id);
if (timeSlot != null)
{
db.Entry(timeSlot).CurrentValues.SetValues(model);
db.SaveChanges();
}
else
{
//404
}

Convert an api result set to a c# Object

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>>();
//...

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 use IUserIdProvider

My code:
public string GetUserId(IRequest request) {
var token = request.QueryString.Get("token");
// what is it? request.User.Identity.Name;
if (string.IsNullOrWhiteSpace(token)) {
return token;
}
else {
return JsonConvert.SerializeObject(new UserAbility().GetUserByToken(token));
}
}
I need to map the connection with the user using a different identifier.
So i want to get the custom token from the QueryString in this method, but GetUserId doesn't trigger in every reqeust.
And i always get the request.User.Identity.Name is string empty?
This article explains what you need to do.
http://www.asp.net/signalr/overview/guide-to-the-api/mapping-users-to-connections#IUserIdProvider

Call a WCF Data service boolean method

I'm trying to receive an answer from a WCF method from the client. When I try to execute void methods, they are working fine. For example:
Uri u = new Uri(string.Format(LogIn.ctx.BaseUri + "/CreateRole?name='{0}'",
TextBox1.Text), UriKind.RelativeOrAbsolute);
LogIn.ctx.Execute(u, "GET");
Now I want to call a method which returns a boolean, and this value will be used. Here's the method I want to call and receive its returned value:
[WebGet]
public bool Controler(string role, string user)
{
if (Roles.IsUserInRole(user, role))
{
return true;
}
else
{
return false;
}
}
Instead of LogIn.ctx.Execute(u, "GET"), try this:
IEnumerable<bool> result = LogIn.ctx.Execute<bool>(u);
bool answer = result.Single();

Resources