Swagger是一种与技术无关的标准,允许发现REST API,为任何软件提供了一种识别REST API功能的方法。
这比看起来更重要:这是一个改变游戏技术的方式,就像Web服务描述语言一样WSDL(Web Service Description Language)一样。
WSDL一直是使Visual Studio等工具和IDE 可以理解Web服务并创建代理类的基础技术。此功能将Web服务的消耗转换为高级任务,封装所有协议详细信息。
这是Swagger的重要性:它可以为REST API做出WSDL已经为Web服务所做的工作,允许创建代理和使用Web API更容易。
VS 2017包括使用Swagger协议支持REST API代理创建。它还处于早期阶段,缺乏一些特点,但这是向广泛采用Swagger迈出的重要一步。
我们将创建一个例子,说明我们如何使用Swagger与VS 2017来分析优势和缺少的功能。
以及VS 2017,我们还将需要安装在开发机器中的IIS(Internet Information Server)作为示例。
发展环境
您可以将IIS作为Windows功能或服务器角色启用,具体取决于您是否使用客户端操作系统或服务器角色。
开始申请
在我们可以使用Swagger之前,我们需要一个具有Web API项目的演示解决方案。我们来构建这个开始的解决方案,然后再继续实施Swagger。
- 创建ASP.NET Web API项目
- 在Visual Studio中,选择“文件” - > “新建项目”菜单
- 在“新建项目”对话框的左侧树视图中,选择“已安装” - > “模板” - > “Visual C#” - > “Web”树项目。
- 在“新建项目”对话框的右侧,选择“ASP.NET Web应用程序(.NET Framework)”
在“名称”文本框中,键入“webDemo”
- 在“解决方案名称”文本框中,键入“slDemo”,然后单击“确定”按钮
在“新ASP.NET Web应用程序”窗口中,在“ASP.NET 4.5.2模板”下,选择“Web API”,然后单击“确定”按钮
- 配置Web API项目以使用本地IIS
- 在“解决方案资源管理器”窗口中,右键单击“webDemo”项目,然后单击“属性”菜单项。
- 在“webDemo”属性窗口的右侧,单击“Web”页面
在“服务器”下的组合框中,选择“本地IIS”
- 单击“创建虚拟目录”按钮
- 关闭'webDemo'属性页面
该项目已经开发了一个Web API控件示例,但是我们需要进行一些更改。我们来看一下现有控制器的细节,并做出这些改变。
- 分析和更改现有的API控制器
- 在“解决方案资源管理器”窗口的“webDemo”项目中,打开“控制器”文件夹并检查现有的控制器。
- 双击“ValuesController.cs”文件并检查现有操作。这是项目中唯一的Web API控制器。
更改下面的代码的“ValuesController”类。我们正在完成PUT操作并将该列表存储在Application memory区域内。
public class ValuesController : ApiController
{
private string[] lista
{
get
{
if (System.Web.HttpContext.Current.Application[<em>"lista"</em>]==null)
{
System.Web.HttpContext.Current.Application[<em>"lista"</em>] =
new string[] { <em>"value1"</em>, <em>"value2"</em> };
}
return
(string[])System.Web.HttpContext.Current.Application[<em>"lista"</em>];
}
}
public IEnumerable<string> Get()
{
return lista;
}
public string Get(int id)
{
return lista[id];
}
public void Post([FromBody]string value)
{
}
public void Put(int id, [FromBody]string value)
{
lista[id] = value;
}
public void Delete(int id)
{
}
}
|
- 执行应用程序并分析结果
- 单击工具栏中的“开始”按钮执行应用程序
在刚刚打开的网页上,点击顶部菜单中的“API”链接。您将注意到API操作,基本上是一个具有两个GET的 CRUD ,一个POST,PUT和DELETE
在浏览器导航栏中,键入新的URL:http:// localhost / webDemo / API / Values。因此,将下载一个JSON文件,因此该Web API正常工作。
在我们的项目中包括Swagger
Swagger是一项技术无关的协议。对于每种技术,我们需要一些实现协议的工具。SwashBuckle是.NET工具的名称。4.5之前的.NET版本和4.5之后的.NET的另一个版本。
让我们逐步练习使用SwashBuckle来实现Swagger :
- 在Web API项目中 包含SwashBuckle nugget包
- 在“ 解决方案资源管理器”窗口中,右键单击“webDemo”项目,然后单击“管理nuget数据包”菜单项。
- 在“Nuget包管理器”窗口中,选择“浏览”
- 在“Nuget软件包管理器”窗口中的文本框中,键入“SwashBuckle”。
在“Nuget软件包管理器”窗口的左侧,选择“SwashBuckle.Net45”软件包
- 在“Nuget软件包管理器”窗口的右侧,单击“安装”按钮。
- 在“查看更改”窗口中,单击“确定”按钮。
- 在“许可验收”窗口中,单击“我接受”按钮。
- 关闭“Nuget软件包管理器”窗口
- 配置XML文档。SwashBuckle将使用XML文档来描述WEB API操作。
- 在“解决方案资源管理器”窗口中,右键单击“webDemo”项目,然后单击“属性”菜单项。
- 在“webDemo”窗口中,单击“构建”页面
在'webDemo'窗口中的“输出”下方,单击“Xml文档文件”复选框。在右边的文本框中,您将看到路径“bin \ webDemo.xml”。
- 在“解决方案资源管理器”窗口的“webDemo”项目中,打开“控制器”文件夹,然后双击“ValuesController.cs”文件。
- 我们为每个动作和控制器创建一个XML文档。通过每个动作,并通过控制器声明,键入'///'并描述动作和控制器。
/// <summary>/// Retrieves the list of values/// </summary>/// <returns></returns>public IEnumerable<string> Get(){return lista;}/// <summary>/// Retrieves one value from the list of values/// </summary>/// <param name=<em>"id"</em>>The id of the item to be retrieved</param>/// <returns></returns>public string Get(int id){return lista[id];}/// <summary>/// Insert a new value in the list/// </summary>/// <param name=<em>"value"</em>>New value to be inserted</param>public void Post([FromBody]string value){}/// <summary>/// Change a single value in the list/// </summary>/// <param name=<em>"id"</em>>The id of the value to be changed</param>/// <param name=<em>"value"</em>>The new value</param>public void Put(int id, [FromBody]string value){lista[id] = value;}/// <summary>/// Delete an item from the list/// </summary>/// <param name=<em>"id"</em>>id of the item to be deleted</param>public void Delete(int id){}
- 配置SwashBuckle。现在,我们需要做的唯一配置就是XML文档的路径。
- 在“解决方案资源管理器”窗口的“webDemo”项目中,打开“App_Start”文件夹,然后双击“SwaggerConfig.cs”文件。该文件由“SwashBuckle.Net45” nuget软件包包含在该项目中。
“SwaggerConfig”类 的“注册”方法被配置为作为“PreApplicationStartMethod”执行。
- 在“SwaggerConfig”类中包含以下方法:
protected static string GetXmlCommentsPath(){return System.String.Format(@<em>"{0}\bin\webDemo.XML"</em>,System.AppDomain.CurrentDomain.BaseDirectory);}
- 在“注册”方法中取消注释以下代码块:
c.IncludeXmlComments(GetXmlCommentsPath());
- 在“SwaggerConfig”类中包含以下方法:
- 执行并测试应用程序
- 执行应用程序,单击工具栏中的“开始”按钮。
- 在浏览器地址栏中输入以下URL:http:// localhost / webDemo / Swagger / ui / index
在Swagger文档页面上,单击“值”,控制器的名称。
- 单击每个操作以查看文档。您可能会注意到Swagger正在使用每个操作的XML文档描述。
- 在浏览器地址栏中输入以下URL:http:// localhost / webDemo / Swagger / docs / v1。这一次我们正在寻找描述Web API 的JSON文档,这是SwashBuckle的核心结果
- 在出现的问题中,点击“保存”按钮(我正在使用Chrome,这可能与其他浏览器有所不同)
- 在出现的消息中,单击“打开文件夹”按钮。(我正在使用Chrome,这可能与其他浏览器有所不同)
用记事本 打开v1.json文件。该文件的格式不会很好,但内容却是对Web API的描述,如下图所示。如果您愿意,可以在Visual Studio中打开该文件,以查看文件格式正确的版本。
- 停止Visual Studio中的执行
创建客户端项目
现在是时候创建一个客户端来消费我们的Web API,并说明这个消费将如何容易多了。
- 向该解决方案添加一个新的Windows桌面项目
- 在Visual Studio中,单击菜单中的 “文件” - > “添加” - > “新建项目”
- 在“新建项目”对话框的左侧树视图中,选择“安装” - > “模板” - > “Visual C#” - > “Windows经典桌面”树项目。
- 在“新建项目”对话框的右侧,选择“Windows Forms App(.NET Framework)”
- 在“名称”文本框中,键入“winClient”,然后单击“确定”按钮
- 添加对Web API的引用并创建代理
在“解决方案资源管理器”窗口中,右键单击“winClient”项目,单击“添加” - > “REST API客户端”菜单项。
- In the ‘Add REST API Client’ window, ‘Swagger Url’ textbox, type http://localhost/webDemo/Swagger/docs/v1 .
In the ‘Client Namespace’ textbox, type ‘SvcRest’ and click the ‘Ok’ button.
It seems that nothing happened. Inside ‘Web Publish Activity’ window you will be able to see what happened and an error message: ‘Found operation object with duplicate OperationId ‘Values_Get’. OperationId must be unique among all operations described in the API’.
The client tool doesn’t support a REST API with operation overload, and our demo API has two GET methods. We need to resolve this problem before we proceed.
Support for operation overload
这种缺乏对操作超载的支持是一个很大的缺陷,因为即使是您可能注意到的演示Web API应用程序也使用操作重载,它有两个GET操作,带有和不带参数。
有两种可能的解决方案:
- 更改操作名称以避免过载
- 实现一个可以拦截JSON文件创建的操作过滤器,避免JSON文件中的重载。
让我们逐步实现一个操作过滤器:
- 为解决方案添加一个新的类库
- 在“ 解决方案资源管理器”窗口中,右键单击解决方案,单击“添加” - > “新建项目”上下文菜单项
- 在“新建项目”对话框的左侧树视图中,选择“安装” - > “模板” - > “Visual C#” - > “Windows经典桌面”树项目。
- 在“新建项目”对话框的右侧,选择“类库(.NET Framework)”
在“名称”文本框中,键入“libTools”,然后单击“确定”按钮
- 在“解决方案资源管理器”窗口中,右键单击“Class1.cs”文件,在“libTools”项目下,单击“删除”菜单项。
- 在新的Class Library项目中 安装“SwashBuckle.Core.Net45”软件包。我只安装SwashBuckle的核心,而不是所有的库。
- 在“解决方案资源管理器”窗口中,右键单击“libTools”项目,然后单击“管理nuget数据包”菜单项。
- 在“Nuget包管理器”窗口中,选择“浏览”
- 在“Nuget软件包管理器”窗口中的文本框中,键入“SwashBuckle”。
- 在“Nuget包管理器”窗口的左侧,选择“SwashBuckle.Core.Net45”包
- 在“Nuget软件包管理器”窗口的右侧,单击“安装”按钮。
- 在“查看更改”窗口中,单击“确定”按钮。
- 在“许可验收”窗口中,单击“我接受”按钮。
- 实现操作过滤器
- 在“解决方案资源管理器”窗口中,右键单击“libTools”项目,单击“添加” - > “类...”上下文菜单项
在“添加新项目”窗口中,在“名称”文本框中键入“MultipleOperationsWithSameVerbFilter.cs”。
- 复制下面的代码并粘贴到新文件中,替换空类:
using Swashbuckle.Swagger;using System.Web.Http.Description;public class MultipleOperationsWithSameVerbFilter : IOperationFilter{public void Apply(Operation operation,SchemaRegistry schemaRegistry,ApiDescription apiDescription){if (operation.parameters != null){operation.operationId += "By";foreach (var parm in operation.parameters){operation.operationId += string.Format("{0}",parm.name);}}}
- 复制下面的代码并粘贴到新文件中,替换空类:
- 在“webDemo”工程,引用添加到“libTools”项目
- 在“解决方案资源管理器”窗口中,右键单击“webDemo”项目,单击“添加” - > “参考”上下文菜单项
- 在“参考管理器”窗口的左侧,选择“项目” - > “解决方案”项
在“参考管理器”窗口的右侧,选中'libTools'以外的框,然后单击“确定”按钮
- 更改Swagger配置以使用新的操作过滤器
- 在“解决方案资源管理器”窗口的“webDemo”项目中,打开“App_Start”文件夹,然后双击“SwaggerConfig.cs”文件。
- 在“SwaggerConfig.cs”文件的顶部,添加以下行:
using libTools;
- 在“注册”方法中,在以下块中:
GlobalConfiguration.Configuration.EnableSwagger(c =>{
添加以下代码行:
c.OperationFilter<MultipleOperationsWithSameVerbFilter>();
在“解决方案资源管理器”窗口中,右键单击解决方案,然后单击“重建解决方案”菜单项
- 重复客户端代理创建的步骤2,这一次它将工作。
在客户端应用程序中使用代理
现在Web API代理是建立在客户端项目中的,现在是使用它来访问Web API的时候了。但是,代理需要一个额外的类来控制身份验证。这个功能的另一个缺点是它对匿名认证的处理不好,但是我们可以通过快速解决来克服这个问题。
- 在'libTools'项目中 安装'Microsoft.Rest.ClientRuntime'包。这个包是我们修复需要的。
- 在“解决方案资源管理器”窗口中,右键单击“libTools”项目,然后单击“管理nuget数据包”菜单项。
- 在“Nuget包管理器”窗口中,选择“浏览”
- 在“Nuget软件包管理器”窗口的文本框中,键入“Microsoft.Rest.ClientRuntime”。
- 在“Nuget包管理器”窗口的左侧,选择“Microsoft.Rest.ClientRuntime”包
- 在“Nuget软件包管理器”窗口的右侧,单击“安装”按钮。
- 在“查看更改”窗口中,单击“确定”按钮。
- 在“许可验收”窗口中,单击“我接受”按钮。
- 实现AnonymousCredential类。这将会导致匿名认证问题。
- 在“解决方案资源管理器”窗口中,右键单击“libTools”项目,然后单击“添加” - > “类”上下文菜单项。
- 在“添加新项目”对话框中,在“名称”文本框中键入“AnonymousCredential.cs”,然后单击“确定”按钮
- 在新文件的顶部,添加以下语句:
using Microsoft.Rest;
- 为此类使用以下代码。是的,没有什么需要,但继承。
public class AnonymousCredential : ServiceClientCredentials{}
- 3)构建客户端Windows窗体来访问API
- 在“解决方案资源管理器”窗口中的“winClient”项目下,双击“Form1.cs”文件。
- 从“工具箱”窗口中,在表单中添加三个按钮。
根据以下内容更改按钮属性:
名称:cmdAllValues
文本:所有值
名称:cmdValue
文本:单值
名称:cmdUpdate
文本:更新
- 在Windows项目中,添加对'libTools'项目的引用
- 在“解决方案资源管理器”窗口中,右键单击“winClient”项目,单击“添加” - > “参考”上下文菜单项
- 在“参考管理器”窗口的左侧,选择“项目” - > “解决方案”项
- 在“参考管理器”窗口的右侧,选中'libTools'以外的框,然后单击“确定”按钮
- 添加“所有值”按钮的代码
- 选择“Form1.cs(design)”页面
- 双击“所有值”按钮,这将为按钮创建一个点击事件。
- 在“Form1.cs”文件的顶部(由上一个任务已经打开),添加以下语句:
using libTools;using svcRest;
- 更改以下代码的“cmdAllValues_Click”:
private async void cmdAllValues_Click(object sender, EventArgs e){SvcRestClient client =new SvcRestClient(new Uri("http://localhost/webDemo"),new AnonymousCredential());var result = client.Values.Get();foreach(var x in result){MessageBox.Show(x);}}
请注意以下细节:
- 代理中有两种,同步和异步方法。代码说明了同步调用。
- 大多数方法是扩展方法:因为这样,我们需要使用“使用svcRest”语句。
- 您不需要处理调用API的协议详细信息。这是代理的优势。自.NET创建以来,我们对webservices有这个优势; 现在我们可以用这种方式使用web API。
- 添加“单值”按钮的代码
- 选择“Form1.cs(design)”页面
- 双击“单一值”按钮,这将为按钮创建一个点击事件。
- 更改以下代码的“cmdValue_Click”:
private async void cmdValue_Click(object sender, EventArgs e){SvcRestClient client =new SvcRestClient(new Uri("http://localhost/webDemo"),new AnonymousCredential());var result = client.Values.GetByid(1);MessageBox.Show(result);}
- 添加“更新”按钮的代码
- 选择“Form1.cs(design)”页面
- 双击“更新”按钮,这将为按钮创建一个点击事件。
- 更改以下代码的“cmdUpdate_Click”:
private async void cmdUpdate_Click(object sender, EventArgs e){SvcRestClient client =new SvcRestClient(new Uri("http://localhost/webDemo"),new AnonymousCredential());client.Values.PutByidvalue(1, "New Value");MessageBox.Show("Change Completed!");}
- 执行并测试应用程序
- 在“解决方案资源管理器”窗口中,右键单击“winClient”项目,然后单击“设为启动项目”
- 单击工具箱中的“开始”按钮运行应用程序
- 点击“所有值”按钮,“单一值”按钮,“更新”按钮和“单一值”按钮,并在需要时单击“确定”按钮,以检查结果。API调用将运行良好。
- 在Windows项目中,添加对'libTools'项目的引用