欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

ASP.NET MVC數(shù)組模型綁定詳解

 更新時間:2016年04月27日 16:56:25   作者:choon  
這篇文章主要為大家詳細(xì)介紹了ASP.NET MVC數(shù)組模型綁定的相關(guān)資料,感興趣的小伙伴們可以參考一下

在ASP.NET MVC中使用Razor語法可以在視圖中方便地展示數(shù)組,如果要進行數(shù)組模型綁定,會遇到索引斷裂問題,如下示例:

<input type="text" name="[0].Name" />

<input type="text" name="[1].Name" />

<input type="text" name="[2].Name" />

<input type="text" name="[4].Name" />

<input type="text" name="[5].Name" />

數(shù)組Name在索引3處斷裂,在模型綁定器解析完成后,會丟棄后面的4和5,只有0、1、2會被正確解析到對應(yīng)模型中。

這種斷裂在進行動態(tài)數(shù)組綁定時會經(jīng)常發(fā)生。

下面,以一個案例來探討如何進行動態(tài)數(shù)組綁定。假設(shè)有以下應(yīng)用場景:

要求能夠動態(tài)地添加和刪除乘機人,最終提交表單后乘機人信息要填充到視圖模型中的一個數(shù)組或集合屬性中,以方便我們進行后續(xù)業(yè)務(wù)處理。

方式一:使用占位符替換
第一種方式我稱之為”占位符替換“,使用的是ASP.NET MVC默認(rèn)的模型綁定器(DefaultModelBinder)并結(jié)合前端處理。

首先,第一步,根據(jù)業(yè)務(wù)場景設(shè)計視圖模型:

public class OrderModel
{
 /// <summary>
 /// 航班號
 /// </summary>
 public string FlightNo { get; set; }
 /// <summary>
 /// 乘機人
 /// </summary>
 public List<Passenger> Passengers { get; set; }
}
 
public class Passenger
{
 public string Name { get; set; }
 public string IdNo { get; set; }
}

其次,將此視圖模型傳遞給視圖:

public ActionResult New()
{
 Models.OrderModel orderModel = new Models.OrderModel();
 List<Models.Passenger> passenger = new List<Models.Passenger>();
 passenger.Add(new Models.Passenger());
 orderModel.Passengers = passenger;
 return View(orderModel);
}

再在視圖文件中進行展示:

<div style="width:680px">
 <div class="form-group">
 <label>航班</label><br/>
 @Html.TextBoxFor(p => p.FlightNo, new { placeholder = "航班號" })
 </div>
 <div class="form-group">
 <label>乘機人</label>
 <table class="passenger" >
  <tbody>
  @if (Model.Passengers != null && Model.Passengers.Count > 0) {
   for(int i = 0; i < Model.Passengers.Count; i++) {
   <tr>
    <td>姓名:</td>
    <td>@Html.TextBoxFor(p => Model.Passengers[i].Name)</td>
    <td>身份證號:</td>
    <td>@Html.TextBoxFor(p => Model.Passengers[i].IdNo)</td>
    <td>
    <a href="javascript:;" onclick="removePassenger(this)" >刪除</a>
    </td>
   </tr>
   }
  }
  </tbody>
 </table>
 <div style="margin-top:10px">
  <a href="javascript:;" onclick="addPassenger()">添加乘機人</a>
 </div>
 </div>
</div>

由于ASP.NET MVC的模型綁定器(DefaultModelBinder)具備自動解析形如"[0].屬性名"、"[1].屬性名"的能力,所以可以在模板文件中以占位符的形式來表示數(shù)組下標(biāo):

<!-- 乘機人模板 -->
<script type="text/html" id="passengerTemplate">
 <tr>
 <td>姓名:</td>
 <td><input id="Passengers_{}__Name" name="Passengers[{}].Name" type="text" value=""></td>
 <td>身份證號:</td>
 <td><input id="Passengers_{}__IdNo" name="Passengers[{}].IdNo" type="text" value=""></td>
 <td>
  <a href="javascript:;" onclick="removePassenger(this)">刪除</a>
 </td>
 </tr>
</script>

以上代碼中的"{}"是數(shù)組下標(biāo)占位符。當(dāng)添加乘機人時,可預(yù)先計算已有乘機人個數(shù),然后再使用JavaScript替換”{}“為數(shù)組下標(biāo)。

