.NET Core Web API:您需要了解的最少知识(第2部分,共2部分)

目录

介绍

在第一篇文章中

添加SubFolder和index.htm

HTML的四个要点

dotnet run:启动您的Web服务器

客户端代码和服务器代码(Web API)

更改Web API以服务静态页面

更改Startup.cs

在JavaScript中配置XHR

用户通过单击按钮开始该过程

PostData()方法:逐行

yyyy-mm-dd日期格式

第9行

第11行:JSON对象

第12行:将值明确转换为数字

设置请求头

XHR发送

TransferCompleted()逐行

XHR响应属性

过程概述


介绍

这是由两部分组成的文章系列的第二部分,也是最后一部分。 

您可以从以下网站阅读第一部分:.NET Core Web API:您需要了解的最少知识(第1部分,共2部分)

在本文中,我们将介绍:

  1. 创建用于向WeatherForecastController提交Post的基本HTML页面
  2. 更改dotnet Web API以返回静态页面(服务HTML)。
  3. 基本的JavaScript,它将包含创建XmlHttpRequestXHR)的代码
  4. 配置XHR以在正文和适当的标头(header)中发布数据。

在第一篇文章中

在第一篇文章中,我们创建了基本的Web API模板项目,并学习了如何使用PostMan ^将其post到该项目。 

现在,我们将在此学到的所有知识应用到创建一个可以将JSON post到我们的Web API的网页上。

让我们直接进入并创建我们的HTML页面,该页面将用于post到我们的Web控制器。

添加SubFolderindex.htm

我要做的第一件事是将一个新的子文件夹添加到名为wwwroot的项目中。我要添加该文件夹名称,因为它是我可以在其中部署Web API的托管网站上将文件部署到的文件夹的名称。

您还将看到dotnet运行的默认服务器将自动了解wwwroot并直接从该目录提供index.htm文件。

接下来,我添加一个名为index.htm的新文件,并添加基本HTML,它将为我们提供一个按钮,我们可以单击该按钮以将帖子提交到Web API

这是整个HTML文件。非常简单,请记住,整个示例都使用普通JavaScript(不需要外部JavaScript库),因此所有代码都非常简单。

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>XHR Poster</title>
        <meta charset="utf-8">
        <script src="main.js"></script>
        <style>
            body{padding: 5px 15px 5px 15px;}
        </style>
    </head>
    <body>
        <label for="tempC">Temp (C)</label>
        <input id="tempC" type="number" value="20">
        <button onclick="postData()">Post TempC</button><br>
        <label for="tempF">Temp (F)</label>
        <input id="tempF" type="text">
    </body>
</html>

该页面在浏览器中呈现以下内容。

HTML的四个要点

由于它是不言自明的,因此我不会解释所有的HTML,但我将指出四点要注意的事项:

  1. 顶部加载的main.js包含我们所有提供所需功能的JavaScript代码
  2. 有一个number输入,允许用户设置发布到Web APITempC 值(以摄氏度表示值)
  3. 文本输入显示Web API返回的TemperatureF 输出值(以华氏表示)
  4. 通过单击调用在main.js中找到的JavaScript方法postData()的按钮来触发页面的功能。

如果您要继续,请立即将main.js文件添加到/ wwwroot文件夹。这是我的Visual Studio CodeVSCIDE(集成开发环境)中所有文件的外观快照。

如果仔细观察,您会发现/wwwroot目录包含两个文件(index.htmmain.js)。

dotnet run:启动您的Web服务器

让我们运行dotnet,以便它再次编译Web API并为我们启动Web服务器,以便我们尝试将其提供给index.htm文件。这会导致错误,但会有所启发。

要启动Web API,请进入您的控制台窗口(所有这些都在本系列的第1部分中进行了详细介绍),然后输入以下命令:

$>dotnet run

这样做时,服务器将在默认主机和端口(localhost:5001)上启动,因此我们可以尝试加载index.htm

