我用这个方法从MVC控制器向web api控制器方法发布一些数据。。
private static async Task<HttpResponseMessage> SendDataToApi (List<TogglRow> input)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:****/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await client.PostAsJsonAsync("api/service", input);
//if (response.StatusCode == HttpStatusCode.OK)
//{
// var resultUri = response.Headers.Location;
//}
return response;
}
}
这是我发布到的Web Api方法。
public HttpResponseMessage Post(HttpRequestMessage request, List<Dagsrapport> value)
{
if (value != null)
{
var rapporter = value.ToList();
//send rapporter to DB
var response = new HttpResponseMessage(HttpStatusCode.OK);
return response;
}
return request.CreateResponse(HttpStatusCode.BadRequest);
}
现在,这篇文章运行良好,我将返回HttpStatusCode.OK。但我不会被重定向回我执行这篇文章的方法(SendDataToApi())。我正在返回触发该帖子的页面。我可以看到页面正在工作(等待localhost..),但什么也没发生。
我可能应该提到,这是两个独立的项目(MVC和WebApi),但在同一个解决方案中。
我错过了什么?
编辑-已解决
我遇到的问题是由于运行任务"SendDataToApi"的方法没有设置为异步。因此,它没有等待post的结果,而是同步运行,控件从未返回到运行SendDataToApi的方法,而是返回到原始调用方UI。
以下是运行SendDataToApi任务的方法。。
[HttpPost]
public async Task<ActionResult> Edit(IEnumerable<TogglRow> tr)
{
var listToExport = tr.Where(x => x.Export.Equals(true));
var result = listToExport.ToList();
var response = await SendDataToApi(result);
return RedirectToAction("Index", "Home",
response.StatusCode == HttpStatusCode.OK ? new { message = "Record(s) were successfully stored." } : new { message = "No records selected." });
}
您似乎对这一切的工作方式有一些根本性的误解。MVC操作和WebAPI操作的工作方式非常不同,这就是为什么它们实际上位于完全不同的命名空间中,尽管它们都实现了类似的组件。
如果您需要从MVC操作连接到Web API,则不应该以HttpResponseMessage
的形式接收响应。这是WebAPI操作的一个返回值,类似于ViewResult
是MVC操作的返回值。它对MVC中的任何东西都没有意义。相反,例如,来自HttpClient
的实际响应将是一个字符串(从技术上讲是一个字节数组),其内容类型指示它应该被解释为纯文本、JSON、XML等。
根据内容类型,您将相应地处理此响应。例如,如果是JSON,那么可以使用Newtonsoft.Json
中的JObject
(MVC中的默认JSON解释器)。然后,您可以使用这个数据对象来构造MVC操作的响应。如果您有指示应该进行重定向的内容,那么MVC操作可以返回Redirect*
系列的结果。重要的是,您不能只对Web API操作的响应进行重定向,因为这只会影响HttpClient
响应对象。