使用 ASP.NET MVC4 和 RestSharp 消费 ASP.NET WEB API






4.89/5 (24投票s)
在本文中,我们将学习如何使用 ASP.NET MVC4(作为客户端)和 RESTSHARP 来消费托管在另一台服务器上的 ASP.NET WEB API(仅作为 REST 服务)。
- 下载 ConsumeWebAPI (RAR) - 499.5 KB
- 下载 ConsumeWebAPI (ZIP) - 541.8 KB
- 下载 article_consumewebapi (ZIP) - 913 KB
- 下载 ConsumeWebAPI (RAR ZIP) - 536.4 KB
目录
- 引言
- 背景
- 先决条件
- 为什么要使用 RestSharp?
- 我们要消费什么?
- 创建 Web 项目
- 向项目添加 RestSharp 支持
- 添加 Rest 客户端
- 创建模型类
- 描述模型类
- 为什么所有检查都在客户端进行?
- 创建控制器
- 描述控制器
- 创建视图
- 执行项目
- 关注点
引言
在大多数场景下,我们使用 ASP.NET WEB API 来开发 ASP.NET MVC4 应用程序。但是,像 ASP.NET WEB API 这样的 RESTFul 服务 meant to be used by different clients。在本文中,我们将使用 ASP.NET MVC4(作为客户端)和 RestSharp(.NET 的简单 REST 和 HTTP 客户端)来消费简单的 ASP.NET WEB API。
背景
在阅读本文之前,我建议您阅读我之前的 文章,其中我定义了如何使用 FluentNHibernate 和 Repository Pattern 创建 ASP.NET WEB API(CRUD 操作)。
先决条件
要实现并运行源代码,您应该具备
- Visual Studio 2013 及更高版本
- ASP.NET MVC4 及更高版本
- ASP.NET WEB API2 及更高版本
- RestFul 服务基础知识
- ASP.NET WEB API 基础知识
- ASP.NET MVC4 及更高版本基础知识
为什么要使用 RestSharp?
由于我们将使用 RestSharp 调用我们的 ASP.NET WEB API URI,因此,首先,让我们讨论 "RestSharp"
。它只是 .NET 的一个简单 REST 和 HTTP API 客户端。它提供了一种简单的方式,我们可以初始化 RestClient
,传递 Request
,定义 Method (GET, POST, PUT, DELETE)
并获得 response
。
以下是常用的代码片段
//Create a restclient
RestClient restClient = new RestClient("url");
//Create request with GET
var request = new RestRequest("api/serverdata", Method.GET);
- 不要忘记提供
RequestFormat
,RestSharp
会自动序列化/反序列化复杂对象,例如我们演示项目中的ServerDataModel
。//Do not forget while using complex types var request = new RestRequest("api/serverdata", Method.GET) {RequestFormat = DataFormat.Json};
- 获取复杂类型的格式化结果
var response = restClient.Execute<List<ServerDataModel>>(request);
本文未涵盖许多其他功能。请参考 RestSharp Wiki。
我们要消费什么?
如前所述,在本文中,我们将消费现有的 ASP.NET WEB API URI(托管在服务器上),下表列出了所有 URI。
操作 | HTTP 方法 | 相对 URI |
获取服务器数据列表 | GET |
/api/serverdata |
按 ID 获取服务器数据 | GET |
/api/serverdata/id |
按数据类型获取服务器数据 | GET |
/api/serverdata/type/datatype |
按机器 IP 获取服务器数据 | GET |
/api/serverdata/ip/ip |
创建一个新的服务器数据 | POST |
/api/serverdata |
更新现有服务器数据 | PUT |
/api/serverdata/id |
删除现有服务器数据 | 删除 |
/api/serverdata/id |
请参考演示应用程序:演示 ASP.NET WEB API。
创建 Web 项目
让我们按照以下步骤开始创建我们的新 ASP.NET 项目(客户端项目)。
启动 Visual Studio,选择 文件->新建->项目(或按 Ctrl + Shift + N)。
在 模板 对话框中,选择 已安装模板,然后展开 Visual C# 节点。在 Visual C# 下,选择 Web。在项目模板列表中,选择 ASP.NET MVC4 Web 应用程序,为项目命名,然后单击“确定”。
我将我的项目命名为 consumewebapi
,您可以选择任何您喜欢的名称。 :)
从 项目模板 中,选择 Internet 应用程序,并从 视图引擎 下拉列表中选择 Razor,然后单击“确定”。
如果您正在进行 测试驱动开发,也可以选中 创建单元测试项目 复选框,我强烈推荐这样做。本文不涵盖这部分内容。
现在,在完成上述步骤后,我们已经拥有了默认的 ASP.NET MVC4 项目模板,稍后我们将添加我们的内容。
向项目添加 RestSharp 支持
我们将使用 RestSharp
来消费我们的 ASP.NET WEB API,请按照以下步骤操作:
转到 工具->NuGet 包管理器->包管理器控制台。
在包管理器控制台中,运行以下命令:
Install-Package RestSharp
它将为您的 consumewebapi
项目安装 RestSharp 的当前版本。
添加 Rest 客户端
- 在解决方案资源管理器中,创建一个新文件夹,并将其命名为 Helper - 此文件夹将包含我们所需的所有 RestSharp 客户端的帮助程序类(这些类将在我们的客户端和服务之间发挥接口作用)。
- 添加一个接口,并将其命名为
IServerDataRestClient
。IServerDataRestClient
的完整代码如下:public interface IServerDataRestClient { void Add(ServerDataModel serverDataModel); void Delete(int id); IEnumerable<serverdatamodel> GetAll(); ServerDataModel GetById(int id); ServerDataModel GetByIP(int ip); ServerDataModel GetByType(int type); void Update(ServerDataModel serverDataModel); }
- 在 Helper 文件夹下添加新类,并将其命名为
ServerDataRestClient
,然后实现接口IServerDataRestClient
。public class ServerDataRestClient : IServerDataRestClient { //implementation }
我们需要创建一个 RestClient
,在类中创建一个变量 private readonly RestClient _client;
并在构造函数中对其进行初始化。
//initializing RestClient
public ServerDataRestClient()
{
_client = new RestClient(_url);
}
在上面,当我们初始化 RestClient
对象时,我们提供了 BaseUrl
什么都没有,只是一个完整的 URL 名称,例如 http://myexample.com/。
我们也可以这样做:
_client = new RestClient {BaseUrl = _url};
我们从 config 文件中获取基础 URL,为什么它在 config 文件中?这对于大型项目非常有用,因为我们有不同的环境,例如 Dev, Staging,QA, Prod 等。
//getting base url from config
private readonly string _url = ConfigurationManager.AppSettings["webapibaseurl"];
现在,我们需要一个请求它只是包含一个资源和一个方法。
通过提供 {RequestFormat = DataFormat.Json};
,我们告诉 RestClient
以 Json 的形式提供输出。这在我们处理复杂类时是必需的,例如我们在这里使用 ServerDataModel
类。
在 DEBUG 模式下,在快速监视(Ctrl + D,Q)中检查 _client
,您将找到我们在创建 RestClient
对象时设置的所有内容。
我们的客户端已准备好传输请求并获取响应。
var response = _client.Execute<List<ServerDataModel>>(request);
上面的代码将以 ServerDataModel
类的列表形式提供输出。
打开 response
的快速监视,您将看到两个节点 [RestSharp.RestResponse<System.Collections.Generic.List<ConsumeWebAPI.Models.ServerDataModel>>] {RestSharp.RestResponse<System.Collections.Generic.List<ConsumeWebAPI.Models.ServerDataModel>>} RestSharp.RestResponse<System.Collections.Generic.List<ConsumeWebAPI.Models.ServerDataModel>>
和 Data.
第一个节点包含我们的实际内容(JSON 格式)以及其他信息,例如 ContentLength
、ContentType
、Cookies
、ErrorMessage
、Header
、Request
、ResponseStatus
、StatusCode
等。
Data 节点包含我们请求和需要的格式化数据。在本例中,它是一个 ServerDataModel
类型的列表。我们将稍后在视图中使用此模型。
我们也可以请求一个特定的资源,例如如果我们按 ID 获取记录,那么我们可以这样做:
var request = new RestRequest("api/serverdata/{id}", Method.GET) {RequestFormat = DataFormat.Json};
request.AddParameter("id", id, ParameterType.UrlSegment);
下面的代码将提供 ServerDataModel
类型的输出:
var response = _client.Execute<serverdatamodel>(request);
这是我们完整的 ServerDataRestClient
帮助程序类:
public class ServerDataRestClient : IServerDataRestClient
{
private readonly RestClient _client;
private readonly string _url = ConfigurationManager.AppSettings["webapibaseurl"];
public ServerDataRestClient()
{
_client = new RestClient {BaseUrl = _url};
}
public IEnumerable<serverdatamodel> GetAll()
{
var request = new RestRequest
("api/serverdata", Method.GET) {RequestFormat = DataFormat.Json};
var response = _client.Execute<list<serverdatamodel>>(request);
if (response.Data == null)
throw new Exception(response.ErrorMessage);
return response.Data;
}
public ServerDataModel GetById(int id)
{
var request = new RestRequest
("api/serverdata/{id}", Method.GET) {RequestFormat = DataFormat.Json};
request.AddParameter("id", id, ParameterType.UrlSegment);
var response = _client.Execute<serverdatamodel>(request);
if (response.Data == null)
throw new Exception(response.ErrorMessage);
return response.Data;
}
public ServerDataModel GetByType(int type)
{
var request = new RestRequest("api/serverdata/type/{datatype}", Method.GET)
{
RequestFormat = DataFormat.Json
};
request.AddParameter("datatype", type, ParameterType.UrlSegment);
var response = _client.Execute<serverdatamodel>(request);
return response.Data;
}
public ServerDataModel GetByIP(int ip)
{
var request = new RestRequest
("api/serverdata/ip/{ip}", Method.GET) {RequestFormat = DataFormat.Json};
request.AddParameter("ip", ip, ParameterType.UrlSegment);
var response = _client.Execute<serverdatamodel>(request);
return response.Data;
}
public void Add(ServerDataModel serverData)
{
var request = new RestRequest
("api/serverdata", Method.POST) {RequestFormat = DataFormat.Json};
request.AddBody(serverData);
var response = _client.Execute<serverdatamodel>(request);
if (response.StatusCode != HttpStatusCode.Created)
throw new Exception(response.ErrorMessage);
}
public void Update(ServerDataModel serverData)
{
var request = new RestRequest
("api/serverdata/{id}", Method.PUT) {RequestFormat = DataFormat.Json};
request.AddParameter("id", serverData.Id, ParameterType.UrlSegment);
request.AddBody(serverData);
var response = _client.Execute<serverdatamodel>(request);
if (response.StatusCode == HttpStatusCode.NotFound)
throw new Exception(response.ErrorMessage);
}
public void Delete(int id)
{
var request = new RestRequest("api/serverdata/{id}", Method.DELETE);
request.AddParameter("id", id, ParameterType.UrlSegment);
var response = _client.Execute<serverdatamodel>(request);
if (response.StatusCode == HttpStatusCode.NotFound)
throw new Exception(response.ErrorMessage);
}
}
创建模型类
在 解决方案资源管理器 中,右键单击 Models 文件夹,然后选择 添加->新建项(或按 Ctrl + Shift + A)。选择类,并将其命名为 ServerDataModel
,然后单击“添加”。这将添加一个空的 Model
类。
这是我们完整的 model
类:
public class ServerDataModel
{
public int Id { get; set; }
[Required]
[Display(Name = "Initial date")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
public DateTime InitialDate { get; set; }
[Required]
[Display(Name = "End date")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
public DateTime EndDate { get; set; }
[Required]
[Display(Name = "Order number")]
public int OrderNumber { get; set; }
[Required]
[Display(Name = "Is dirty")]
public bool IsDirty { get; set; }
[Required, StringLength(15)]
[Display(Name = "Data Server IP")]
[RegularExpression(@"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)
{3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$",
ErrorMessage = "Data Server IP should be in the form of 255.255.255")]
public string IP { get; set; }
[Required]
[Display(Name = "Record data type")]
[RegularExpression(@"^([1-2])$",
ErrorMessage = "Record Data Type should be 1 or 2")]
public int Type { get; set; }
[Display(Name = "Record identifier")]
[RegularExpression(@"^([0-9])$",
ErrorMessage = "Record identifier should be between 0 to 9")]
public int RecordIdentifier { get; set; }
}
描述模型类
以下是我们应该在 model
类中注意的一些点:
Initial Date
和End Date
应为Date
类型,格式为MM/dd/yyyy
。[DataType(DataType.Date)] [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)] public DateTime InitialDate { get; set; }
- 在这里,我们使用了数据注解。
- 我们设置了
ApplyFormatInEditMode = true
,这样在编辑模式下,用户就不会忘记提供所需的格式。 - 我们的日期字段在浏览器上应该包含
calendar
控件,该控件遵循 HTML5 规则。 IP
应以实际 IP 格式显示(以避免输入不必要的string
)。[Display(Name = "Data Server IP")] [RegularExpression(@"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.) {3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$", ErrorMessage = "Data Server IP should be in the form of 255.255.255")] public string IP { get; set; }
- 这里,我们使用了
RegularExpression
,如果格式不匹配,应用程序将抛出错误。 Record data type
应为 1 或 2。[Required] [Display(Name = "Record data type")] [RegularExpression(@"^([1-2])$", ErrorMessage = "Record Data Type should be 1 or 2")] public int Type { get; set; }
- 如果表达式不匹配,它将抛出错误消息。
Record identifier
应介于 0-9 之间。- 如果表达式不匹配,它将抛出错误消息。
为什么所有检查都在客户端进行?
在本文中,我们在客户端项目(ASP.NET MVC4)中实现了 ASP.NET WEB API,在这里我们希望确保每个请求都经过验证且无错误。关于这种方法(是在客户端还是在服务侧实现)存在很多争论。在我看来,服务是中心化的过程,它将从多个客户端调用,因此,每个客户端都有责任确保传入的请求经过验证且无错误(这里传入的请求不包含任何安全逻辑,这里我指的是正常的验证数据检查)。
创建控制器
- 在 解决方案资源管理器 中,右键单击 Controllers 文件夹,然后单击 控制器。
- 在“添加控制器”对话框中,输入控制器名称
ServerDataController
,并从 模板 下拉列表中选择“带有空的读/写操作的 MVC 控制器”,然后单击“添加”。
描述控制器
我们的 ServerDataController
将使用 RestSharp 来消费 ASP.NET WEB API(我们将使用上面创建的帮助程序类)。
static readonly IServerDataRestClient RestClient = new ServerDataRestClient();
上面,我们简单地初始化了我们的 ServerDataRestClient
。
private IServerDataRestClient _restClient;
public ServerDataController(IServerDataRestClient restClient)
{
_restClient = restClient;
}
上面是另一种方式,其中我们需要使用控制反转(IOC)。
public ActionResult Index()
{
return View(RestClient.GetAll());
}
在上面的代码中,我们的 Index ActionResult
方法将从服务获取所有 ServerData
记录并渲染我们的 view
。此时我们需要添加视图。
创建视图
此时,我们需要一个 UI,我们可以在其中显示输出或为用户提供与应用程序交互的界面。因此,我们需要添加一个 view
。
添加视图的直接/粗略方法是,在解决方案资源管理器中,添加一个新文件夹 ServerData,右键单击它,然后单击 添加视图。
在 添加视图 对话框中,将视图命名为 Index
,选择 Razor
作为 ViewEngine
,创建强类型视图,并选择 ServerDataModel
作为 Model
类。我使用了 List 的 Scaffold Template
(如果您不想使用,可以忽略),使用您的主布局,然后单击“添加”。
这将在项目中添加一个新的视图。
@model IEnumerable<consumewebapi.models.serverdatamodel>
@{
ViewBag.Title = "Manipulate Server Data";
Layout = "~/Views/Shared/_Layout.cshtml";
}</consumewebapi.models.serverdatamodel>
我们做了一些小的修改来获得输出。
@string.Format(item.IsDirty ? "Yes" : "No")
这将为我们显示 Yes
或 No
,表明我们的记录是否脏。
按照相同的步骤添加其他视图,这是结构:
执行项目
最后,我们完成了所有自定义和更改,现在是时候运行我们的项目了。只需单击运行或按 F5
。我们的 Index
页面将呈现为:
关注点
- 啊!ASP.NET MVC4 没有提供直接实现 RestSharp 的方法。有一个很好的方法可以向我们的项目添加
RestSharp
支持,然后我们就可以使用这个强大的框架了。 - 我在这里创建了一个演示应用程序:here。您可以使用它,并将其代码作为部分或全部采用。如果您发现任何问题或需要处理的其他事项,我很乐意收到您的反馈。
历史
- 2014 年 10 月 6 日:初始版本
- 2015 年 8 月 13 日:源代码已更新