// 添加乘機人
function addPassenger() {
 // 當(dāng)前添加行數(shù)組元素下標(biāo)
 var index = $(".passenger").find("tbody").find("tr").length;
 //{}是數(shù)組元素下標(biāo)占位符
 var passengerHTML = $('#passengerTemplate').html().replace(/{}/g, index);
 $(".passenger").find("tbody").append(passengerHTML);
}

當(dāng)刪除乘機人時,注意如果刪除的不是最后一個,會發(fā)生索引斷裂問題,需要重新調(diào)整數(shù)組下標(biāo):

// 刪除乘機人
function removePassenger(e) {
 $(e).parents("tr").remove();
 // 依次遍歷表格的每行,重新調(diào)整數(shù)組下標(biāo)
 var tb = $(".passenger").first();
 var count = tb.find("tbody").find("tr").length;
 for (var i = 0; i < count; i++) {
 var newTR = tb.find("tr").eq(i).formhtml().replace(/\[\d+\]/g, '[' + i + ']');//重新調(diào)整數(shù)組元素下標(biāo)
 tb.find("tr").eq(i).html(newTR);
 }
}

這樣,當(dāng)我們提交表單時,乘機人信息就會自動填充到模型的Passengers屬性中。

方式二:使用Vue.js
使用第一種方式需要編寫大量前端代碼,包括模板文件,添加刪除事件,還需要處理重新調(diào)整順序時的插值問題。

如果使用前端MVVM框架會讓這一流程變得簡單,目前比較流行的前端MVVM框架有AngularJS,有老古董KnockoutJS,也有新興小眾框架Vue.js。

AngularJS比較龐大,這么簡單的一個模型綁定用Anuglar有一種殺雞用牛刀的感覺;Knockout和Vue都是輕量級的MVVM框架,但Knockout需要包裹原生數(shù)據(jù)來制造可觀察對象,取值和賦值時需要采用函數(shù)調(diào)用的形式,使用起來不是很方便,所以我選擇了Vue.js。Vue.js是一個輕量高效的庫,它沒有像Angular的module、controller、scope、factory、service這種API,核心就是一個模型綁定功能。大小只有70kb,gzip壓縮后只有25kb,非常輕量化。

這種方式的基本原理是前端使用Vue.js聲明視圖模型并進行綁定,然后提交表單時把模型序列化為json字符串傳遞到后臺,后臺再使用Json.net反序列化為C#對象。

由于Vue.js的綁定特點,我們只需要操作數(shù)組元素即可,不需要額外關(guān)注DOM操作,節(jié)省了不少工作量。

首先,需要聲明視圖模型,并使用Vue.js進行綁定:

<script src="~/Scripts/vue.js"></script>
<script type="text/javascript">
 // 視圖模型
 var viewModel = {
  FlightNo: '',
  Passengers: [
  { ElementId: 'passenger_1', Name: '', IdNo: '' }
  ]
 }
 // 模型綁定
 new Vue({
  el: '#app',
  data: viewModel,
  methods: {
  removePassenger: function (elementId) {
   for (var i = 0; i < viewModel.Passengers.length; i++) {
   if (viewModel.Passengers[i].ElementId == elementId) {
    viewModel.Passengers.splice(i, 1);
   }
   }
  },
  addPassenger: function () {
   var tb = document.getElementsByTagName('table')[0];
   var index = tb.rows[tb.rows.length - 1].getElementsByTagName('input')[0].getAttribute("id").split('_')[1];
   viewModel.Passengers.push({ Name: '', IdNo: '', ElementId: 'passenger_' + (index + 1) });
  },
  submitForm: function () {
   var jsonString = JSON.stringify(viewModel);
   document.getElementById("viewModel").value = jsonString;
   return true;
  }
  }
 });
</script>

然后,在視圖中使用Vue.js綁定:

<form action="/Order2/NewPost" method="post">
 <div id="app" style="width:680px">
 <div class="form-group">
  <label>航班</label><br />
  <input v-model="FlightNo" type="text" placeholder="航班號" />
 </div>
 <div class="form-group">
  <label>乘機人</label>
  <table class="passenger">
  <tbody>
   <tr v-for="passenger in Passengers">
   <td>姓名:</td>
   <td><input v-model="passenger.Name" v-bind:id="passenger.ElementId" type="text" /></td>
   <td>身份證號:</td>
   <td><input v-model="passenger.IdNo" type="text" /></td>
   <td>
    <a href="javascript:;" v-on:click="removePassenger(passenger.ElementId)">刪除</a>
   </td>
   </tr>
  </tbody>
  </table>
  <div style="margin-top:10px">
  <a href="javascript:;" v-on:click="addPassenger">添加乘機人</a>
  </div>
  <div style="margin-top:10px">
  <input type="submit" class="btn btn-default" v-on:click="submitForm" />
  </div>
 </div>
 </div>
 <input type="hidden" id="viewModel" name="viewModel" />
