问题
I have been trying to figure out what is going wrong for a few hours now and i just can't find what is going wrong.
Via the Mvc application the put method doesn't get hit, the request doesn't happen. But when i test it in fiddler the PutMethod in the api works.
Hopefully someone can clear things up for me.
Also pointers for a better structure or some good documentation are welcome .
public void UpdateWerknemerCompetentieDetail(int wnID, int WNC, CompetentieWerknemerDetail detail)
{
using (HttpClient client = new HttpClient())
{
string token = (string)HttpContext.Current.Session["token"];
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var wn = GetWerknemerById(wnID);
//var wnc = wn.CompetentiesWerknemer.Select(c => c).Where(c => c.ID == WNC).FirstOrDefault();
detail.CompetentieWerknemerID = WNC;
//wnc.CompetentieWerknemerDetail = detail;
var url = String.Format(URL + "PutDetails?id=" + WNC);
var json = JsonConvert.SerializeObject(detail, new JsonSerializerSettings()
{
ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
});
var response = client.PutAsync(url, new StringContent(json, Encoding.UTF8, "application/json"));
}
}
The above code is my service that should make the request to the api.
Here is the web api IHttpActionResult method (the put method).
[Route("PutDetails")]
[HttpPut]
public IHttpActionResult PutWerknemerCompetentieDetails(int id, [FromBody]CompetentieWerknemerDetail cwn)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != cwn.CompetentieWerknemerID)
{
return BadRequest();
}
//_db.Entry(cwn).State = EntityState.Modified;
try
{
_db.CompetentieWerknemerDetail.Add(cwn);
_db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!WerknemerExist(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
回答1:
HttpClient.PutAsync is an asynchronous API, it returns a Task<HttpResponseMessage>
which represents an operation which will complete in the future, which you need to await
. You're wrapping your HttpClient
inside a using
statement, which means that right after you trigger the asynchronous PUT, you're disposing the client which causes a race condition with the request and the disposal of your object, and is probably the reason you're not seeing the request fire.
You have two choices. Either make the method async Task
and await
inside it:
public async Task UpdateWerknemerCompetentieDetailAsync(
int wnID, int WNC, CompetentieWerknemerDetail detail)
{
using (HttpClient client = new HttpClient())
{
string token = (string)HttpContext.Current.Session["token"];
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
var wn = GetWerknemerById(wnID);
//var wnc = wn.CompetentiesWerknemer.Select(c => c)
// .Where(c => c.ID == WNC)
// .FirstOrDefault();
detail.CompetentieWerknemerID = WNC;
//wnc.CompetentieWerknemerDetail = detail;
var url = String.Format(URL + "PutDetails?id=" + WNC);
var json = JsonConvert.SerializeObject(detail, new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
});
var response = await client.PutAsync(
url, new StringContent(json, Encoding.UTF8, "application/json"));
}
}
Or use a synchronous API, such as exposed by WebClient.
来源:https://stackoverflow.com/questions/36173165/putasync-doesnt-send-request-to-web-api-but-fiddler-works-fine