MVC基礎——引數與值傳遞,提交資料
準備工作:
現在新增Customer控制器,同時,在建立控制器的時候,新增Create,Delete,Detail動作。
Customer的模型結構為:
Customer類:CustomerID,LastName,FirstName
現在控制器情況為:
程式碼 public class CustomerController : Controller{
public ActionResult Index()
{
return View();
}
public ActionResult Details(int
{
return View();
}
public ActionResult Create()
{
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection collection)
{
try
{
return
}
catch
{
return View();
}
}
public ActionResult Edit(int id)
{
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection collection)
{
try
{
return RedirectToAction("Index");
}
catch
{
return View();
}
}
}
可以看到,除Index,Details動作外,其它的CU全是兩個動作,由於修飾標籤的作用而在不同情況下呼叫動作來返回檢視。
(一)新增列表
在Views中新增Customer資料夾,然後在此資料夾中新增Index檢視。並指定強型別Customer,並指定自動生成檢視內容:List
程式碼就不貼了。然後在動作中為檢視指定model
public ActionResult Index(){
IList<Customer> _list = dd.ShowList();
return View(_list);
}
Index
|
現在點選第一條的詳細,會發生什麼事:
<%= Html.ActionLink("詳細", "Details", new { /* id=item.PrimaryKey */ })%>通過ActionLink來重定向到控制器下的Details動作。
public ActionResult Details(int id){
return View();
}
這個動作接受一個引數,但在列表中沒有提供引數:
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Details(Int32)' in 'Web.Controllers.CustomerController'. To make a parameter optional its type should be either a reference type or a Nullable type. 引數名: parameters |
因為在Details方法(動作)動作中要求有一個int型引數,但在傳遞時傳遞的是一個Null值,解決:
1 為Details方法的引數改為可空整形
2 傳遞引數
現在為Details動作新增檢視,Details。這個就不說了。然後再點詳細:
會提示:未將物件引用設定到物件的例項。這是因為還沒有為詳細檢視返回model例項。現在在Details方法(動作)中,新增:
public ActionResult Details(int? id){
Customer customer = new Customer();
if (id.HasValue)
customer = dd.GetCustomer((int)id);
return View(customer);
}
現在再點詳細看看,會發現,可以預覽,但沒有值,這個很容易理解,傳遞的值為Null,所以int? id就為空,所以返回的是一個空例項(只有例項的預設值)。這時候可以為其指定一個路由預設值:
new { controller = "News", action = "NewsList", id = "2" },它取的的是id=2這個預設值
接下來為詳細傳遞id引數,即在列表檢視中為詳細連結新增引數:
<%= Html.ActionLink("詳細", "Details", new { id=item.CustomerId })%>
其中id部分與Details動作的引數名相同。現在的詳細就可以正常了。
Index
Details CustomerId: 3 FirstName: Tom |
(二)建立Create檢視
在建立過程中,選擇強型別,並選擇Customer實體。
然後Create檢視的程式碼就不貼了。簡單的說明一下:
·驗證控制元件,每個建立的輸入文字框都有相應的ValidationMessage
·Form,添加了表單,但沒有指定動作型別,所以這裡預設的是Post
Post:表單在提交時,填寫在表單中的資料將在底層傳送到action=“url”中的url去
Get:表單在提交時,填寫在表單中的資料會和action=“url”中的url編碼在一起
·輸入框,這個會依賴此頁的強型別Model而對應生成。
Inherits="System.Web.Mvc.ViewPage<Web.Models.Customer>"
然後看控制器中,可以看到有兩個動作:
public ActionResult Create(){
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection collection)
{
try
{
return RedirectToAction("Index");
}
catch
{
return View();
}
}
第一個沒有引數,返回空檢視,它就是為導航到Create頁。且預設Method為get
第二個用於處理建立工作,它的Method被標籤修飾為Post,它只接受post動作。
還以列表頁Index為例,當點選
<%= Html.ActionLink("Create New", "Create") %>時,會get到Create動作。這時執行第一個動作,返回空檢視(其實這個檢視與返回一個沒有值的model一樣)
然後在建立時,提交表單,會提交到Create動作,這個時候接愛的謂詞為Post:[AcceptVerbs(HttpVerbs.Post)]
所以,在這個動作中做資料新增操作。
(1)引數為FormCollection collection
這個表單集合包含了post過來的表單元素。
[AcceptVerbs(HttpVerbs.Post)]public ActionResult Create(FormCollection collection)
{
try
{
Customer customer = new Customer
{
FirstName = collection["FirstName"],
LastName=collection["LastName"]
};
dd.Add(customer);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
(2)引數為持久實體
[AcceptVerbs(HttpVerbs.Post)]public ActionResult Create(Customer customer)
{
try
{
dd.Add(customer);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
這個比較方便。
(3)通過Form方法得到引數。
string strFirstName = Request.Form["FirstName"].ToString();string strLastName = Request.Form["LastName"].ToString();
這個與FormCollection 相同
Index
|
(三)刪除與編輯與上面的同理
例如:刪除可以get方式傳遞一個id值
(四)檔案上傳
如果有檔案上傳時,要把Form的
enctype="multipart/form-data"
屬性設定一下。
HTML enctype 屬性 enctype 屬性 -- 代表HTML表單資料的編碼方式 application/x-www-form-urlencoded:窗體資料被編碼為名稱/值對.這是標準的編碼格式. multipart/form-data:窗體資料被編碼為一條訊息,頁上的每個控制元件對應訊息中的一個部分. text/plain:窗體資料以純文字形式進行編碼,其中不含任何控制元件或格式字元. |
Form的這個屬性的預設值是:application/x-www-form-urlencoded
在http頭中可以看到:Content-Type:application/x-www-form-urlencoded
<input type="file" name="upfile1" />
注意:上傳控制元件的name屬性一定要設定,否則提交附件無效!
(1)以預設方式提交文字
FirstName:
LastName:
提交建立:
傳送的資料是:
FirstName:鬆
LastName:武
(2)以預設方式提交上傳檔案
現在發現,上傳檔案不能提交到伺服器。
檢視提交的內容,可以看到:
FirstName=q1&LastName=q2
兩個文字屬性以kv對傳到伺服器,而附件:
upfile1=C:\Documents and Settings\Administrator\妗岄潰\Image76.gif
只有一個地址而已
(3) 改用multipart/form-data
這個時候,在http頭及提交的資料流裡可以看到:
Content-Type:multipart/form-data; boundary=---------------------------7daf1ec01dc -----------------------------7daf1ec01dc Content-Disposition: form-data; name="FirstName" x -----------------------------7daf1ec01dc Content-Disposition: form-data; name="LastName" X Content-Disposition: form-data; name="upfile1"; filename="C:\Documents and Settings\Administrator\妗岄潰\Image76.gif" Content-Type: image/gif 二進位制 |
以上貼出部分內容。
現在,全部的值都可以得到了。
[AcceptVerbs(HttpVerbs.Post)]public ActionResult Create(FormCollection collection)
{
try
{
Customer customer = new Customer
{
FirstName = collection["FirstName"],
LastName = collection["LastName"]
};
dd.Add(customer);
if (Request.Files.Count > 0)
{
Request.Files[0].SaveAs(Server.MapPath("../uploadlist/xx.gif"));
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}