※以下內容純屬本人理解,如果有誤歡迎指出
.NET 如果要從View把Model Post Back回Controller,並且自動Bind Model的值,只能使用一開始導入的Model (在純使用Razor的情況下也就是一開始使用 @model 指定的模型
而接收Post的Controller參數也必須放入該Model才能進行綁定
Post需透過表單(Form)的方式進行,在表單中使用Input指定要傳回Controller的參數
使用asp-action可以指定該參數為模型的哪個值,沒有使用input的部分不會有值
如果只需要Post值回去而不要讓使用者輸入的話可以善用hidden,像是
<input value="@Model.Id" hidden/> |
只要是想要Post回Controller的Model都必須包在ViewModel裡面
舉例:一個文章的View會顯示「作者、日期、文章內文、留言」,而輸入留言也會在同一個頁面中進行,所以ViewModel會長這樣
public class ArticleViewModel{ public int Id { get; set; } public string PosterName { get; set; } public string Content { get; set; } public DateTime PublishTime { get; set; } public List<MessageModel> Messages { get; set; } public MessageModel NewMessage { get; set; } } |
假設MessageModel的資料如下
public class MessageModel{ public int Id{ get; set; } public int PosterId{ get; set; } public string PosterName{ get; set; } public string Message{ get; set; } public DateTime PublishTime{ get; set; } } |
View如下
<form asp-action="AddMessage" method="post" enctype="multipart/form-data"> <textarea asp-for="NewMessage.Message" type="text" class="form-control" placeholder="Enter message"></textarea> <button class="btn btn-success" type="submit">submit</button> </form> |
順便放一下Controller,主要是參數要放對其他沒甚麼問題
[HttpPost] public IActionResult AddMessage(ArticleViewModel _model){ //新增邏輯 return RedirectToAction("Index"); } |
一些實作中遇到的Error
1.要拿來給實作表單的ViewModel,一定要使用Property而不是Field
還沒有深入去研究,但如果使用Field丟回Controller的時候會是null
養成使用{ get; set; }的好習慣嚕
2.要綁定的模型需要有無參數的建構式
.NET在綁定模型的時候會使用new的方法,所以如果ViewModel使用了帶參數的建構式的話一定要新增一個無參數的建構式
補充
如果今天只是想Post一個Message回去,不想為此特地在ViewModel中新增一個「NewMessage」屬性的話可以怎麼做呢?
在View 表單的地方使用「name」就可以指定回傳參數的名字
表單會長這樣
<form asp-action="AddMessage" method="post" enctype="multipart/form-data"> <textarea name="message" type="text" class="form-control"></textarea> <button class="btn btn-success" type="submit">submit</button> </form>然ㄢ |
[HttpPost] public IActionResult AddMessage(string message){ //新增邏輯 return RedirectToAction("Index"); } |
只是這個方法沒辦法綁定成模型,如果回傳過多參數還是建議綁成模型,畢竟獨立的參數式無意義的,模型才有意義