客户端代码和服务器代码(Web API

请记住,现在我们的项目包含客户端代码(index.htmmain.js)和服务器代码(用C#编写)。但是,dotnet引擎基本上会忽略我们的HTMLJavaScript。它知道不需要编译该代码,而只需要使用找到的C#代码即可。但是dotnet要做的另一件事是为您启动一个不错的Web服务器。

尝试加载index.htm

试试这个URL,看看是否加载了index.htm https://localhost:5001/index.htm

这就是您所看到的。这是一个完全空白的页面。

您的第一个想法可能是您需要更改URL以包括以下子目录/wwwroot,如https://localhost:5001/wwwroot/index.htm

我想也许是我尝试解决此问题时遇到的问题。

您可能还认为其中至少有一些框架HTML,但我向您保证没有。当您点击该URLWeb API不存在)时,服务器将不响应。 

如果您是第一次尝试,可能会造成混淆,因为您可能认为其他问题。搜索也是一个非常困难的问题,因为没有错误值或错误消息。

问题在于Web API未设置为提供静态网页,例如index.htm。让我们改变它。

更改Web API以服务静态页面

默认情况下,Web API项目将不会提供静态页面,例如index.htm。这可能很有意义,因为这是我们正在创建的Web API。但是,如果您希望能够测试Web API而不遇到CORS(跨原始资源共享)的各种麻烦,那么很高兴知道如何更改Web API,这非常容易。

更改Startup.cs

为此,我们只需要打开Startup.cs并添加一个新服务即可开始在dotnet应用程序上运行。

当您打开Startup.cs并查看Configure()方法的内部时,您将看到已经加载了许多服务。在更改代码之前,它将类似于以下内容:

// This method gets called by the runtime. 
// Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
 
            app.UseHttpsRedirection();
 
            app.UseRouting();
 
            app.UseAuthorization();
 
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

您可以看到项目模板已经添加了许多服务,可以开始在app对象上运行。这些服务提供某些功能,例如路由(UseRouting())和HttpsRedirection()等。

我们只需要添加一行代码即可添加静态页面服务。

让我们在具有以下内容的当前行之后添加一行:

app.UseAuthorization();

我们的新代码行将是:

app.UseStaticFiles();

VSC中看起来像这样:

进行更改后,返回控制台并停止Web APICTRL-C),然后通过 $> dotnet run重新启动。

现在,我们可以再次尝试该URL,然后该页面将正确投放:

https://localhost:5001/index.htm^

这样更好

现在,我们开始尝试一些JavaScript代码。但是现在我们需要使用XmlHttpRequestXHR)来使JavaScript正确无误。我们将在main.js文件中完成所有这些工作。

JavaScript中配置XHR

我们需要做四件事:

  1. 实例化内置的(JavaScript/Browser提供的XHR对象)
  2. 在异步请求完成时将事件侦听器添加到XHR对象(加载事件)
  3. 将事件侦听器添加到XHR对象,如果发生错误它将运行
  4. 添加一个变量来保存我们将发布到的URL

这是我放在main.js顶部的四行代码

var xhr = new XMLHttpRequest();
xhr.addEventListener("load", transferComplete);
xhr.addEventListener("error", transferFailed);
var url = "http://localhost:5001/WeatherForecast/"

XHR对象load事件发生时,它将调用一个名为transferComplete()方法,该方法将在JavaScript代码中进一步定义。

如果发生XHR对象error事件,则它将调用一个名为transferFailed()方法,该方法将在我们的JavaScript代码中进一步定义。

用户通过单击按钮开始该过程

稍后我将向您展示这两种方法,但首先让我们看一下用户单击[TempC]按钮时触发的代码。

请记住,我们在HTML中连接了按钮,以便οnclick="postData()"。该方法在我们的main.js JavaScript中定义。

这是VSC中带有行号的整个方法,因此我们可以讨论正在发生的事情。

PostData()方法:逐行

