iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 18
1
Modern Web

打net core肉飯系列 第 18

[2020鐵人賽] Day18 - Model Binding(1/2)

  • 分享至 

  • twitterImage
  •  

這邊來介紹一下MVC中參數傳遞的方式,主要會透過Model Binder來完成傳遞,Model Binder主要是用於將HTTP request資料對應到controller/Action去。

參數,可以是各種型別,例如string、integer,或是class、list、array也可以。
在.net core MVC架構下Model Binding主要是在startup.cs中設定,之前也有提到,程式碼如下

app.UseMvc(routes =>routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"));

簡單傳遞參數
例如,今天的網址為http://www.IronMan.com/Home/Index/999
參數就會如下傳遞

    public class HomeController : Controller
    {
        public IActionResult Index([FromRoute]string id)
        {
            ViewBag.result = id;
            return View();
        }
    }

接著,我們來使用form傳遞資料到剛剛的controller看看,程式碼如下:


@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <h1>Home</h1>
    <form action="~/home/index" method="post">
        <input type="text" name="id" value="999" />
        <input type="submit" value="post" />
    </form>
    <h3>Result:@ViewBag.result</h3>
</body>
</html>

Model Binder傳遞方式
預設的傳遞方式可能不符合需求,這邊有提供內建的Attribute來指定傳遞方式,主要有下列幾種:

  1. Header,Request
  2. Query,Form,Route
  3. FormBody

Header:主要是從HTTP Header去Binding,程式碼如下,我們在傳遞參數放上[FromHeader]的attribute

    public class HomeController : Controller
    {
        public IActionResult Index([FromHeader]string test1,[FromHeader] string test2)
        {
            return View();
        }
    }

也可以用class接起來,class的property也可以放上FromHeader的attribute

    public class Headers
    {
        [FromHeader]
        public string test1 { get; set; }

        [FromHeader]
        public string  test2 { get; set; }
    }

複雜資料型別:主要是使用form post,controller的Action會用類別(class)給接起來,而不用一個一個傳遞
Model如下

namespace IronMan.Models
{
    public class IronMan
    {
        [Display(Name = "Id")]
        public int Id { get; set; }
        [Display(Name = "Name")]
        public string Name { get; set; }
        [Display(Name = "Birth Date")]
        [DataType(DataType.Date)]
        public DateTime BirthDate { get; set; }
    }

}

View如下,這邊使用tag helper對應資料,其中會指定到對應的Action,Controller沒寫預設導到HomeController

@model IronMan.Models.IronMan

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>AddNew</title>
</head>
<body>
<div class="row">
    <div class="col-md-4">
        <form asp-action="AddNew">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Id" class="control-label"></label>
                <input asp-for="Id" class="form-control" />
                <span asp-validation-for="Id" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="BirthDate" class="control-label"></label>
                <input asp-for="BirthDate" class="form-control" />
                <span asp-validation-for="BirthDate" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="AddNew" class="btn btn-default" />
            </div>
        </form>
    </div>
</div>
<pre>@ViewBag.result</pre>
<div>
    <a asp-action="Index">Back to List</a>
</div>
</body>
</html>

Controller如下,AddNew action接收前端form post的資料

 public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
        [HttpPost]
        public IActionResult AddNew(IronMan model)
        {
            ViewBag.result = $@"
      IronMan id : {model.Id}
      IronMan Name : {model.Name}
      IronMan Birth Date : {model.BirthDate}
      ";

            return View();
        }
    }

使用class接資料算是MVC架構下常見的方式,也會比一個一個參數傳遞來的好

參考資料
https://docs.microsoft.com/zh-tw/aspnet/core/web-api/advanced/formatting?view=aspnetcore-3.1


上一篇
[2020鐵人賽] Day17 - 使用Layout
下一篇
[2020鐵人賽] Day19 - Model Binding(2/2)
系列文
打net core肉飯30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言