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 项目中定义)传递到我的视图(在我的前端项目中)而言,我该怎么做呢?
4

2 回答 2

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. 将 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");
        }
    }
    
  4. 将 Edit 操作(非 HttpPost 操作)替换为以下内容。这有点棘手,因为为了进行编辑,您必须先检索记录,所以基本上,HttpPost 版本的 Edit 将包含一些类似的代码,还有一行代码执行编辑 POST (PUT)。下面,我们通过向 WebAPI 传递一个特定的记录 ID 来获取响应。所以,就像索引 (GET) 一样,我们做同样的事情只是传递 ID,所以我们只取回一条记录。然后,我们将响应转换为可以在 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. 将 Edit 操作(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");
    }
    
于 2013-09-17T15:28:39.710 回答
2

您可以使用jQuery ajax 方法从客户端调用您的 Web API 。但是由于您是从部署 Web API 的站点以外的站点调用的,因此您必须使用 JSONP 而不是 JSON。查看此QA 以了解如何将 JSONP 与 Web API 一起使用。您的模型将作为 JSON 传递,您必须在客户端呈现,而不是使用 Razor 在服务器端呈现它。我会使用类似Knockout的东西在客户端上创建一个视图模型,它将您的模型绑定到客户端上的 HTML 元素。

于 2013-09-16T13:55:05.820 回答