由于我们已经实例化了xhr对象并设置了url,因此我们现在只需要调用xhr对象的open()方法。

我们为open()方法提供了两个参数。

  1. HTTP操作(Get)作为字符串
  2. 我们发布到的URL

yyyy-mm-dd日期格式

在第8行,我们设置一个局部变量来容纳日期string。请注意,此日期的格式为yyyy-mm-dd

如果使用其他格式,则Web API可能无法在服务器端将字符串转换为日期,并且可能会失败。 

9

我们调用浏览器方法document.querySelector()以获取对数字输入控件的引用并获取其当前值。这样,用户可以动态更改值以将不同的值提交到Web API。我们将当前值存储在局部变量中以备后用。

10行只是浏览器控制台的console.log(),因此我们可以看到发生了什么。

11行:JSON对象

在第11行,我们创建了一个名为weather的新变量,并使用JSON值对其进行了初始化。JSON中的每个名称都将成为本地weather对象的属性。我这样做是因为它使将JSON发布到Web API变得容易得多。当然,weather 对象中的每个属性名称都与我们的WeatherForecast 域对象中的属性名称匹配(在Web API中的C#中定义-有关更多信息,请参见本文的第1部分)。

12行:将值明确转换为数字

在第12行中,我将一个新属性TemperatureC添加到已经创建的天气对象中。JavaScript是一种动态语言,并允许对其对象进行这种类型的操作。只需在对象上引用新属性并将其设置为值,就可以动态添加新属性。我添加此属性名称(TemperatureC),因为这是Web API端域对象上的预期名称。

请注意,我还明确地将局部变量tempC值(它是一个字符串)转换为JavaScript Number类型(它是Double-数字高精度)。那是因为我发现,由于Web API期望这样Int32TemperatureC,因此如果将值作为字符串输入(似乎没有Int32JSON对象的字符串自动转换为)似乎失败了。

13行是另一个console.log()仅用于检查Date属性的格式的行。

设置请求头

在第14行上,我们必须在XHR对象上设置Content-Type请求标头,否则Web API将失败并出现415错误,就像我们使用PostMan发布到URL一样(请参见第1部分)。

XHR发送

最后,在第15行,我们调用XHR send()方法,该方法实际上将发布到Web API URL

但是,我们要发布表示天气对象的JSON字符串,然后调用内置的浏览器方法JSON.stringify(),该方法将天气对象转换为适当的JSON字符串。

但是,这只是使Web API WeatherForecastController默认Post方法启动的请求。当请求完成并且我们的JavaScript代码被警告加载事件已触发时,我们需要做一些工作。这就是我们前面绑定的事件处理程序起作用的地方。

TransferCompleted()逐行

transferCompleted()是我们定义的极其简单的方法,并在XHR对象的load事件触发时运行。 

前两行仅输出到浏览器控制台,因此我们可以看到Web API返回的内容。现在,我们使用Web API 的默认Post()方法返回华氏温度,该温度代表我们发布到该方法的摄氏温度(更多信息,请参见第1部分)。

XHR响应属性

xhr对象的response属性包含Web API返回的数据。在我们的例子中,这只是代表华氏温度的整数值。通常,您将返回一个完整的JSON对象,该对象表示比这还复杂的东西,但是对于我们的测试,我们只返回整数值。

在第21行,我们仅使用document.querySelector() 方法来获取对tempF 文本控件的引用,并将其值设置为Web API返回的值(xhr.response)。

过程概述

现在,当用户在数字控件中选择一个值并单击按钮时,将调用Web API,并返回相关的华氏温度并将其显示在tempF文本框中。

这一切都可以,因为我们使用以下命令正确设置了XHR对象:

  1. 正确的网址
  2. 正确的Content-Type标头
  3. 正确的JSON(代表WeatherForecast领域对象)

如果您发现其中任何一个不正确,都会在浏览器控制台中看到一个非常基本的错误,让您知道出了点问题。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章