目录
背景
本文涵盖的内容
介绍
创建新项目
将创建一个新文件夹
运行Web API项目
只是生成项目
实际使用中的Web API
一个通过Get的Web API方法
Visual Studio Code
开启文件夹
重点地区
检查WeatherForecastController
在子目录中打开文件
控制器:应用逻辑层
我们的主要挑战
默认Post方法
次要挑战:客户端Post创建
第一次最简单的Post测试
Walkthru:PostMan请求
创建一个新请求
PostMan:配置更改
HTTPS:不支持自签名证书
Post到WeatherForecastController
发布JSON:尝试1
WeatherForecast类分析
JSON:名称/值对
更改WeatherForecastController Post方法
进行更改并运行
错误说明
Console.WriteLine的Post()方法无法运行
自动转换为领域对象:太神奇了!
总结第1部分
使用代码
您是否曾经想过生成一种快速的Web API来运行某些服务器端功能?阅读本文,您将拥有一个可用的Web API,并了解如何使用原始JavaScript通过XMLHttpRequest(AJAX)将JSON发布到它。
- 下载源代码4.4 KB
最近,在放松使用.NET Core Web API的同时,我发现我不确定通过XMLHttpRequest(XHR)对象将数据发布到Web API的正确方法。
我不确定:
- 如何将数据添加到XHR对象以使其显示在帖子主体中。
- 如何确保Web API将发布的JSON自动转换为我的目标域对象。
我遇到了各种各样的错误,我无法分辨是客户端错误还是Web API错误,或者两者都不是。我发现两者都是错误的,但是即使您认为这是常见的配对(将纯JavaScript XHR发布到Web API),也很难找到一个明确的答案。
本文涵盖的内容- 创建一个.NET Core Web API项目(通过命令行)——我使用在Ubuntu Linux上运行的Visual Studio Code
- 添加可以发布的Web API方法
- 更改Web API应用程序,以便它将提供index.htm文件(用于测试我们的Web API)
- 设置一个简单的index.htm和main.js文件,我们用它来发布到Web API
- 配置XMLHttpRequest(XHR)以将JSON发布到Web API
我假设您已经在计算机上安装了Visual Studio或Visual Studio Code的最新副本。
当然,您还需要确保也安装了最新版本的.NET Core。如果需要,可以访问https://dotnet.microsoft.com/download^。
我在Ubuntu Linux上运行Visual Studio Code,因此我可以从命令行执行所有操作,但是如果您在Windows上运行并使用Visual Studio,则可以使用向导创建.NET Core Web API。.NET Core的命令行实际上并不难,您可能会发现它非常令人满意。
创建新项目首先,请执行以下步骤:
- 打开一个控制台(或终端)。
- 导航到要在其中创建新项目的目录。
- 输入以下命令: dotnet new webapi --name MainWebAPI
当您键入该命令并按时,它将创建一个名为MainWebAPI的新子文件夹,并将所有项目文件添加到该目录中。
如果成功,您将看到以下内容:
如果您收到某种无法识别该命令的错误,则可能您没有安装.NET Core SDK。要确定已安装的.NET版本,可以尝试以下命令:
dotnet --version
我的回答是3.1.202。
如果一切顺利,那么您就可以在.NET Core上运行一个非常基本的Web API。
运行Web API项目让我们确保项目可以编译并运行。很简单
首先,只需将目录更改为新创建的项目目录: cd MainWebAPI
接下来,键入: dotnet run
.NET将构建并启动Web API。
它看起来像以下内容:
顺便说一句,如果您只是想生成项目,则可以输入: dotnet build
实际使用中的Web API要查看Web API的功能,可以按住CTRL键并单击控制台窗口中显示的链接(https:// localhost:5001)。完成后,默认浏览器将打开该链接。
但这并不十分令人惊奇,因为您尚未调用任何Web API方法。
您只会看到一个空白网页。
一个通过Get的Web API方法但是,您可以通过GET调用一个方法。尝试以下URL:https://localhost:5001/WeatherForecast/^。
这将在WeatherForecastController*类上调用默认的Get方法。该方法只是生成一些随机的WeatherForecast *领域对象,然后将它们作为JSON发送给客户端。
*当我们看一下代码时,我将向您展示这两个类。
您将在浏览器中看到类似以下两个图像之一的图像(取决于浏览器呈现JSON的方式)。
现在您已经看到了代码的运行,让我们看一下代码并开始进行修改WeatherForecastController,以便我们可以向其发送JSON,并使它自动将JSON转换为领域对象。
Visual Studio Code在本文中,我将一直使用Visual Studio Code(VSC),但如果愿意,您仍然可以使用Visual Studio。
继续并启动Visual Studio Code(VSC),然后打开项目。
开启文件夹要在VSC中加载项目,请执行以下操作:
- 进入主菜单
- 选择[文件...]菜单项
- 选择[打开文件夹...]
- 导航到创建项目时创建的文件夹,然后选择它
当您按照这些步骤,您将看到类似以下内容:
我在VSC中强调了一些领域,因此我们可以讨论它们。
工具栏
第一部分是工具栏,其中包含一些图标。
文件视图
当前选定的图标以白色突出显示,并指示已显示“文件视图”。您可以看到在第二部分中有一个文件列表。但是,如果您选择其他图标之一,则此部分将更改。
调试视图
在本文中,我们还将使用“调试”项向您展示如何使用VSC逐步遍历Web API代码。调试项由指示。
但是,要在VSC中使用调试器,必须确保已安装并正在运行C#Extensions插件。
插件视图
插件视图由指示。
您可以看到我在上面提供的VSC概述图像的第4部分实际上是VSC,警告我需要将C#Extension插件添加到项目中,以便我们可以调试代码。如果看到该内容,然后单击[是]按钮,它将把它添加到项目中。但是,如果未将扩展名添加到系统中,则可能看不到。
同样,该弹出窗口往往会迅速消失。没关系,因为您可以单击“插件”图标,然后随时将插件添加到系统和项目中。
安装和激活后的外观如下:
主编辑区
最后,您可以看到主编辑区域(上面的VSC图像上的区域3)当前正在显示有关VSC当前版本的注释。从“文件查看器”区域中选择每个文件时,这里是将显示每个文件的区域。
现在您对VSC更加熟悉了,让我们开始看一下WeatherForecastController。
检查WeatherForecastController 在子目录中打开文件确保您在“文件视图”上。接下来,在文件视图中,找到Controllers目录。它将有一个向下的右箭头(大于号)指向Controllers名称。这表示当前已折叠的文件夹。单击Controllers文件夹,然后选择出现的WeatherForecaseController.cs,它将显示在编辑器区域中。
控制器:应用逻辑层我不会解释Controller代码的每个方面。您通常可以将控制器视为应用程序逻辑层。这是发生的事情的基础。
用户通过将HTTP命令(GET,POST,PUT等^)发送到服务器上的命名控制器(由URL描述)来请求控制器上的操作(功能或方法)。注意:在本文中,我们将仅处理POST命令。
作为开发人员,我们可以在Controller中使用运行提供特定功能的应用程序逻辑的方法编写代码。真的就是这么简单。
项目模板包含在Controller的Get方法如下所示:
[HttpGet]
public IEnumerable Get()
{
Console.WriteLine("in get...");
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
这可能很明显,但是[HttpGet]方法装饰器告诉编译器通过HTTP Get使此方法可用。
此方法仅生成五个WeatherForecast对象(领域对象)的数组并返回它们。它们将被自动序列化为JSON,这就是我们先前在浏览器中看到的。
我们的主要挑战这里的挑战是如何将数据发布到WeatherForecast Controller,以便将其自动反序列化为WeatherForecast对象。
首先,让我们向控制器添加最基本的Post方法。
[HttpPost]
public String Post(){
Console.WriteLine("in post...");
return "It worked!";
}
首先,请注意,我们将装饰器更改为 [HttpPost] ,以便在用户发布到URL http://localhost:5001/WeatherForecast时触发此方法。
此内部方法名称是Post(),但在外部没有显示任何操作(方法名称),因此,这意味着当用户直接发布到Controller时,这是将发生的默认操作(将运行的方法)。
有一种方法可以提供一个外部名称,然后可以在WeatherForecast控制器URL 上提供该名称,稍后我将向您展示。
次要挑战:客户端Post创建现在,我们面临着在WeatherForecast控制器上测试Post()方法的挑战。由于我们不再只能使用浏览器导航到URL(简单的HTTP Get),因此我们需要其他方法从客户端调用HTTP Post。
第一次最简单的Post测试Post对控制器执行操作的第一种,可能是最简单的方法是下载PostMan并设置它。还有其他工具,但PostMan可能是最简单的工具,并且是免费的。
转到https://www.postman.com/downloads/^,获得免费的实用程序并为您的系统安装它。
完成并启动后,我们可以尝试将其发布到我们的控制器。
Walkthru:PostMan请求PostMan用户界面有点混乱,但是创建一个新请求很容易,我将逐步引导您。
创建一个新请求您要做的第一件事是创建一个新请求。为此,您可以选择[新建(New)]按钮,然后在菜单出现时选择[请求(Request)]。或者,您可以单击[创建请求(Create a Request)]选项。在下一个图像中,这两个都以红色突出显示。
选择这些选项之一后,您将看到一个新表格。在图像中,您可以看到我还删除了HTTP操作列表,以向您显示可以在其中选择提交请求时使用的HTTP操作。首先,我们将尝试简单的Get。
但是,在我们发出第一个请求之前,您需要对PostMan默认设置进行一次更改。如果不这样做,则所有请求都将失败,因为PostMan不支持自签名证书。
如果不更改设置,则将看到类似以下的错误(请注意,蓝色突出显示的错误文本)。
HTTPS:不支持自签名证书要解决此问题,只需在PostMan中转到“文件 ... 设置 ...”,然后关闭以红色突出显示的选项(此处显示为打开状态)-SSL证书验证。
完成此操作并关闭“设置”窗口后,即可继续进行,它将起作用。
继续并从下拉列表中选择Get命令。
接下来,添加以下URL,然后按或单击[发送]按钮。
完成此操作后,您将看到与以前(在浏览器中)看到的结果类似的结果,但只是以PostMan格式化内容的方式进行了格式化。
请记住,这是在WeatherForecast控制器上调用默认Get()操作的结果。我提到这一点是为了提醒您,我们没有在URL上添加任何操作名称(特定)方法。
Post到WeatherForecastController现在,让我们简单地在PostMan中将HTTP Verb更改为Post,然后重试。
这是新的非常基本的结果:
一切都很好,但是我们要做的是将一些JSON发布到控制器,并使其自动将JSON转换为我们的领域对象(WeatherForecast)。
发布JSON:尝试1我们需要了解的第一件事是目标领域对象的外观。它有什么特性?
我们可以回顾一下VSC 中的WeatherForecast类。
WeatherForecast类分析这是一个非常简单的类。这是该类的完整代码清单。
using System;
namespace MainWebAPI
{
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string Summary { get; set; }
}
}
它实际上仅由四个属性组成(尽管其中一个确实运行函数来获取其值)。
- Date
- TemperatureC //(摄氏温度)
- TemperatureF //(以华氏温度计算)
- Summary //基于文本的天气摘要
由于我们知道JSON(JavaScript对象表示法)只是用于定义对象的名称值对,因此我们可以非常轻松地创建自己的WeatherForecast(带有数据)。这是我们将用于测试的一个。
{"Date":"2015-05-03", "TemperatureC":37,"Summary":"Our weather data"}
请注意,由于TemperatureF是从TemperatureC中计算得出的,因此我甚至没有在JSON中包含该属性。
方括号:Think Object——快速JSON摘要
这是考虑您在JSON中看到的内容的快速方法。大括号表示对象的开始和结束。冒号前面的每个值表示属性名称,冒号后面的每个值表示属性值。每个名称/值对用逗号分隔。每个属性名称必须与目标类中的一个属性匹配。
就是这样,所以让我们使用PostMan尝试一下。
更改WeatherForecastController Post方法我们必须在WeatherForecastController中的默认Post()方法中进行一项更改。我们必须确保它期望接收一个WeatherForecast对象。
让我们在VSC中打开WeatherForecastController并进行更改。
我们还将更改方法以返回Int32,然后返回TemperatureF,以便您可以看到生成的值。这也为我们提供了某种可用的Web API方法(尽管有些许作弊),因为您可以发送一个知道摄氏温度的WeatherForecast对象,并且该方法将以华氏温度返回温度。
这是更改后的默认Post()方法。
[HttpPost]
public Int32 Post(WeatherForecast wf){
Console.WriteLine("in post...");
return wf.TemperatureF;
}
进行更改并运行
进行了这些更改之后,请返回控制台并执行以下操作:
- 如果该程序已经在运行,则将其关闭(按CTRL-C结束会话)
- 再次构建并运行该应用程序——dotnet run将再次构建并运行该应用程序
- 复制我们在上面创建的JSON
- 回到PostMain
- 单击[body]选项卡(见下图)
- 选择[raw](下一个图像)单选按钮
- 将JSON粘贴到编辑器区域。
- 点击[发送]按钮。
完成所有这些步骤后,您将看到以下结果(错误)。注意:我使用一张图像来显示多个步骤和结果。
这有点令人困惑,但是最下面的部分是将我们的JSON发布到Controller之后的结果。我们没有得到预期的响应(TemperatureF),但是得到了描述问题的JSON。很难说一个错误甚至发生在哪里。
Console.WriteLine的Post()方法无法运行请记住,我们的默认WeatherForecastController有一个Console.WriteLine()调用来尝试输出消息。这应该在运行应用程序的控制台窗口中输出一些文本,但是如果您查看的话,将没有输出。这为我们提供了一个线索,即我们的方法从未运行过。
不支持的媒体类型
发生错误的真正线索是错误415和消息“不支持的媒体类型”。但是,它仍然是一个神秘的事物,如果您刚刚开始,那么您真的会想知道这意味着什么。经过大量搜索和阅读之后,您会发现这意味着服务器不知道我们要向其发布什么类型的数据,并且也不喜欢这样。
使用HTTP标头解决问题
通过在Post操作中添加HTTP标头,我们可以告诉服务器正在发送的数据类型。
服务器想知道您要发送的数据类型,以便可以正确使用数据。让我们将适当的HTTP标头添加到PostMan Post操作中,然后重试。
HTTP标头:名称/值对
HTTP标头是与数据一起发送的元数据(与实际数据一起发送的数据,用于描述数据)。要将名称/值对添加到PostMan标头中,我们只需要:
- 选择“标题”标签(请参见下图)
- 添加一个名为:Content-Type的新标题(在Key(与Name相同)下的列表中键入)
- 为添加的键添加一个新值: application/json
该Key和value都是服务器将理解的HTTP规范描述的预定义值。
现在,当您再次发布时,服务器将理解传入的内容是JSON,应将其作为JSON处理。
完成这些更改后,继续并再次单击PostMan中的[发送]按钮,这一次,您将获得有效的结果。98华氏温度与37摄氏度(我们在JSON中发送WeatherForecastController的值)相同。
您还可以说WeatherForecastController Post()方法确实运行了,因为回到控制台窗口,对Console.WriteLine()的调用有一些输出:
另外,请考虑一下底层的.NET Core Web API将我们的JSON自动转换为我们的域对象(WeatherForecast)的惊人程度。
您可以说它是自动完成的,因为我们的默认Post()方法只接受类型WeatherForecast参数,并且我们在return语句中引用了对象的属性:
return wf.TemperatureF;
总结第1部分
我希望您能从本系列文章的第1部分中获得指导,并以一种清晰的方式揭示了一些棘手的元素(HTTP标头,HTTP Post和使用PostMan)。
但是,由于本文已经很长了,因此我决定将本文的其余部分放在第2部分中。
现在我们知道我们需要...
- JSON数据已添加到Post正文
- 特殊Content-Type Header添加到Post操作中
...这将使我们更容易理解如何通过JavaScript 使用AJAX(XMLHttpRequest对象)将数据发布到我们的Web API控制器。
使用代码- 下载压缩文件。
- 解压缩到Dev目录(有一个名为MainWebAPI的外部文件夹,其中包含所有文件和子文件夹)。
- 打开控制台并将目录更改为\MainWebAPI。
- 运行命令/> dotnet run。
- 该应用程序将构建并启动Web服务器。