Steve Mak
Posted on May 29, 2020
(Original reference: https://zh.wikipedia.org/wiki/ASP.NET_MVC_Framework)
- Initial release on 17 March 2009.
- Latest release (ASP.NET MVC 5.2) on 24 December 2014.
- ASP.NET MVC Framework includes in the package of System.Web.Mvc.
- Core namespaces of ASP.NET
- System.Web.Mvc
- HtmlHelper
- System.Web.Mvc.Html
- ASP.NET MVC support below view of type
- Normal view (.aspx, supported by ViewPage)
- Partial view (.ascx, supported by ViewUserControl)
- Layout view (.master, suppoted by ViewMasterPage)
- Type of View Engine
- Web Form
- Razor View
- Support HTTP methods
- HttpVerbs.Get
- HttpVerbs.Post
- HttpVerbs.Delete
- HttpVerbs.Put
- HttpVerbs.Head
(GitHub: https://github.com/aspnet/AspNetWebStack)
Controller
Support on method decorator
- HttpVerbs.Get
- HttpVerbs.Post
- HttpVerbs.Delete
- HttpVerbs.Put
- HttpVerbs.Head
Type of ActionResult
- ViewResult物件,這個物件內裝載了IView介面的資訊,以及IViewEngine的資訊,實際產生輸出資料的會是 IViewEngine,以及其指示的 View 物件。
- PartialViewResult物件,與ViewResult相似,但它回傳的是"部份展示",即使用者控制項的View。
- ContentResult物件,裝載由使用者自訂的 Content-Type 以及資料。
- EmptyResult物件,表示不回傳任何東西。
- HttpUnauthorizedReuslt物件,表示動作沒有被授權(即 HTTP 401)的錯誤訊息。
- JavaScriptResult物件,表示回傳的是JavaScript指令碼。
- JsonResult物件,表示回傳的是JSON資料。
- FileResult物件,表示回傳的是一個檔案資料。
- RedirectResult物件,表示回傳的是一個重導向 (HTTP Redirect) 指令。
- RedirectToRouteResult物件,與 RedirectResult 類似,但是它是重導向給一個 Route 的路徑。
using System.Linq;
using System.Web.Mvc;
using System.Web;
using System;
// GET: /Person/
public ActionResult Index()
{
return View(people);
}
// GET: /Person/Details/5
public ActionResult Details(Person person)
{
return View(person);
}
// GET: /Person/Create
public ActionResult Create()
{
return View();
}
// POST: /Person/Create
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Person person)
{
if (!ModelState.IsValid)
{
return View("Create", person);
}
people.Add(person);
return RedirectToAction("Index");
}
View
ASP.NET supports three types of view
- .aspx網頁,由 ViewPage 來支援。
- .ascx使用者控制項,由 ViewUserControl 來支援。
- .master主版頁面,由 ViewMasterPage 來支援。
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head runat="server">
<title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="page">
<div id="header">
<div id="title">
<h1>My MVC Application</h1>
</div>
<div id="logindisplay">
<% Html.RenderPartial("LogOnUserControl"); %>
</div>
<div id="menucontainer">
<ul id="menu">
<li><%= Html.ActionLink("Home", "Index", "Home")%></li>
<li><%= Html.ActionLink("About", "About", "Home")%></li>
</ul>
</div>
</div>
<div id="main">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
<div id="footer">
</div>
</div>
</div>
</body>
</html>
Model Validation
/*
* Manually Validation
*/
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Person person)
{
if (person.Name.Trim().Length == 0)
{
ModelState.AddModelError("Name", "Name is required.");
}
if (person.Age < 1 || person.Age > 200)
{
ModelState.AddModelError("Age", "Age must be within range 1 to 200.");
}
if ((person.Zipcode.Trim().Length > 0) && (!Regex.IsMatch(person.Zipcode, @"^\d{5}$|^\d{5}-\d{4}$")))
{
ModelState.AddModelError("Zipcode", "Zipcode is invalid.");
}
if (!Regex.IsMatch(person.Phone, @"((\(\d{3}\) ?)|(\d{3}-))?\d{3}-\d{4}"))
{
ModelState.AddModelError("Phone", "Phone number is invalid.");
}
if (!Regex.IsMatch(person.Email, @"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$"))
{
ModelState.AddModelError("Email", "Email format is invalid.");
}
if (!ModelState.IsValid)
{
return View("Create", person);
}
people.Add(person);
return RedirectToAction("Index");
}
/*
* Use Data Annotation
*/
using System.ComponentModel.DataAnnotations;
namespace MvcDA {
[MetadataType(typeof(ProductMD))]
public partial class Product {
public class ProductMD {
[StringLength(50),Required]
public object Name { get; set; }
[StringLength(15)]
public object Color { get; set; }
[Range(0, 9999)]
public object Weight { get; set; }
// public object NoSuchProperty { get; set; }
}
}
}
<h2>Create</h2>
<%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %>
<% using (Html.BeginForm()) {%>
<fieldset>
<legend>Fields</legend>
<p>
<label for="Name">Name:</label>
<%= Html.TextBox("Name") %> Required
<%= Html.ValidationMessage("Name", "*") %>
</p>
<p>
<label for="Age">Age:</label>
<%= Html.TextBox("Age") %> Required
<%= Html.ValidationMessage("Age", "*") %>
</p>
<p>
<label for="Street">Street:</label>
<%= Html.TextBox("Street") %>
<%= Html.ValidationMessage("Street", "*") %>
</p>
<p>
<label for="City">City:</label>
<%= Html.TextBox("City") %>
<%= Html.ValidationMessage("City", "*") %>
</p>
<p>
<label for="State">State:</label>
<%= Html.TextBox("State") %>
<%= Html.ValidationMessage("State", "*") %>
</p>
<p>
<label for="Zipcode">Zipcode:</label>
<%= Html.TextBox("Zipcode") %>
<%= Html.ValidationMessage("Zipcode", "*") %>
</p>
<p>
<label for="Phone">Phone:</label>
<%= Html.TextBox("Phone") %> Required
<%= Html.ValidationMessage("Phone", "*") %>
</p>
<p>
<label for="Email">Email:</label>
<%= Html.TextBox("Email") %> Required
<%= Html.ValidationMessage("Email", "*") %>
</p>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
<div>
<%=Html.ActionLink("Back to List", "Index") %>
</div>
Html Helper
// Render
Html.Encode | Html.AttributeEncode
Html.ActionLink | Html.RouteLink
Html.Partial | Html.RenderPartial
Html.DisplayFor | Html.DisplayTextFor | Html.DisplayNameFor
Html.FormatValue | Html.Raw
// Verification
Html.EnableClientValidation | Html.EnableUnobtrusiveJavaScript
// Form related
Html.BeginForm | Html.EndForm
Html.AntiForgeryToken
Html.EditorFor | Html.LabelFor | Html.Hidden
Html.Password | Html.RadioButton | Html.CheckBox
Html.TextBox | Html.TextArea | Html.DropDownList
Html.ListBox
Html.ValidationMessageFor | Html.ValidationSummary
💖 💪 🙅 🚩
Steve Mak
Posted on May 29, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.