65.9K
CodeProject 正在变化。 阅读更多。
Home

在 Visual Studio 2010 中创建带有 CRUD 操作的自托管 ASP.NET WebAPI

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.85/5 (15投票s)

2016年4月14日

CPOL

14分钟阅读

viewsIcon

77100

downloadIcon

3169

在本文中,我将解释如何将 WebAPI 托管在独立于 IIS 的另一个进程中。

引言

在我关于 WebAPI 的学习系列中,我写了很多关于 WebAPI 的内容,但我漏掉了一个关键主题,那就是托管 ASP.NET WebAPI。您可以按照以下系列来从头开始理解 WebAPI。

在 IIS 中托管 WebAPI 非常简单,与托管典型的 ASP.NET Web 应用程序非常相似。在本文中,我将解释如何将 WebAPI 托管在独立于 IIS 的另一个进程中。

我将解释如何使用 Entity Framework 4.0 快速创建一个具有 CRUD 操作的 WebAPI,然后将其托管在独立的服务器上。我将通过一个充当客户端的控制台应用程序来调用服务终结点。您可以使用任何客户端来检查服务终结点并验证其功能。我将尝试通过实际应用来解释该主题,然后在 Visual Studio 2010 中围绕 .NET Framework 4.0 等目标框架创建一个服务和一个测试客户端。

WebAPI 项目

创建 ASP.NET REST 服务的传统方法是从 Visual Studio 中选择一个 WebAPI 项目,创建一个控制器,公开终结点,然后将其托管在 IIS 上。但当涉及到在 Windows 上创建自托管的 Web API 时,我们需要采用一个基于 Windows 或控制台的应用程序,该应用程序编译后会生成一个 EXE 文件,然后可以通过命令提示符用于托管。您可以使用 OWIN 托管 WebAPI 2,这借助下面提到的两个 NuGet 包非常简单。

Microsoft.Owin.SelfHost

Microsoft.AspNet.WebApi.OwinSelfHost

但是,我们将对 WebAPI 1 进行托管,并且不为此应用程序使用 OWIN。

步骤 1:创建控制台应用程序

打开您的 Visual Studio 并创建一个名为 SelfHostedAPI 的新控制台应用程序。

我们将向其中添加一个 WebAPI 控制器并编写 CRUD 操作的代码,但在此之前,我们需要一个数据库以及用于执行数据库事务的通信。我将使用 EntityFramework 进行数据库事务。

步骤 2:创建数据库

您可以创建任何您想要的数据库。我使用的是 SQL Server,将创建一个名为 WebAPIdb 的数据库,其中包含一个名为 Products 的表,用于执行 CRUD 操作。此数据库中有更多表,但我们不会使用它们。

