讓 Razor Pages 模仿 WebAPI 一樣用 HTTP GET 回傳 JSON 資料

栏目: 后端 · 前端 · 发布时间: 5年前

内容简介:因為有一次我只想做一個很簡單的頁面,但有些功能還是要透過 JavaScript 來做比較方便,又不想另外做一個 WebAPI,加上還是想保留前後端分離的架構,因此想要模擬一個 Web API 的 GET 動作來做資料處理層,所以有了這篇實驗。首先開啟 Visual Studio 選擇 ASP.NET Core Web 應用程式來建立傳案,這會是一個 Razor Pages 專案。

Razor Pages 是 ASP.NET Core MVC 的一部分,他讓撰寫網頁變得非常簡單,你不用管太多關於 MVC 架構上的事情,專注在頁面的編寫即可,相當具有生產力。如果你想透過 Razor Pages 簡單使用 HTTP GET 呼叫並回傳的 JSON 資料,像是 Web API 那樣,這時因為 Razor Pages 背後其實是 MVC 的架構,因此你也可以很簡單的實現這件事。

因為有一次我只想做一個很簡單的頁面,但有些功能還是要透過 JavaScript 來做比較方便,又不想另外做一個 WebAPI,加上還是想保留前後端分離的架構,因此想要模擬一個 Web API 的 GET 動作來做資料處理層,所以有了這篇實驗。

建立專案

首先開啟 Visual Studio 選擇 ASP.NET Core Web 應用程式來建立傳案,這會是一個 Razor Pages 專案。

讓 Razor Pages 模仿 WebAPI 一樣用 HTTP GET 回傳 JSON 資料

因為 Razor Pages 預設在執行階段會從 Pages 資料夾中尋找 Razor Pages 的檔案,所以你可以把 Pages 看作網站的根目錄,例如 Pages/Index.cshtml 這個專案路徑,相當於網站的 /Index 網址路徑。

建立 API

為了將 API 的網址端點和網頁的區分開來,可以在 Pages 資料夾下建立一個 API 資料夾,之後我們用 Razor Pages 做的回傳 JSON 資料的 API 端點就會放在這裡。

讓 Razor Pages 模仿 WebAPI 一樣用 HTTP GET 回傳 JSON 資料

再來我們簡單建立一個 UserInfoModel 資料模型。

public class UserInfoModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

接著我們在 API 資料夾下使用 Scaffold 快速產生 Razor Pages 檔案,並取名叫做 User ,這裡要注意因為我們要做的是回傳 JSON 資料,因此不需要使用共用的 Layout Page,所以建立 Razor Pages 的時候不要勾選 使用 Layout Page

讓 Razor Pages 模仿 WebAPI 一樣用 HTTP GET 回傳 JSON 資料

讓 Razor Pages 模仿 WebAPI 一樣用 HTTP GET 回傳 JSON 資料

讓 Razor Pages 模仿 WebAPI 一樣用 HTTP GET 回傳 JSON 資料

這時 Scaffold 會幫你建立兩個檔案 User.cshtmlUser.cshtml.cs ,這兩個檔案是一組的,也就是我們常說的 Code Behind 方式。

基本上 User.cshtml 我們完全不需要動他,因為對 JSON 資料來說只是個端點的殼而已,完全用不到。

Razor Pages 使用習慣取代配置的方式來命名執行方法,我們常見的 HTTP GET 和 POST 動作,對應到 Razor Pages 來說就是下面這四種:

OnGet
OnPost
OnGetAsync
OnPostAsync

HTTP GET 動作

這裡我們先使用 OnGet 來製作呼叫 HTTP GET 動作時的回應,程式碼如下:

public class UserModel : PageModel
{
    public IActionResult OnGet()
    {
        var userInfoList = new List<UserInfoModel>
        {
            new UserInfoModel{ Id = 1, Name = "Poy Chang", Email = "poy@mail.com"},
            new UserInfoModel{ Id = 2, Name = "foo", Email = "foo@mail.com"},
            new UserInfoModel{ Id = 3, Name = "bar", Email = "bar@mail.com"}
        };

        return new JsonResult(userInfoList);
    }
}

