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

时间:2013-09-16 13:07:47

标签: http c#-4.0 asp.net-mvc-4 asp.net-web-api crud

我有一个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 个答案:

答案 0 :(得分:3)

虽然凯文是对的,但我采用的是非Ajax方式。请记住,我正在使用JSON数据,因此这是以JSON为中心。

在您的控制器页面中,删除任何与DbContext,Entity Framework等有关的内容。原因是默认情况下,控制器希望通过调用DbContext来执行CRUD操作,我们不希望这样。我们想要调用WebAPI来执行此操作。

首先,在控制器中声明一些成员变量。控制器的其余部分将使用这些:

    HttpClient client = new HttpClient();
    HttpResponseMessage response = new HttpResponseMessage();
    Uri contactUri = null;
  1. 在控制器中,为控制器创建一个构造函数,如下所示:

    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. 使用以下内容替换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");
        }
    }
    
  3. 使用以下内容替换“创建”操作(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");
        }
    }
    
  4. 使用以下内容替换“编辑”操作(非HttpPost操作)。这有点棘手,因为为了编辑,你必须首先检索记录,所以基本上,编辑的HttpPost版本将包含一些类似的代码,另外一行代码执行编辑POST(PUT)。下面,我们通过传递特定的记录ID来获取WebAPI的响应。所以,就像Index(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);
    }
    
  5. 使用以下内容替换编辑操作(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");
        }
    }
    
  6. 使用以下内容替换Delete操作(非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);
    }
    
  7. 最后,使用以下内容替换Delete操作(HttpPost操作)。同样,我们正在做类似于Edit操作的操作。我们将要删除的记录,将其转换为对象,然后将该对象传递到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");
    }
    

答案 1 :(得分:2)

您可以使用jQuery ajax method从客户端调用Web API。但是,由于您从部署Web API之外的站点进行调用,因此您必须使用JSONP而不是JSON。看一下这个QA to see how you use JSONP with Web API。您的模型将作为JSON传递,您必须在客户端呈现,而不是使用Razor在服务器端呈现它。我会使用Knockout之类的东西在客户端上创建一个View Model,它将你的模型绑定到客户端上的HTML元素。