.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領域對象)

如果您發現其中任何一個不正確,都會在瀏覽器控制檯中看到一個非常基本的錯誤,讓您知道出了點問題。

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