在本節中,您將驗證電影控制器生成的編輯方法(Edit action methods)和視圖。但是首先將修改點代碼,使得發布日期屬性(ReleaseDate)看上去更好。打開Models \ Movie.cs文件,并添加高亮行如下所示:
using System; using System.ComponentModel.DataAnnotations; using System.Data.Entity; namespace MvcMovie.Models { public class Movie { public int ID { get; set; } public string Title { get; set; } [Display(Name = "Release Date")] [DataType(DataType.Date)] [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] public DateTime ReleaseDate { get; set; } public string Genre { get; set; } public decimal Price { get; set; } } public class MovieDBContext : DbContext { public DbSet<Movie> Movies { get; set; } } }
在接下來的教程中,我們將討論DataAnnotations。Display屬性指明要顯示的字段的名稱(在本例中“Release Date”來代替“ReleaseDate”)。DataType屬性用于指定類型的數據,在本例它是一個日期,所以不會顯示存放在該字段時間詳情。DisplayFormat屬性在Chrome瀏覽器里有一個bug:呈現的日期格式不正確。
在瀏覽器地址欄里追加/Movies, 瀏覽到Movies頁面。并進入編輯(Edit)頁面。
Edit(編輯)鏈接是由Views\Movies\Index.cshtml視圖
中的Html.ActionLink方法所生成的
@Html.ActionLink("Edit", "Edit", new { id=item.ID })
Html
對象是一個Helper, 以屬性的形式在System.Web.Mvc.WebViewPage基類上公開。 ActionLink是一個幫助方法(Helper),便于動態生成指向Controller中操作方法 的HTML 超鏈接鏈接。ActionLink
方法的第一個參數是想要呈現的鏈接文本 (例如,<a>Edit Me</a>
)。第二個參數是要調用的操作方法的名稱(在本例中, Edit方法)。最后一個參數是一個匿名對象(anonymous object),用來生成路由數據 (在本例中,ID 為 4 的)。
在上圖中所生成的鏈接是http://localhost:xxxxx/Movies/Edit/4。默認的路由 (在App_Start\RouteConfig.cs 中設定) 使用的 URL 匹配模式為: {controller}/{action}/{id}
。因此,ASP.NET 將http://localhost:xxxxx/Movies/Edit/4轉化到Movies
控制器中Edit
操作方法,參數ID
等于 4 的請求。查看App_Start\RouteConfig.cs文件中的以下代碼。
MapRoute方法是使用HTTP請求路由查找到正確的控制器(controller)和行動方法,并提供了可選ID的參數。MapRoute方法也被用于通過HtmlHelpers如ActionLink的控制器,操作方法及任何路由數據,以生成URL。
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); }
您還可以使用QueryString來傳遞操作方法的參數。例如,URL: http://localhost:xxxxx/Movies/Edit?ID=3還會將參數ID
為 3的請求傳遞給Movies
控制器的Edit
操作方法。
打開Movies
控制器。如下所示的兩個Edit
操作方法。
// GET: /Movies/Edit/5 public ActionResult Edit(int? id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } Movie movie = db.Movies.Find(id); if (movie == null) { return HttpNotFound(); } return View(movie); } // POST: /Movies/Edit/5 // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see http://go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include="ID,Title,ReleaseDate,Genre,Price")] Movie movie) { if (ModelState.IsValid) { db.Entry(movie).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } return View(movie); }
注意,第二個Edit
操作方法的上面有HttpPost屬性。此屬性指定了Edit
方法的重載,此方法僅被POST 請求所調用。您可以將HttpGet屬性應用于第一個編輯方法,但這是不必要的,因為它是默認的屬性。(操作方法會被隱式的指定為HttpGet
屬性,從而作為HttpGet
方法。) 綁定(Bind)屬性是另一個重要安全機制,可以防止黑客攻擊(從over-posting數據到你的模型)。您應該只包含在bind屬性屬性,您想要更改。您可以閱讀有關在我overposting security note。我們將在本教程中使用的簡單模型,模型中綁定所有數據。ValidateAntiForgeryToken屬性是用來防止偽造的請求,并配對@Html.AntiForgeryToken()文件 (Views\Movies\Edit.cshtml),如下圖所示,部分在編輯view文件:
@model MvcMovie.Models.Movie @{ ViewBag.Title = "Edit"; } <h2>Edit</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>Movie</h4> <hr /> @Html.ValidationSummary(true) @Html.HiddenFor(model => model.ID) <div class="form-group"> @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Title) @Html.ValidationMessageFor(model => model.Title) </div> </div>
@Html.AntiForgeryToken() 生成隱藏的窗體, 防偽令牌必須匹配的的Movies控制器的Edit方法。在我的教程XSRF/CSRF Prevention in MVC,你可以讀到更多關于跨站點請求偽造(也稱為XSRF或CSRF)。
HttpGet
Edit
方法會獲取電影ID參數、 查找影片使用Entity Framework 的Find方法,并返回到選定影片的編輯視圖。如果不帶參數調用Edit
方法,ID 參數被指定為默認值 零。如果找不到一部電影,則返回HttpNotFound 。當scaffolding自動創建編輯視圖時,它會查看Movie
類并為類的每個屬性創建用于Render的<label>
和<input>
的元素。下面的示例為visual studio scaffolding自動創建的編輯視圖:
@model MvcMovie.Models.Movie @{ ViewBag.Title = "Edit"; } <h2>Edit</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>Movie</h4> <hr /> @Html.ValidationSummary(true) @Html.HiddenFor(model => model.ID) <div class="form-group"> @Html.LabelFor(model => model.Title, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Title) @Html.ValidationMessageFor(model => model.Title) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.ReleaseDate, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.ReleaseDate) @Html.ValidationMessageFor(model => model.ReleaseDate) </div> </div> @*Genre and Price removed for brevity.*@ <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Save" class="btn btn-default" /> </div> </div> </div> } <div> @Html.ActionLink("Back to List", "Index") </div> @section Scripts { @Scripts.Render("~/bundles/jqueryval") }
注意,視圖模板在文件的頂部有 @model MvcMovie.Models.Movie
的聲明,這將指定視圖期望的模型類型為Movie
。
scaffolded自動生成的代碼,使用了Helper方法的幾種簡化的 HTML 標記。 Html.LabelFor
用來顯示字段的名稱("Title"、"ReleaseDate"、"Genre"或"Price")。 Html.EditorFor
用來呈現 HTML <input>
元素。Html.ValidationMessageFor
用來顯示與該屬性相關聯的任何驗證消息。
運行該應用程序,然后瀏覽URL,/Movies。單擊Edit鏈接。在瀏覽器中查看頁面源代碼。HTML Form中的元素如下所示:
<form action="/movies/Edit/4" method="post"> <input name="__RequestVerificationToken" type="hidden" value="UxY6bkQyJCXO3Kn5AXg-6TXxOj6yVBi9tghHaQ5Lq_qwKvcojNXEEfcbn-FGh_0vuw4tS_BRk7QQQHlJp8AP4_X4orVNoQnp2cd8kXhykS01" /> <fieldset class="form-horizontal"> <legend>Movie</legend> <input data-val="true" data-val-number="The field ID must be a number." data-val-required="The ID field is required." id="ID" name="ID" type="hidden" value="4" /> <div class="control-group"> <label class="control-label" for="Title">Title</label> <div class="controls"> <input class="text-box single-line" id="Title" name="Title" type="text" value="GhostBusters" /> <span class="field-validation-valid help-inline" data-valmsg-for="Title" data-valmsg-replace="true"></span> </div> </div> <div class="control-group"> <label class="control-label" for="ReleaseDate">Release Date</label> <div class="controls"> <input class="text-box single-line" data-val="true" data-val-date="The field Release Date must be a date." data-val-required="The Release Date field is required." id="ReleaseDate" name="ReleaseDate" type="date" value="1/1/1984" /> <span class="field-validation-valid help-inline" data-valmsg-for="ReleaseDate" data-valmsg-replace="true"></span> </div> </div> <div class="control-group"> <label class="control-label" for="Genre">Genre</label> <div class="controls"> <input class="text-box single-line" id="Genre" name="Genre" type="text" value="Comedy" /> <span class="field-validation-valid help-inline" data-valmsg-for="Genre" data-valmsg-replace="true"></span> </div> </div> <div class="control-group"> <label class="control-label" for="Price">Price</label> <div class="controls"> <input class="text-box single-line" data-val="true" data-val-number="The field Price must be a number." data-val-required="The Price field is required." id="Price" name="Price" type="text" value="7.99" /> <span class="field-validation-valid help-inline" data-valmsg-for="Price" data-valmsg-replace="true"></span> </div> </div> <div class="form-actions no-color"> <input type="submit" value="Save" class="btn" /> </div> </fieldset> </form>
被<form>
HTML 元素所包括的 <input>
元素會被發送到,<form>的action
屬性所設置的URL:/Movies/Edit。單擊Save按鈕時,from數據將會被發送到服務器。第二行顯示隱藏XSRF通過@Html.AntiForgeryToken()調用生成的令牌。
處理 POST 請求
下面的代碼顯示了Edit
操作方法的HttpPost
處理:
[HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include="ID,Title,ReleaseDate,Genre,Price")] Movie movie) { if (ModelState.IsValid) { db.Entry(movie).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } return View(movie); }
ASP.NET MVC model binder
接收form所post的數據,并轉換所接收的Movie請求數據從而創建一個Movie
對象。ModelState.IsValid
方法用于驗證提交的表單數據是否可用于修改(編輯或更新)一個Movie
對象。如果數據是有效的電影數據,將保存到數據庫的Movies
集合(MovieDBContext
實例)。通過調用MovieDBContext
的SaveChanges
方法,新的電影數據會被保存到數據庫。數據保存之后,代碼會把用戶重定向到MoviesController
類的Index
操作方法,頁面將顯示電影列表,同時包括剛剛所做的更新。
一旦客戶端驗證確定某個字段的值是無效的,將顯示出現錯誤消息。如果禁用JavaScript,則不會有客戶端驗證,但服務器將檢測回傳的值是無效的,而且將重新顯示表單中的值與錯誤消息。在本教程的后面,我們驗證更詳細的審查。Edit.cshtml視圖模板中的Html.ValidationMessageFor
Helper將用來顯示相應的錯誤消息。
所有HttpGet方法遵循類似的模式。他們得到一個電影對象(或對象列表中,如本案例的Index),并把模型數據傳遞給視圖。Create方法傳遞一個空的影片對象給Create視圖。所有的create, edit, delete方法,或其他的方法: 用HttpPost重載的方法修改數據。修改數據在HTTP GET方法, 存在安全風險,如博客文章ASP.NET MVC Tip #46 – Don’t use Delete Links because they create Security Holes. 在HTTP GET方法中修改數據也違反HTTP的最佳實踐和REST模式架構,指明GET請求不應該改變你的應用程序的狀態。換句話說,執行GET操作應該是一個安全,操作,無任何副作用,不會修改你的持久化數據。
如果您的電腦是是US-English的語言設置,可以跳過這一節,直接進入下一個教程。
注意,為了使jQuery支持使用逗號的非英語區域的驗證 ,需要設置逗號(",")來表示小數點,你需要引入globalize.js并且你還需要具體的指定cultures/globalize.cultures.js文件 (地址在https://github.com/jquery/globalize) 在 JavaScript 中可以使用 Globalize.parseFloat
。你可以從NuGet中安裝非英語的jQuery的驗證、插件。 (如果您使用的是英語語言環境,不要安裝全球化 (Globalize)。)
1. 在工具(Tools)菜單,點擊庫程序包管理器( Library Package Manager),選擇解決方案程序包管理器(Manage NuGet Packages for Solution).
2. 在左邊面板上,選擇聯機庫(Online,見下圖)
3. 在搜索已安裝庫( Search Installed packages ),輸入 Globalize搜索
點擊安裝(Install). JavaScript腳本 \jquery.globalize\globalize.js 文件將會添加到您的當前工程下. 腳本\jquery.globalize\cultures\ 文件夾的下面會包含很多不同文化的JavaScript文件
注意事項:安裝這個包,預計花費5分鐘時間(取決于您的網速).
下面的代碼展示了在"FR-FR" Culture下的 Views\Movies\Edit.cshtml 視圖:
@section Scripts { @Scripts.Render("~/bundles/jqueryval") <script src="~/Scripts/jquery.globalize/globalize.js"></script> <script src="~/Scripts/jquery.globalize/cultures/globalize.culture.fr-FR.js"></script> <script> $.validator.methods.number = function (value, element) { return this.optional(element) || !isNaN(Globalize.parseFloat(value)); } $(document).ready(function () { Globalize.culture('fr-FR'); }); </script> <script> jQuery.extend(jQuery.validator.methods, { range: function (value, element, param) { //Use the Globalization plugin to parse the value var val = $.global.parseFloat(value); return this.optional(element) || ( val >= param[0] && val <= param[1]); } }); </script> <script> $.validator.methods.date = function (value, element) { return this.optional(element) || Globalize.parseDate(value); } </script> }
為了避免在每一個編輯視圖重復這段代碼,你可以將它移動到布局文件。要優化腳本下載,看我的教程Bundling and Minification。欲了解更多信息,請,ASP.NET MVC 3 Internationalization和ASP.NET MVC 3 Internationalization - Part 2 (NerdDinner)。
作為一個臨時解決辦法,如果您不能驗證當前的區域設置,可以強制你的計算機使用US English,或者你可以在瀏覽器中禁用JavaScript。為了強制您的電腦使用美國英語,你可以在項目根目錄Web.config文件里面添加的全球化設置。
下面的代碼演示設置為美國英語的全球化文化設置。
<system.web> <globalization culture ="en-US" /> <!--elements removed for clarity--> </system.web>
在接下來的教程,我們將實現搜索功能。
添加一個搜索方法(Search Method)和搜索視圖(Search View)
在本節中,您將添加Index操作方法,可以讓你按照電影流派(genre)或名稱搜索電影。
升級 Index窗體
我們開始在方法現有MoviesController類中,更新Index方法。代碼如下:
public ActionResult Index(string searchString) { var movies = from m in db.Movies select m; if (!String.IsNullOrEmpty(searchString)) { movies = movies.Where(s => s.Title.Contains(searchString)); } return View(movies); }
Index方法的第一行創建以下的LINQ查詢,以選擇看電影:
var movies = from m in db.Movies select m; 如果searchString參數包含一個字符串,可以使用下面的代碼,修改電影查詢要篩選的搜索字符串: if (!String.IsNullOrEmpty(searchString)) { movies = movies.Where(s => s.Title.Contains(searchString)); }
上面s => s.Title
代碼是一個Lambda 表達式。Lambda 是基于方法的LINQ查詢,例如上面的where查詢。在上面的代碼中使用了標準查詢參數運算符的方法。當定義LINQ查詢或修改查詢條件時,如調用Where
或OrderBy
方法時,不會執行 LINQ 查詢。相反,查詢執行會被延遲,這意味著表達式的計算延遲,直到取得實際的值或調用ToList
方法。在Search示例中,Index.cshtml視圖中執行查詢。有關延遲的查詢執行的詳細信息,請參閱Query Execution.
注:Contains 方法是運行在的數據庫,而不是C#代碼上面。在數據庫中,Contains映射到to SQL LIKE,這是大小寫不敏感的。
現在,您可以實現Index視圖并將其顯示給用戶。
運行這個應用程序和導航到 /Movies/Index。追加一個查詢字符串,URL如 ?searchString=ghost。篩選的影片會被顯示。
如果你改變了Index方法簽名參數名為id的,這個id參數將匹配{ id }的占位符。App_Start\ RouteConfig.cs文件中設置的缺省路由定義如下。
{controller}/{action}/{id}
原來的 Index 方法看起來如下所示:
public ActionResult Index(string searchString) { var movies = from m in db.Movies select m; if (!String.IsNullOrEmpty(searchString)) { movies = movies.Where(s => s.Title.Contains(searchString)); } return View(movies); } 修改后的 Index 方法看起來如下所示: public ActionResult Index(string id) { string searchString = id; var movies = from m in db.Movies select m; if (!String.IsNullOrEmpty(searchString)) { movies = movies.Where(s => s.Title.Contains(searchString)); } return View(movies); }
現在,您可以通過路由數據(URL段)的標題搜索了,而不是作為查詢字符串值,截圖如下:
然而,你不能期望用戶可以每次要搜索一部電影都會去修改URL。所以,現在你將添加用戶界面,幫助他們來過濾影片。如果你改變Index方法來測試如何通過路由綁定ID參數的簽名,Index方法需要一個字符串參數searchString:
public ActionResult Index(string searchString) { var movies = from m in db.Movies select m; if (!String.IsNullOrEmpty(searchString)) { movies = movies.Where(s => s.Title.Contains(searchString)); } return View(movies); } 打開文件 Views\Movies\Index.cshtml, 在這段代碼@Html.ActionLink("Create New", "Create")后之后, 新增如下高亮的: @model IEnumerable<MvcMovie.Models.Movie> @{ ViewBag.Title = "Index"; } <h2>Index</h2> <p> @Html.ActionLink("Create New", "Create") @using (Html.BeginForm()){ <p> Title: @Html.TextBox("SearchString") <br /> <input type="submit" value="Filter" /></p> } </p>
Html.BeginForm輔助會創建一個<form>標簽。當用戶通過點擊“過濾器”按鈕,提交表單, Html.BeginForm助手會導致窗體post到它本身。
Visual Studio2013中有一個很好的改善: 顯示和編輯視圖文件時。當你運行應用程序打開視圖文件時,Visual Studio2013的將調用正確的控制器操作方法來展示視圖。
在Visual Studio中打開使用Index視圖(在上面的圖片所示),點擊Ctr F5或F5運行應用程序,然后試試搜索一部電影。
該Index 方法的HttpPost沒有重載。 你不需要它,因為該方法不改變application的狀態,只是過濾數據。
您可以添加以下httppost Index方法。在這種情況下,函數調用將匹配的HttpPost Index方法,的HttpPost Index方法運行的如下面的圖片所示。
[HttpPost] public string Index(FormCollection fc, string searchString) { return "<h3> From [HttpPost]Index: " + searchString + "</h3>"; }
但是,即使您添加此HttpPost
Index方法,這一實現其實是有局限的。想象一下您想要添加書簽給特定的搜索,或者您想要把搜索鏈接發送給朋友們,他們可以通過單擊看到一樣的電影搜索列表。請注意 HTTP POST 請求的 URL 和GET 請求的URL 是相同的(localhost:xxxxx/電影/Index)— — 在 URL 中沒有搜索信息。現在,搜索字符串信息作為窗體字段值,發送到服務器。這意味著您不能在 URL 中捕獲此搜索信息,以添加書簽或發送給朋友。
解決方法是使用重載的BeginForm,它指定 POST 請求應添加到 URL 的搜索信息,并應該路由到 HttpGet版的 Index方法。將現有的無參數BeginForm
方法,修改為以下內容
@using (Html.BeginForm("Index","Movies",FormMethod.Get))
現在當您提交搜索,該 URL 將包含搜索的查詢字符串(query string)。搜索還會請求到 HttpGet
Index操作方法,即使您也有一個HttpPost
Index方法。
按照電影流派添加搜索
如果您添加了HttpPost
的Index方法,請立即刪除它。
接下來,您將添加功能可以讓用戶按流派搜索電影。將Index方法替換成下面的代碼:
public ActionResult Index(string movieGenre, string searchString) { var GenreLst = new List<string>(); var GenreQry = from d in db.Movies orderby d.Genre select d.Genre; GenreLst.AddRange(GenreQry.Distinct()); ViewBag.movieGenre = new SelectList(GenreLst); var movies = from m in db.Movies select m; if (!String.IsNullOrEmpty(searchString)) { movies = movies.Where(s => s.Title.Contains(searchString)); } if (!string.IsNullOrEmpty(movieGenre)) { movies = movies.Where(x => x.Genre == movieGenre); } return View(movies); }
這個版本的Index方法將接受一個附加的movieGenre
參數。前幾行的代碼會創建一個List
對象來保存數據庫中的電影流派。
下面的代碼是從數據庫中檢索所有流派的 LINQ 查詢。
var GenreQry = from d in db.Movies orderby d.Genre select d.Genre;
該代碼使用泛型 List集合的 AddRange方法將所有不同的流派,添加到集合中的。(使用 Distinct
修飾符,不會添加重復的流派 -- 例如,在我們的示例中添加了兩次喜劇)。
該代碼然后在ViewBag
對象中存儲了流派的數據列表。的SelectList對象在ViewBag作為存儲類數據(這樣的電影流派),然后在下拉列表框中的數據訪問類別,是一個典型的MVC applications的方法。
下面的代碼演示如何檢查movieGenre
參數。如果它不是空的,代碼進一步指定了所查詢的電影流派。
if (!string.IsNullOrEmpty(movieGenre)) { movies = movies.Where(x => x.Genre == movieGenre); }
如前所述,查詢數據不會在數據庫上運行,直到電影列表迭代結束(恰發生在View,Index方法返回后)。
Index視圖添加標記,以支持按流派搜索電影
在Views\Movies\Index.cshtml 文件中,添加Html.DropDownList輔助方法,在TextBox前。完成的代碼如下圖所示:
@model IEnumerable<MvcMovie.Models.Movie> @{ ViewBag.Title = "Index"; } <h2>Index</h2> <p> @Html.ActionLink("Create New", "Create") @using (Html.BeginForm("Index", "Movies", FormMethod.Get)) { <p> Genre: @Html.DropDownList("movieGenre", "All") Title: @Html.TextBox("SearchString") <input type="submit" value="Filter" /> </p> } </p> <table class="table">
下面的代碼:
@Html.DropDownList("movieGenre", "All")
ViewBag 中, "movieGenre" 參考作為key在DropDownList 中搜索IEnumerable<SelectListItem >. ViewBag填入的操作方法:
public ActionResult Index(string movieGenre, string searchString) { var GenreLst = new List<string>(); var GenreQry = from d in db.Movies orderby d.Genre select d.Genre; GenreLst.AddRange(GenreQry.Distinct()); ViewBag.movieGenre = new SelectList(GenreLst); var movies = from m in db.Movies select m; if (!String.IsNullOrEmpty(searchString)) { movies = movies.Where(s => s.Title.Contains(searchString)); } if (!string.IsNullOrEmpty(movieGenre)) { movies = movies.Where(x => x.Genre == movieGenre); } return View(movies); }
參數“All”提供的項列表中的預先選擇的。如我們使用下面的代碼:
@Html.DropDownList("movieGenre", "Comedy")
在我們的數據庫中,我們擁有與“喜劇”流派的電影,“喜劇”在下拉列表中將預先選擇。因為我們沒有一個電影流派“All”,也沒有“All”的SelectList,所以當我們post back后不做任何選擇,movieGenre查詢字符串值是空的。
運行應用程序并瀏覽/Movies/Index。嘗試搜索流派,電影名稱,并同時選擇這兩個條件。
在本節中,您創建了一個搜索的方法和視圖,使用它,用戶可以通過電影標題和流派來搜索。在下一節中,您將看到如何添加一個屬性到Movie model,和如何添加一個初始值設定項值,它會自動創建一個測試數據庫。以上創建搜索方法和視圖的示例是為了幫助大家更好的掌握MVC的知識,在進行MVC開發時,開發工具也可以大大幫助提高工具效率。使用 ComponentOne Studio ASP.NET MVC 這款輕量級控件,在效率大幅提高的同時,還能滿足用戶的所有需求。
-----------------------------------------------------------------------------------------
《ASP.NET MVC 5 入門指南》12篇文章匯總如下:
4. ASP.NET MVC 5 - 將數據從控制器傳遞給視圖
6. ASP.NET MVC 5 - 創建連接字符串(Connection String)并使用SQL Server LocalDB
8. ASP.NET MVC 5 - 驗證編輯方法(Edit method)和編輯視圖(Edit view)
9. ASP.NET MVC 5 - 給電影表和模型添加新字段
10. ASP.NET MVC 5 - 給數據模型添加校驗器
11. ASP.NET MVC 5 - 查詢Details和Delete方法
12. ASP.NET MVC 5 - 使用Wijmo MVC 5模板1分鐘創建應用
希望這些文章對感興趣的朋友有所幫助,另附上PDF版的匯總文檔:
《ASP.NET MVC 5 入門指南》PDF版
相關閱讀:
微軟 Build 2017 開發者大會:Azure 與 AI 的快速發展
文章列表