</form>

最后在Controller里,我們反序列化即可得到對應(yīng)的C#強類型模型:

[HttpPost]
public ActionResult NewPost()
{
 var jsonString = Request.Form["viewModel"];
 Models.OrderModel model = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.OrderModel>(jsonString);
 if (model != null) {
 // our code here...
 }
 return RedirectToAction("Index", "Home");
}
 

這兩種方式均可以實現(xiàn)動態(tài)數(shù)組綁定,方式一使用js進行占位符替換,表單中的元素都以[index].屬性名的方式命名,然后由MVC默認(rèn)的模型綁定器來轉(zhuǎn)化模型;

方式二使用Vue.js來直接進行模型綁定,提交表單時將模型序列化為json字符串,然后后端再反序列化,最終得到強類型模型。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助。

相關(guān)文章

  • EFCore 通過實體Model生成創(chuàng)建SQL Server數(shù)據(jù)庫表腳本

    EFCore 通過實體Model生成創(chuàng)建SQL Server數(shù)據(jù)庫表腳本

    這篇文章主要介紹了EFCore 通過實體Model生成創(chuàng)建SQL Server數(shù)據(jù)庫表腳本的示例,幫助大家更好的理解和學(xué)習(xí)使用.net框架,感興趣的朋友可以了解下
    2021-03-03
  • .NET Core類庫System.Reflection.DispatchProxy實現(xiàn)簡易Aop的方法

    .NET Core類庫System.Reflection.DispatchProxy實現(xiàn)簡易Aop的方法

    這篇文章主要給大家介紹了關(guān)于.NET Core類庫System.Reflection.DispatchProxy實現(xiàn)簡易Aop的相關(guān)資料,文中通過示例代碼結(jié)束的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • asp.net core中靈活的配置方式詳解

    asp.net core中靈活的配置方式詳解

    這篇文章主要給的阿加介紹了關(guān)于在asp.net core中靈活的配置方式的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。
    2017-07-07
  • ASP.NET中實時圖表的實現(xiàn)方法分享

    ASP.NET中實時圖表的實現(xiàn)方法分享

    這篇文章介紹了ASP.NET中實時圖表的實現(xiàn)方法,有需要的朋友可以參考一下
    2013-11-11
  • the sourcesafe database has been locked by the administrator之解決方法

    the sourcesafe database has been locked by the administrator

    今天早上打開soucesafe的時候出現(xiàn)提示:“the sourcesafe database has been locked by the administrator"。仔細(xì)想想, 可能是前天晚上用"f:\analyze.exe" -I- -DB -F -V3 -D "f:\vssData\data" 命今分析的時候鎖定了database
    2009-04-04
  • ASP.NET Core 2.1 使用Docker運行的方法步驟

    ASP.NET Core 2.1 使用Docker運行的方法步驟

    這篇文章主要介紹了ASP.NET Core 2.1 使用Docker運行的方法步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • .Net通過TaskFactory.FromAsync簡化APM

    .Net通過TaskFactory.FromAsync簡化APM

    這篇文章介紹了.Net通過TaskFactory.FromAsync簡化APM的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • ASP.NET Core使用HttpClient調(diào)用WebService

    ASP.NET Core使用HttpClient調(diào)用WebService

    這篇文章介紹了ASP.NET Core使用HttpClient調(diào)用WebService的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • DataReader不能使用using的詳細(xì)示例

    DataReader不能使用using的詳細(xì)示例

    這篇文章主要介紹了DataReader不能使用using的詳細(xì)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • ASP.NET中HTML頁面的訪問驗證設(shè)置方法

    ASP.NET中HTML頁面的訪問驗證設(shè)置方法

    這篇文章主要介紹了ASP.NET中HTML頁面的訪問驗證設(shè)置方法,需要的朋友可以參考下
    2015-10-10

最新評論