我将在此文章中提供该数据库脚本。Products 表的脚本如下:

   1:  
   2: USE [WebApiDb]
   3: GO
   4: /****** Object: Table [dbo].[Products] Script Date: 
   5: 04/14/2016 11:02:51 ******/
   6: SET ANSI_NULLS ON
   7: GO
   8: SET QUOTED_IDENTIFIER ON
   9: GO
  10: SET ANSI_PADDING ON
  11: GO
  12: CREATE TABLE [dbo].[Products](
  13:  [ProductId] [int] 
  14: IDENTITY(1,1) NOT NULL,
  15:  [ProductName] [varchar](50) NOT 
  16: NULL,
  17: CONSTRAINT [PK_Products] PRIMARY KEY CLUSTERED 
  18:  
  19: (
  20:  [ProductId] ASC
  21: )WITH (PAD_INDEX = OFF, 
  22: STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS 
  23: = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
  24: ) ON [PRIMARY]
  25: GO
  26: SET ANSI_PADDING OFF
  27: GO

至此,数据库创建完成,现在让我们设置用于通信的实体层。

步骤 3:使用 Entity Framework 设置数据访问

在您的 Visual Studio 中,选择工具 -> 程序包管理器 -> 程序包管理器控制台以添加 Entity framework 程序包。

我将安装 Entity Framework 5.0,因为它与 .NET Framework 4.0 配合良好。所以选择 SelfHostedAPI 作为默认项目,然后输入命令 Install-Package EntityFramework –Version 5.0.0 并按 Enter 键。

成功安装后,您将看到 Entity framework DLL 已添加到您的项目中。

现在右键单击您的项目并添加新项。从 Visual C# 项列表中选择 ADO.Net Entity Data Model。

系统将提示您选择生成模型。选择“从数据库生成”选项并继续。

在下一步提供数据库详细信息后,选择您要映射到模型数据库表。我只选择了 products 表,因为我们将只在此表上执行 CRUD。

单击“完成”,您的 Entity Data Model 将准备好并映射到您的数据库表。您将看到生成了一个 App.Config 文件,并在该配置文件中添加了一个特定于所选数据库的连接字符串。

现在我们需要生成一个处理事务的对象上下文和充当映射到表的模型类的对象集。

右键单击您的 edmx 视图,然后在上下文菜单中单击“添加代码生成项”。

在打开的项列表窗口中,选择 ADO.NET EntityObject Generator,如下图所示。

选择此项并按 OK,这将生成您的 Model1.tt 类,其中包含同一类中的上下文和实体。现在我们完成了所有与数据库相关的工作。我将创建一个 WebAPI 控制器并将所有 CRUD 操作放在其中。

步骤 4:添加 WebAPI 控制器

由于我们需要一个可以对数据库执行所有 CRUD 操作的 API,因此我们必须在项目中添加一个 WebAPI 控制器类。由于这是一个控制台应用程序而不是 WebAPI 项目,因此我们没有为添加控制器定义适当的结构。您可以创建自己的文件夹结构以便于理解。我直接在项目中添加一个名为 ProductController 的 API 控制器类。

右键单击项目,添加新项,然后从项列表中选择 WebAPI 控制器类。您可以将其命名为您选择的任何名称。我将其命名为 ProductController。

生成的类派生自 APIController 类。这意味着它是一个有效的 WebAPI 控制器类。该类默认包含默认 CRUD 方法,这些方法具有以下实现:

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Net;
   5: using System.Net.Http;
   6: using System.Web.Http;
   7:  
   8: namespace SelfHostedAPI
   9: {
  10:     public class ProductController : ApiController
  11:     {
  12:         // GET api/<controller>
  13:         public IEnumerable<string> Get()
  14:         {
  15:             return new string[] { "value1", "value2" };
  16:         }
  17:  
  18:         // GET api/<controller>/5
  19:         public string Get(int id)
  20:         {
  21:             return "value";
  22:         }
  23:  
  24:         // POST api/<controller>
  25:         public void Post([FromBody]string value)
  26:         {
  27:         }
  28:  
  29:         // PUT api/<controller>/5
  30:         public void Put(int id, [FromBody]string value)
  31:         {
  32:         }
  33:  
  34:         // DELETE api/<controller>/5
  35:         public void Delete(int id)
  36:         {
  37:         }
  38:     }
  39: }

我们将利用这些默认方法,但为数据库操作编写自己的业务逻辑。

步骤 5:添加 CRUD 方法

我们将添加创建、读取、更新和删除的所有四种方法。请注意,我们将不使用 UnitOfWork 或 Repository 等设计模式来进行数据持久化,因为我们的主要目标是自托管此服务并公开其 CRUD 终结点。

1. 获取所有记录

修改 Get() 方法以返回 Product 实体的列表,并使用 Model1.cs 文件中生成的 WebAPIEntities 类来获取产品列表。此处的方法名称也表示方法类型,所以这基本上是服务的 Get 方法,并且从客户端调用时应该也是方法类型 get。对于我们在此类中为所有 CRUD 操作编写的每种方法,情况都是如此。

   1: // GET api/<controller>
   2:         public IEnumerable<Product> Get()
   3:         {
   4:             var entities=new WebApiDbEntities();
   5:             return entities.Products;
   6:         }

在上述代码库中,我们返回 Product 实体的 IEnumerable,并使用 WebApiDbEntities (自动生成的上下文类) 的对象来通过 entities.Products 获取所有对象。

2. 按 id 获取产品

修改 Get(int id) 方法以返回一个产品实体。该方法接受一个 id 并返回特定于该 id 的产品。您可以增强该方法以进行验证和检查,使其更健壮,但为了理解概念,我只是直接进行。

   1: // GET api/<controller>/5
   2:        public Product Get(int id)
   3:        {
   4:            var entities = new WebApiDbEntities();
   5:            return entities.Products.FirstOrDefault(p=>p.ProductId==id);
   6:        }

3. 创建产品

   1: // POST api/<controller>
   2:        public bool Post([FromBody]Product product)
   3:        {
   4:            var entities = new WebApiDbEntities();
   5:            entities.AddToProducts(product);
   6:            var i = entities.SaveChanges();
   7:            return i > 0;
   8:        }

顾名思义,这是一个 Post 方法,它从请求正文中获取一个 Product 类对象,并将该产品添加到实体中。请注意,只有当您执行 entities.SaveChanges() 时,您的产品才会被添加到实际数据库中。此方法实际在数据库中插入您的记录,并在成功插入时返回 1,否则返回 0。

4. 编辑/更新产品

   1: // PUT api/<controller>/5
   2:      public bool Put(int id, [FromBody]Product product)
   3:      {
   4:          using (var entities = new WebApiDbEntities())
   5:          {
   6:              var prod = (from p in entities.Products
   7:                          where p.ProductId == id
   8:                          select p).FirstOrDefault();
   9:  
  10:              prod.ProductName = product.ProductName;
  11:              var i=entities.SaveChanges();
  12:              return i > 0;
  13:          }
  14:      }

由于这是一项更新操作,我们将其命名为 Put 方法,顾名思义,它是 PUT 类型。该方法将 id 和 product 对象作为参数,首先从数据库中获取具有作为参数传递的 id 的实际产品,然后使用参数 product 的详细信息修改该产品,然后再次保存到数据库。在我们的例子中,只有产品名称可以更改,因为 id 是固定的主键,所以我们在该方法中更新产品的产品名称并保存对该实体的更改。

5. 删除产品

   1: // DELETE api/<controller>/5
   2:         public bool Delete(int id)
   3:         {
   4:             using (var entities = new WebApiDbEntities())
   5:             {
   6:                 var prod = (from p in entities.Products
   7:                             where p.ProductId == id
   8:                             select p).FirstOrDefault();
   9:  
  10:                entities.Products.DeleteObject(prod);
  11:                var i=entities.SaveChanges();
  12:                return i > 0;
  13:             }
  14:         }

上述删除方法是 DELETE 类型,并接受产品 id 作为参数。该方法根据传递的 id 从数据库中获取产品,然后删除该产品并保存更改。实现非常简单且不言自明。

有了这个方法,我们就完成了所有需要的 CRUD 终结点。正如您所见,我没有为终结点应用任何特殊的路由,而是依赖于 WebAPI 提供的默认路由,即 api/<controller>/<id>

步骤 6:托管 WebAPI

现在到了这篇帖子的最重要的部分,“自托管”。还记得您创建 SelfHostedAPI 项目时,它是一个控制台应用程序,所以它带有一个在项目中创建的 Program.cs 文件。Program.cs 文件包含 main 方法,即应用程序的入口点。我们将使用此 main 方法来编写 WebAPI 的自托管代码。

在我们编写任何代码之前,我们需要通过程序包管理器控制台添加一个 nuget 程序包。此程序包包含托管 API 在控制台应用程序中所需的托管特定类,即独立于 IIS 的单独进程。请注意,在 WebAPI 2 中,我们有 OWIN 中间件,它提供了这种灵活性。

由于我们使用的是 Visual Studio 2010 和 .NET Framework 4.0,因此我们需要安装一个名为 Microsoft.AspNet.WebApi.SelfHost 的特定版本程序包。我找到的兼容版本是 4.0.20710。

所以打开您的程序包管理器控制台,选择默认项目,然后执行命令 "Install-Package Microsoft.AspNet.WebApi.SelfHost -Version 4.0.20710"

这将为您的项目安装程序包,现在您可以使用它进行实现。

打开 Program.cs 文件并添加一个命名空间。

   1: using System.Web.Http.SelfHost;

然后在 main 方法中定义您要公开的终结点的基地址。我选择的终结点是 8082。确保您以管理员模式运行 Visual Studio,否则您将需要更改一些配置才能使其正常工作。我从这个 ASP.NET 文章中获取了以下解释来解释配置更改,

添加 HTTP URL 命名空间保留

此应用程序侦听 https://:8080/。默认情况下,侦听特定 HTTP 地址需要管理员权限。因此,当您运行教程时,您可能会收到此错误:“HTTP 无法注册 URL http://+:8080/”。有两种方法可以避免此错误:

  • 以提升的管理员权限运行 Visual Studio,或
  • 使用 Netsh.exe 为您的帐户授予保留 URL 的权限。

要使用 Netsh.exe,请以管理员权限打开命令提示符,然后输入以下命令:

netsh http add urlacl url=http://+:8080/ user=machine\username

其中 machine\username 是您的用户帐户。

完成自托管后,请务必删除保留项。

netsh http delete urlacl url=http://+:8080/"

1. 定义 SelfHostConfiguration 对象如下:

   1: var config = new HttpSelfHostConfiguration("https://:8082");

2. 定义 WebAPI 的默认路由。

   1: config.Routes.MapHttpRoute(
   2:                "API Default", "api/{controller}/{id}",
   3:                new { id = RouteParameter.Optional });

这是服务运行时将遵循的默认路由。

3. 在进程中启动服务器

   1: using (var server = new HttpSelfHostServer(config))
   2:  {
   3:      server.OpenAsync().Wait();
   4:      Console.WriteLine("Server started....");
   5:      Console.WriteLine("Press Enter to quit.");
   6:      Console.ReadLine();
   7:  }

上面的代码用于托管和启动我们创建的服务服务器。正如您所见,只需几行代码即可在单独的进程中启动我们的服务,而无需依赖 IIS 服务器。

因此,我们的 Program.cs 文件如下:

   1: using System;
   2: using System.Web.Http;
   3: using System.Web.Http.SelfHost; 
   4:  
   5: namespace SelfHostedAPI
   6: {
   7:     class Program
   8:     {
   9:         static void Main(string[] args)
  10:         {
  11:             var config = new HttpSelfHostConfiguration("https://:8082");
  12:  
  13:             config.Routes.MapHttpRoute(
  14:                 "API Default", "api/{controller}/{id}",
  15:                 new { id = RouteParameter.Optional });
  16:  
  17:             using (var server = new HttpSelfHostServer(config))
  18:             {
  19:                 server.OpenAsync().Wait();
  20:                 Console.WriteLine("Server started....");
  21:                 Console.WriteLine("Press Enter to quit.");
  22:                 Console.ReadLine();
  23:             }
  24:         }
  25:     }
  26: }

现在,当您按 F5 启动应用程序时,您的服务器将启动,服务终结点将侦听您的请求。我们将通过即将创建的测试客户端来测试这些终结点。但在此之前,让我们启动服务器。

编译应用程序,然后在 Windows 资源管理器中导航到 bin\debug 文件夹中的 SelfHostedAPI.exe 并以管理员身份运行它。

您的服务器将立即启动。

当您在浏览器中输入 URL https://:8082 时,您会看到服务器实际上返回了资源未找到的响应。

这意味着我们的端口正在侦听请求。

WebAPI 测试客户端

既然我们知道我们的服务已启动并正在运行,那么是时候通过测试客户端进行测试了。您可以使用自己的测试客户端,也可以将其构建为一个控制台应用程序。我正在 .NET 中构建一个单独的测试客户端来测试服务。

步骤 1:添加一个控制台应用程序

在同一解决方案或另一个解决方案中添加一个名为 APITestClient 或您选择的名称的控制台应用程序。我们将使用 Program.cs 来编写调用 WebAPI 方法的所有代码。但在此之前,我们需要安装一个 nuget 程序包,该程序包有助于我们创建 httpclient,通过它我们将进行 API 调用。

步骤 2:添加 Web 客户端程序包

打开 Library package manager,选择 APITestClient 作为默认项目,然后执行命令 "Install-Package Microsoft.AspNet.WebApi.Client -Version 4.0.20710"



这将为您的测试客户端项目安装必要的程序包及其依赖项。

步骤 3:设置客户端

是时候编写代码了,打开 program.cs 并添加命名空间。

   1: using System.Net.Http;
   2: using System.Net.Http.Headers;

定义 HttpClient 变量。

   1: private static readonly HttpClient Client = new HttpClient();

然后在 Main 方法中,使用基本要求初始化客户端,例如要调用的服务的基地址和媒体类型。

   1: Client.BaseAddress = new Uri("https://:8082");
   2: Client.DefaultRequestHeaders.Accept.Clear();
   3: Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

一切就绪,现在我们可以编写 CRUD 调用方法并从 main 方法调用它们。

步骤 4:调用方法

1. GetAllProducts

   1: /// <summary>
   2:        /// Fetch all products
   3:        /// </summary>
   4:        private static void GetAllProducts()
   5:        {
   6:            HttpResponseMessage resp = Client.GetAsync("api/product").Result;
   7:            resp.EnsureSuccessStatusCode();
   8:  
   9:            var products = resp.Content.ReadAsAsync<IEnumerable<SelfHostedAPI.Product>>().Result.ToList();
  10:            if (products.Any())
  11:            {
  12:                Console.WriteLine("Displaying all the products...");
  13:                foreach (var p in products)
  14:                {
  15:                    Console.WriteLine("{0} {1} ", p.ProductId, p.ProductName);
  16:                }
  17:            }
  18:        }

上述方法通过 HttpClient 实例调用“api/product”终结点,并期望从服务返回 HttpResponseMessage 结果。请注意,它使用 GetAsync 方法进行终结点调用,这表明它正在调用 REST API 的 Get 方法。

我们的数据库中有大约六条记录需要显示。

让我们通过调用 Main 方法中的方法来运行应用程序,但在那之前,请确保您的 WebAPI 正在控制台应用程序中运行,就像我们之前所做的那样。

   1: private static void Main(string[] args)
   2: {
   3:     Client.BaseAddress = new Uri("https://:8082");
   4:     Client.DefaultRequestHeaders.Accept.Clear();
   5:     Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
   6:     GetAllProducts();
   7:   
   8:     Console.WriteLine("Press Enter to quit.");
   9:     Console.ReadLine();
  10: }

结果如下。

太棒了,我们从数据库中获取了所有产品到这个客户端。

这证明了我们的服务已成功托管并正常运行。我们可以以类似的方式定义其他方法并测试 API 终结点。

2. GetProduct()

此方法按 id 获取产品。

   1: /// <summary>
   2: /// Get product by id
   3: /// </summary>
   4: private static void GetProduct()
   5: {
   6:     const int id = 1;
   7:     var resp = Client.GetAsync(string.Format("api/product/{0}", id)).Result;
   8:     resp.EnsureSuccessStatusCode();
   9:  
  10:     var product = resp.Content.ReadAsAsync<SelfHostedAPI.Product>().Result;
  11:     Console.WriteLine("Displaying product having id : " + id);
  12:     Console.WriteLine("ID {0}: {1}", id, product.ProductName);
  13: }

该方法同样不言自明。我默认调用此方法来获取产品 id “1”,您可以根据需要自定义该方法。只需编译并运行该方法。我们得到:

因此,我们得到了结果。

3. AddProduct()

   1: /// <summary>
   2:        /// Add product
   3:        /// </summary>
   4:        private static void AddProduct()
   5:        {
   6:            var newProduct = new Product() { ProductName = "Samsung Phone" };
   7:            var response = Client.PostAsJsonAsync("api/product", newProduct);
   8:            response.Wait();
   9:            if (response.Result.IsSuccessStatusCode)
  10:            {
  11:                Console.WriteLine("Product added.");
  12:            }
  13:        }

在上面的方法中,我尝试在现有产品列表中添加一个名为“Samsung Phone”的新产品。由于我们在数据库中有自动 ID 生成,因此我们不必提供产品的 ID。它将自动以唯一的 ID 插入数据库。请注意,此方法通过 Post 类型的方法调用 API 终结点。运行应用程序。

它显示产品已添加。现在让我们转到数据库并检查我们的表。在 SQL Server 数据库中对您的表执行 select 查询,我们会发现表中添加了一个新产品,ID 为“7”,名称为“Samsung Phone”。

4. EditProduct()

   1: /// <summary>
   2:        /// Edit product 
   3:        /// </summary>
   4:        private static void EditProduct()
   5:        {
   6:            const int productToEdit = 4;
   7:            var product = new Product() { ProductName = "Xamarin" };
   8:  
   9:            var response =
  10:                Client.PutAsJsonAsync("api/product/" + productToEdit, product);
  11:            response.Wait();
  12:            if (response.Result.IsSuccessStatusCode)
  13:            {
  14:                Console.WriteLine("Product edited.");
  15:            }
  16:  
  17:        }

在上面的代码中,我正在编辑 ID 为“4”的产品,并将现有产品名称 iPad 修改为 Xamarin。请注意,此方法通过 Put 类型的方法调用 API 终结点。运行应用程序。

在数据库中

我们在这里看到,我们现有的产品 iPad 已更新为新名称“Xamarin”。我们看到一个 ID 为 8 的新产品也被添加了。这是因为我们再次从 main 方法调用了 add 方法。理想情况下,我们在测试 edit 方法时会将其注释掉。

5. DeleteProduct()

   1: /// <summary>
   2:     /// Delete product
   3:     /// </summary>
   4:     private static void DeleteProduct()
   5:     {
   6:         const int productToDelete = 2;
   7:         var response = Client.DeleteAsync("api/product/" + productToDelete);
   8:         response.Wait();
   9:         if (response.Result.IsSuccessStatusCode)
  10:         {
  11:             Console.WriteLine("Product deleted.");
  12:         }
  13:     }

在上面的方法中,我们删除了 ID 为 2 的产品。请注意,此方法通过 Delete 类型的方法调用 API 终结点。运行应用程序。

产品已删除。让我们在数据库中检查一下:

我们看到 ID 为“2”的产品已被删除。

因此,我们对自托管的 WebAPI 执行了所有 CRUD 操作。结果符合预期。以下是 Program.cs 文件的合并代码。

   1: #region Using namespaces
   2: using System;
   3: using System.Collections.Generic;
   4: using System.Linq;
   5: using System.Net.Http;
   6: using System.Net.Http.Headers;
   7: using SelfHostedAPI; 
   8: #endregion
   9:  
  10: namespace APITestClient
  11: {
  12:     internal class Program
  13:     {
  14:         #region Private member variables
  15:         private static readonly HttpClient Client = new HttpClient(); 
  16:         #endregion
  17:  
  18:         #region Main method for execution entry
  19:         /// <summary>
  20:         /// Main method
  21:         /// </summary>
  22:         /// <param name="args"></param>
  23:         private static void Main(string[] args)
  24:         {
  25:             Client.BaseAddress = new Uri("https://:8082");
  26:             Client.DefaultRequestHeaders.Accept.Clear();
  27:             Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
  28:             GetAllProducts();
  29:             GetProduct();
  30:             AddProduct();
  31:             EditProduct();
  32:             DeleteProduct();
  33:             Console.WriteLine("Press Enter to quit.");
  34:             Console.ReadLine();
  35:         } 
  36:         #endregion
  37:  
  38:         #region Private client methods
  39:         /// <summary>
  40:         /// Fetch all products
  41:         /// </summary>
  42:         private static void GetAllProducts()
  43:         {
  44:             HttpResponseMessage resp = Client.GetAsync("api/product").Result;
  45:             resp.EnsureSuccessStatusCode();
  46:  
  47:             var products = resp.Content.ReadAsAsync<IEnumerable<SelfHostedAPI.Product>>().Result.ToList();
  48:             if (products.Any())
  49:             {
  50:                 Console.WriteLine("Displaying all the products...");
  51:                 foreach (var p in products)
  52:                 {
  53:                     Console.WriteLine("{0} {1} ", p.ProductId, p.ProductName);
  54:                 }
  55:             }
  56:         }
  57:  
  58:         /// <summary>
  59:         /// Get product by id
  60:         /// </summary>
  61:         private static void GetProduct()
  62:         {
  63:             const int id = 1;
  64:             var resp = Client.GetAsync(string.Format("api/product/{0}", id)).Result;
  65:             resp.EnsureSuccessStatusCode();
  66:  
  67:             var product = resp.Content.ReadAsAsync<SelfHostedAPI.Product>().Result;
  68:             Console.WriteLine("Displaying product having id : " + id);
  69:             Console.WriteLine("ID {0}: {1}", id, product.ProductName);
  70:         }
  71:  
  72:         /// <summary>
  73:         /// Add product
  74:         /// </summary>
  75:         private static void AddProduct()
  76:         {
  77:             var newProduct = new Product() { ProductName = "Samsung Phone" };
  78:             var response = Client.PostAsJsonAsync("api/product", newProduct);
  79:             response.Wait();
  80:             if (response.Result.IsSuccessStatusCode)
  81:             {
  82:                 Console.WriteLine("Product added.");
  83:             }
  84:         }
  85:  
  86:         /// <summary>
  87:         /// Edit product 
  88:         /// </summary>
  89:         private static void EditProduct()
  90:         {
  91:             const int productToEdit = 4;
  92:             var product = new Product() { ProductName = "Xamarin" };
  93:  
  94:             var response =
  95:                 Client.PutAsJsonAsync("api/product/" + productToEdit, product);
  96:             response.Wait();
  97:             if (response.Result.IsSuccessStatusCode)
  98:             {
  99:                 Console.WriteLine("Product edited.");
 100:             }
 101:  
 102:         }
 103:  
 104:         /// <summary>
 105:         /// Delete product
 106:         /// </summary>
 107:         private static void DeleteProduct()
 108:         {
 109:             const int productToDelete = 2;
 110:             var response = Client.DeleteAsync("api/product/" + productToDelete);
 111:             response.Wait();
 112:             if (response.Result.IsSuccessStatusCode)
 113:             {
 114:                 Console.WriteLine("Product deleted.");
 115:             }
 116:         }
 117:  
 118:         #endregion
 119:     }
 120: }

结论

我已尽力使本教程简单明了,并通过每个步骤来解释您如何使用 Entity Framework 创建一个包含所有 CRUD 操作的简单 WebAPI,最后自托管该 API 并进行测试。希望您喜欢阅读这篇文章。您可以从 github 下载完整的源代码。

© . All rights reserved.