use*_*094 5 asp.net-mvc asp.net-web-api
我已经实现了创建WebApi本身,我可以从浏览器中浏览它并获得输出.
对我不起作用的是我试图从MVC Controller中使用WebAPI,并且我已经编写了用于在我的"cshtml"视图中调用WebAPI的代码.
但它不起作用,因为我在加载页面时遇到错误,我知道我做错了.所以第一个问题是:我是正确地做了这个,还是在MVC项目中创建一个WebAPI部分然后尝试在控制器的同一个MVC项目中使用它是完全错误的?
为了回答你的问题,它实际上是“按照设计的”,并且建议将你的 WebAPI 和 MVC 客户端放在同一个项目中。这就是为什么您的 MVC 项目中 同时存在 aRouteConfig.cs和 a 的原因。适用于您的 MVC 控制器,并且显然适用于您的 Api 控制器。WebApiConfig.csRouteConfig.csWebApiConfig.cs
将两者放在同一个项目中很容易。我所做的就是在我的根目录中添加一个名为“API”的文件夹,并将所有 WebAPI 控制器放在其中。请记住,我相信您知道,WebAPI 控制器和 MVC 控制器之间的唯一区别是 WebAPI 控制器继承了ApiController(System.Web.Http我相信)的一部分,而 MVC 控制器继承Controller了System.Web.MVC.
以下是从MVC 前端向WebAPI发出 GET/PUT/DELETE/POST 请求的正确方法。是否在同一个项目中并不重要,因为您在控制器的构造函数中指定了 WebAPI URL。如果您的 WebAPI 与前端 MVC 应用程序位于不同的服务器上,则需要启用 CORS 支持,这是 WebAPI 版本 2 及更高版本中提供的功能。
这是从前端(MVC 客户端)调用 WebAPI 的正确方法。
在控制器页面中,删除与 DbContext、Entity Framework 等相关的任何内容。原因是默认情况下,控制器希望通过调用 DbContext 来执行 CRUD 操作,而我们不希望这样做。我们想调用 WebAPI 来执行此操作。当我提到“控制器”时,我指的是 MVC 控制器,而不是 WebAPI 控制器。
首先,也是最重要的,在 MVC 控制器中声明一些成员变量。MVC 控制器的其余部分将利用这些:
HttpClient client = new HttpClient();
HttpResponseMessage response = new HttpResponseMessage();
Uri contactUri = null;
Run Code Online (Sandbox Code Playgroud)
在 MVC 控制器中,为控制器创建一个构造函数,如下所示:
public ContactController()
{
// set base address of WebAPI depending on your current environment
// the URL below, if the API is in the same project, will be something
// like "http://server/YourProjectName" - replace server with either
// "localhost", etc.
client.BaseAddress = new Uri("http://server/YourAPI/");
// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
}
Run Code Online (Sandbox Code Playgroud)将 Index 操作的代码替换为如下所示的代码。请注意,唯一相关的部分是client.GetAsync()调用和var contacts分配。对于这个问题的上下文来说,其他一切都不是必要的。内部的值client.GetAsync()应该是控制器的名称,前面加上您在 WebApiConfig.cs 中设置的任何自定义路由 - 就我而言,我api在路由中添加了该部分以区分 API 调用和普通调用:
public ActionResult Index()
{
response = client.GetAsync("api/contact").Result;
if (response.IsSuccessStatusCode)
{
var contacts = response.Content.ReadAsAsync<IEnumerable<Contact>>().Result;
return View(contacts);
}
else
{
// add something here to tell the user hey, something went wrong
return RedirectToAction("Index");
}
}
Run Code Online (Sandbox Code Playgroud)将 Create 操作(HttpPost 操作)替换为如下内容。同样,唯一重要的部分是该client.PostAsJsonAsync()部分 - 这就是调用 WebAPI 的 POST 操作的部分,在我的例子中,该操作负责将新记录插入数据库:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Contact contact)
{
// Create a new product
response = client.PostAsJsonAsync("api/contact", contact).Result;
if (response.IsSuccessStatusCode)
{
return RedirectToAction("Index");
}
else
{
// add something here to tell the user hey, something went wrong
return RedirectToAction("Index");
}
}
Run Code Online (Sandbox Code Playgroud)将“编辑”操作(非 HttpPost 操作)替换为如下内容。这有点棘手,因为为了进行编辑,您必须首先检索记录,因此基本上,Edit 的 HttpPost 版本将包含一些类似的代码,以及执行编辑 POST (PUT) 的附加代码行。下面,我们通过向 WebAPI 传递特定的记录 ID 来获取响应。因此,就像索引 (GET) 一样,我们做同样的事情,只是传入 ID,因此我们只返回一条记录。然后,我们将响应投射到可以在视图中操作的实际对象:
public ActionResult Edit(int id = 0)
{
response = client.GetAsync(string.Format("api/contact/{0}", id)).Result;
Contact contact = response.Content.ReadAsAsync<Contact>().Result;
if (contact == null)
{
return HttpNotFound();
}
return View(contact);
}
Run Code Online (Sandbox Code Playgroud)将编辑操作(HttpPost 操作)替换为如下内容。client.GetAsync()下面,我们通过调用并传入主键作为参数 (contact_id)来获取要编辑的记录。然后,我们从该响应中获取 RequestUri 并保存它。然后,我们调用client.PutAsJsonAsync()并传入 Uri.PathAndQuery (我们刚刚保存的内容)以及要编辑的对象。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Contact contact)
{
response = client.GetAsync(string.Format("api/contact/{0}", contact.contact_id)).Result;
contactUri = response.RequestMessage.RequestUri;
response = client.PutAsJsonAsync(contactUri.PathAndQuery, contact).Result;
if (response.IsSuccessStatusCode)
{
return RedirectToAction("Index");
}
else
{
// add something here to tell the user hey, something went wrong
return RedirectToAction("Index");
}
}
Run Code Online (Sandbox Code Playgroud)将删除操作(非 HttpPost 操作)替换为类似以下内容。同样,我们通过简单地调用client.GetAsync()并将其转换为我的应用程序知道的实际对象来从数据库中获取记录。
public ActionResult Delete(int id = 0)
{
response = client.GetAsync(string.Format("api/contact/{0}", id)).Result;
Contact contact = response.Content.ReadAsAsync<Contact>().Result;
if (contact == null)
{
return HttpNotFound();
}
return View(contact);
}
Run Code Online (Sandbox Code Playgroud)最后,将删除操作(HttpPost 操作)替换为如下内容。同样,我们正在执行与“编辑”操作类似的操作。我们获取要删除的记录,将其转换为一个对象,然后将该对象传递给调用client.DeleteAsync(),如下所示。
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
response = client.GetAsync(string.Format("api/contact/{0}", id)).Result;
contactUri = response.RequestMessage.RequestUri;
response = client.DeleteAsync(contactUri).Result;
return RedirectToAction("Index");
}
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
1450 次 |
| 最近记录: |