Razor Page–Asp.Net Core 2.0新功能

來源:互聯網
上載者:User

標籤:test   傳統   visual   微服務   ide   視圖   檔案名稱   dir   使用   

Razor Page介紹前言

    上周期待已久的Asp.Net Core 2.0提前發布了,一下子Net圈熱鬧了起來,2.0帶來了很多新的特性和新的功能,其中Razor Page引起我的關注清單,作為web程式員來說,Asp.Net下的任何web架構都會去特別關注,因為每次一個新的架構出來,意味著一次革命。此次的Razor Page是否能帶來不一樣的體驗呢,讓我們一起來看看吧。

什麼是Razor Page

    我們都知道在Asp.Net MVC中,Razor是其一種視圖引擎。而今天我們介紹的Razor Page卻是一種web架構,它是一種簡化的MVC架構,如果你曾經做過WebForm的開發人員,你會發現,Razor Page有點類似Web Form,一個page,一個class。

    大家或許會有疑惑,我們現在Asp.Net MVC已經很完善了,為何還需要出來一種新型的架構呢?在我看來,MVC確實已經足夠強大了,只是因為太強大了,卻變成了它的缺點。當我們的業務越來越龐大的時候,你是否覺得你的一個Controller內部已經淩亂不堪?當我們業務模組劃分越多的時候,你是否會為你的Model建立而頭疼呢?當我們建立一個新的View的時候,我們需要在MVC層增加1個View,1個Model,修改一個Controller,每當這個時候,我都會疑惑這不是違反Open-Closed Principle(對擴充開放,對修改關閉)了嘛!這個時候我會想起以前的webform,現在不需要了,我們有了Razor Page,一種更輕量級的MVC(我覺得更像MVVM)。

如何建立Razor Page

我們可以通過多種方式來建立Razor Page項目,最簡單的就是利用dotnet命令方式,當然我還是建議您使用Visual Studio 2017(宇宙最強的IDE)。要建立Razor Page,你需要先安裝.Net Core 2.0 SDK,如果要使用VS2017來建立,您還必須要更新到15.3版本以上

dotnet命令方式建立

開啟cmd或者powershell工具,先檢查下你的dotnet 版本是否為2.0.0

dotnet –version

先通過命令,到你需要建立項目的目錄,我這裡為E盤下demos目錄:cd e:\demos\RazorPageDemo1

dotnet new razor

輸入以上命令,你就已經建立了razorPage的項目了,這裡說一下dotnet 2.0預設是自動restore的,你也可以通過--no-restore選項關閉。我們直接通過命令dotnet run 可以直接運行,看到的頁面應該跟之前mvc建立的類似。

輸入dir,我們看下產生了哪些:

跟之前mvc不同的是,我們不再看到model,view,controller目錄了,取而代之的是Pages目錄,這個就是我們的razor Page的主要工作目錄。

Visual Studio 2017建立Razor Page

用Visual Studio 2017建立是非常方便的(宇宙最強IDE),不過我們必須要先升級到15.3,升級之後選擇建立項目->.Net Core –> Asp.Net Core Web應用程式,接下來會彈出一個對話方塊,讓我們選擇模板類型:

多了好多模板,好興奮啊!我們在這裡無法找到Razor Page,那是因為Razor Page已經變成預設的【Web應用程式模板】了,而傳統的MVC方式已經變成【Web應用程式(模型視圖控制器)】。選擇【Web應用程式模板】,點擊確定我們就完成建立了,通過Solution Explore,我們可以看到:

與命令方式建立的一致。

QuickStart Razor PageHello Razor Page

通過上節我們建立了Razor Page項目,直接通過dotnet run或者在vs中F5運行。上文中我們說到,Razor Page的項目中,我們的關注點都在Pages目錄下,在VS Explore中,我們看到在Index.cshtml的左邊有一個三角箭頭,點擊就會看到Index.cshtml.cs檔案,是不是感覺回到了webform。我們看下代碼:

public class IndexModel : PageModel{    public void OnGet()    {    }}

因為我們的Index頁面沒有綁定任何資料,所以這裡基本上只繼承了PageModel,OnGet方法是個約定,查看mvc的源碼你會發現它會擷取On{handler}{Async}()。比如OnGet,它會在Get Index的時候被執行,我們可以通過這個約定進行資料繫結,這裡知道下在Razor Page下HttpMethod也是一個handler,所以Razor Page的處理方式是通過handler進行的。

舉個例子,我們在IndexModel中添加一個String類型的屬性Message,在OnGet中進行賦值:

public void OnGet(){    Message = "this is a test!";}

然後我們修改下Index.csthml:

@page@model IndexModel@{    ViewData["Title"] = "Home page";}<div class="row">   Message : @Model.Message</div>

運行下,如果我們在頁面上看到Message : this is a test!,說明賦值成功。

是不是很方便,一般我們的web基本上百分之八十在Get和Post,特別情況會出現其他HttpMethod,當然我們的RazorPage也支援,不過不建議。

現在來說PageModel就是一個Model,Action,HttpMethod的合體,對於Controller使用檔案自己的路徑+檔案名稱的方式,比如原先我們的HomeController,預設情況下我們可以通過’/’訪問也可以通過’/Home/’ 訪問,這其實有歧義的,為了避免這種情況,我們必須去修改Route,非常不方便,而現在,我們只需要在Pages主目錄下建立相應的Action就可以了,微軟提供了Razor Page的對應Url關係,

快速自訂Routing

你是否會問現在還支援/Controller/Action/ID 嗎?

支援,不過你需要在cshtml頁面上,通過@page設定路由

@page "{parameter:type?}"

例如 /Address/Province/City  我們只需要在Address/Index.cshtml頁面上加入如下:

@page "{Province}/{City?}"

問號代表選擇性參數。這樣的好處就是我們不需要在RegisterRoute的時候去填寫規則了,是不是很棒!

那像原來我們在一個Controller中,有Get()和Get(id)表示擷取列表和擷取單個Item,那在Razor Page中如何運用呢?

抱歉,目前我沒有找到最佳的解決方案,原本我打算在@page "~/user/{id:int}",但是測試結果發現不支援,因為我們的page對應到url也是一個目錄,@page route的時候它不會識別絕對路徑和相對路徑,它只會在當前路徑後面添加映射,也就是說我們的url變成了/users/user/{id},目前最佳的解決方式是建立兩個目錄,如下:


模型繫結

在Razor Page中,資料繫結是非常簡單的, 您只要在需要綁定的屬性上添加[BindProperty]特性即可。

public class IndexModel : PageModel{        public string Message { get; set; }    [BindProperty]    public User TestUser { get; set; }}public class User{    public Guid UserID { get; set; }    public  string Name { get; set; }}

預設情況模型繫結不支援Get方法,你需要使用[BindProperty(SupportsGet=true)]

TempData 臨時資料

TempData是Asp.Net Core 2.0新增的特性,你只需要在PageModel中的屬性上加上TempData特性即可。加上TempData特性的屬性,會在你跳轉路由或者頁面的時候隱性的傳遞過去。

什麼意思呢?比如當你建立一個使用者的時候,你會希望跳回使用者列表頁,並在使用者列表頁提示添加成功的資訊,這時候你可以通過在Message屬性上加上[TempData]特性,引用下微軟Docs的例子:

public class CreateDotModel : PageModel{    [TempData]    public string Message { get; set; }    [BindProperty]    public Customer Customer { get; set; }    public async Task<IActionResult> OnPostAsync()    {        if (!ModelState.IsValid)        {            return Page();        }        //todo create a new customer        Message = $"Customer {Customer.Name} added";        return RedirectToPage("./Index");    }}

跳轉到Index後,我們的IndexModel的Message屬性(需要同樣設定TempData特性)就會被賦值。有點類似於之前的model傳遞,但又不一樣,感覺棒棒噠!

遇到的一些問題

Q:自訂routing的時候,無法支援絕對路徑和相對路徑

A:應該可以通過重寫某個介面達到目的,稍後我會看下

Q:不支援多個handler在同一個pageModel中,比如OnGet, OnGetAsync不能在同一個PageModel中

A:可以通過自己重寫IPageHandlerMethodSelector介面,然後註冊到service中應該可以解決。

Q:用VS2017建立新的Page的時候,會在頁面上顯示紅線

A:關閉頁面再開啟。。。。

寫在最後

    最近工作有點忙,Core2.0的出現使Net圈沸騰了,RazorPage的出現更是讓我們這種web開發人員為之振奮,今天介紹的有限,畢竟也是剛出來的東西。個人覺得Razor Page還是非常棒的,雖然還有些問題,如果遇到Razor Page無法解決的事情,請大家結合MVC,國外有大神就是這麼做的,但我相信不久之後,Razor Page會瘋狂出現在我們面前,特別是對於微服務架構來說,簡單和快速是微服務的重要所在。

    最後推薦下自己的.Net Core學習群:376248054

Razor Page–Asp.Net Core 2.0新功能

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.