1. 程式人生 > >MVC基礎——引數與值傳遞,提交資料

MVC基礎——引數與值傳遞,提交資料

準備工作:

現在新增Customer控制器,同時,在建立控制器的時候,新增Create,Delete,Detail動作。

Customer的模型結構為:

Customer類:CustomerID,LastName,FirstName

現在控制器情況為: 

複製程式碼 程式碼 public class CustomerController : Controller
{
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Details(int
 id)
        {
            return View();
        }

        public ActionResult Create()
        {
            return View();
        } 

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(FormCollection collection)
        {
            try
            {
                 return
 RedirectToAction("Index");
            }
            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

CustomerId

FirstName

LastName

3

Tom

編輯 | 詳細

2

Tom

Song

編輯 | 詳細

現在點選第一條的詳細,會發生什麼事:

<%= 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

CustomerId

FirstName

LastName

3

Tom

編輯 | 詳細

2

Tom

Song

編輯 | 詳細

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

CustomerId

FirstName

LastName

2

Tom

Song

編輯 | 詳細

3

Tom

編輯 | 詳細

4

編輯 | 詳細

5

編輯 | 詳細

6

編輯 | 詳細

(三)刪除與編輯與上面的同理

例如:刪除可以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();
    }
}