如果你有用過 ASP.NET MVC 可以發現這個方法的回傳型別是熟悉的 IActionResult ,藉此我們可以使用 MVC 內建的 JsonResult 來幫我們把物件序列化成 JSON 格式,這樣就輕鬆完成 HTTP GET 動作並取得 JSON 資料了,呼叫 /API/User 的執行畫面結果如下圖。

讓 Razor Pages 模仿 WebAPI 一樣用 HTTP GET 回傳 JSON 資料

@page “{name?}”

我們可以透過 Model Binding 的方式將 URL 的 QueryString 當參數傳入,例如下面程式碼可以只回傳指定 Name 的資料:

public class UserModel : PageModel
{
    public IActionResult OnGet(string name)
    {
        var userInfoList = new List<UserInfoModel> { /* 略 */};

        return new JsonResult(userInfoList.Where(p => p.Name == name));
    }
}

如果你不想要使用 QueryString 的方式,想透過路由參數的方式來做了話,你可以將 User.cshtml@page 改成 @page "{name?}" ,透過設定 name? 可以直接將原本的 /API/User?name=foo 查詢方式,變成 /API/User/foo 來操作。

參考完整範例程式碼 poychang/Demo-Razor-Pages-Json-API 中的 UserWithRouteParam

如果想用此方法接多個路由參數,可以用 @page "{name?}/{id?}" 這樣的設定方式,就可以使用像 /API/User/foo/3 這樣的方式來呼叫。

HTTP POST 動作

那我們可以如法炮製做 HTTP POST 的動作嗎?結果是不行的。

Razor Pages 主要在處理頁面的呈現,而不是提供資料服務,因此上面同樣的處理方式,是不能用在 OnPost 中的。

但我們知道 Razor Pages 是架構在 MVC 之下,所以 MVC 能做的我們還是可以做,例如使用 Controller 類別來建立對應的功能,程式碼如下:

[Produces("application/json")]
[Route("api/user2")]
public class UserController : Controller
{
    private readonly List<UserInfoModel> _data = new List<UserInfoModel>
    {
        new UserInfoModel{ Id = 1, Name = "Poy Chang", Email = "poy@mail.com"},
        new UserInfoModel{ Id = 2, Name = "foo2", Email = "foo@mail.com"},
        new UserInfoModel{ Id = 3, Name = "bar2", Email = "bar@mail.com"}
    };

    [HttpGet]
    public IActionResult GetData()
    {
        return new JsonResult(_data);
    }

    [HttpPost]
    public IActionResult PostData()
    {
        return new JsonResult(_data);
    }
}

這裡要注意的是,Razor Pages 和 MVC 的路由不能相衝突,所以上面的程式碼中,路由是指定成 [Route("api/user2")] ,和 Razor Pages 的區分開,如果兩者有相同路由了話,是會 404 的唷!

如此一來,可以玩的事情是不是瞬間多了起來,所以即使我們的專案是用 Razor Pages 來開發,和骨子裡還是可以透過 MVC 來實作一些功能。

雖然有一點本末倒置,畢竟 Razor Pages 就是設計給專注在頁面而非複雜架構下的框架,但是靈活運用,才是克敵致勝的關鍵呀 :)

本篇完整範例程式碼請參考 poychang/Demo-Razor-Pages-Json-API

參考資料:


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数学世纪

数学世纪

皮耶尔乔治·奥迪弗雷迪 / 胡作玄、胡俊美、于金青 / 上海科学技术出版社 / 2012-1 / 28.00元

《数学世纪:过去100年间30个重大问题》以简短可读的方式论述了整个20世纪的数学。20世纪的数学博大精深,新兴领域及学科的建立发展,许多经典问题得到解决,大量新的有意义的问题的引入,为数学带来了活力。《数学世纪:过去100年间30个重大问题》介绍了数学基础,20世纪的纯粹数学、应用和计算数学,以及目前未解的重要问题,中间穿插了希尔伯特的23个问题的解决情况、菲尔兹奖和沃尔夫奖得主的工作成就等。一起来看看 《数学世纪》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

URL 编码/解码
URL 编码/解码

URL 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试