ASP.NET MVC4前端作为一个项目,ASP.NET Web API作为同一解决方案中的另一个项目 - 如何从前端调用WebAPI?

3

我在我的解决方案中有一个ASP.NET MVC4前端作为一个项目,以及另一个ASP.NET Web API作为同一个解决方案中的另一个项目。Web API将包含所有的CRUD操作。

2个问题

  1. 如何从我的前端调用Web API执行CRUD操作? 我已经在我的Web API项目中定义了实体数据模型,并且需要将我的前端视图绑定到它,我该如何做?
  2. 一旦部署到我的Web服务器上,前端将驻留在一个服务器上,而Web API将驻留在另一个服务器上(保存大部分我们的Web服务的服务器)。 所以,我猜想,一旦部署,我该如何从我的前端调用Web API? 我知道Web API只需使用HTTP请求即可,但是在将我的模型(在我的Web API项目中定义)传递到我的视图(在我的前端项目中)方面,我该如何做到这一点?
2个回答

3
虽然Kevin是对的,但我是以非Ajax方式进行的。请记住,我正在使用JSON数据,因此这个过程是围绕JSON展开的。
在你的控制器页面中,删除任何与DbContext、Entity Framework等有关的内容。原因是默认情况下,控制器将希望通过调用DbContext执行CRUD操作,而我们不希望这样做。我们要调用WebAPI来完成这个过程。
首先,声明一些成员变量在你的控制器中。你的控制器的其余部分将利用这些变量。
    HttpClient client = new HttpClient();
    HttpResponseMessage response = new HttpResponseMessage();
    Uri contactUri = null;
  1. In your controller, create a constructor for your controller, as such:

    public ContactController()
    {
        // set base address of WebAPI depending on your current environment
        client.BaseAddress = new Uri("http://server/YourAPI/");
    
        // Add an Accept header for JSON format.
        client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));
    }
    
  2. Replace the Index action's code with something like the following. Note that the only relevant pieces are the client.GetAsync() call and the var contacts assignment. Everything else is not necessary for the context of this problem. The value inside the client.GetAsync() should be the name of your controller, prepended by any custom routing you set up in your WebApiConfig.cs - in my case, I added the api part in my route to distinguish between API calls and normal calls:

    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");
        }
    }
    
  3. Replace the Create action (the HttpPost action) with something like the following. Again, the only important piece is the client.PostAsJsonAsync() part - this is what calls the WebAPI's POST action which takes care of, in my case, inserting a new record into the database:

    [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");
        }
    }
    
  4. Replace the Edit action (the non-HttpPost action) with something like the following. This was a little tricky because in order to edit, you had to retrieve the record first, so basically, the HttpPost version of Edit will contain somewhat similar code, with an additional line of code that performs the edit POST (PUT). Below, we're getting the response from the WebAPI by passing it a specific record ID. So, just like for Index (GET), we are doing the same thing only passing in the ID so we only get back one record. Then, we cast the response to an actual object that can be operated on in the View:

    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);
    }
    
  5. Replace the Edit action (the HttpPost action) with something like the following. Below, we're getting the record to be edited by calling client.GetAsync() and passing in the primary key as a parameter (contact_id). Then, we're getting the RequestUri from that response and saving it. Then, we're calling client.PutAsJsonAsync() and passing in the Uri.PathAndQuery (what we just saved) as well as the object to be edited.

    [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");
        }
    }
    
  6. Replace the Delete action (the non-HttpPost action) with something like the following. So again, we're getting the record from the database by simply calling client.GetAsync() and casting it to an actual object my app knows of.

    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);
    }
    
  7. Finally, replace the Delete action (the HttpPost action) with something like the following. Again, we're doing something similar to that of the Edit action. We are getting the record to be deleted, casting it to an object, and then passing that object into a client.DeleteAsync() call, as shown below.

    [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");
    }
    

2
您可以使用jQuery ajax方法从客户端调用Web API。但由于您是从部署Web API的站点以外的站点进行调用,因此您将不得不使用JSONP而不是JSON。请查看这个QA,了解如何在Web API中使用JSONP。您的模型将被传递为JSON,您需要在客户端上呈现它,而不是使用Razor在服务器端呈现它。我建议使用类似Knockout的工具,在客户端上创建一个视图模型,将您的模型绑定到HTML元素上。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接