原文鏈接:http://www.cnblogs.com/wenming205/archive/2010/08/08/1795341.html
文章不錯,看完之后搭建項目就沒什么問題了,其他很多就是經驗問題了
做過webform的,其實也就需要知道怎么把頁面和C#代碼關聯起來,看看這個不錯
一、簡介
此項目為.Net Mvc學習試例,原版的項目可從www.asp.net網站上下載;
在學習的過程中,我們將通過.net mvc2來創建一個音樂倉儲系統。整個應用程序包括三個部分,分別為:選購、結帳和后台管理
二、預備知識
在學習此項目時,最好具用Linq知識。在這里推薦博客園里LoveCherry的一步一步學Linq to sql
http://www.cnblogs.com/lovecherry/archive/2007/08/13/853754.html
三、項目開始
第一節 搭建基本開發准備
項目開發環境
開發工具:vs2010旗艦版
使用迅雷可從此連接下載;
thunder://QUFlZDJrOi8vfGZpbGV8Y25fdmlzdWFsX3N0dWRpb18yMDEwX3VsdGltYXRlX3g4Nl9kdmRfNTMyMzQ3Lmlzb3wyN
jg1OTgyNzIwfDRhZTYyMjg5MzNkZGU0OWQ5YmZhNGMzNDY3YzgzMWMyfC9aWg==
數據庫:sqlserver2000或更高,此項目中我采用的是sqlserver2005
第二節 新建MVC項目
打開vs2010 選中文件à新建à項目

將打一個新建項目對話框,

1. 選擇.net framework4平台
2. 選擇web模板中 Asp.net MVC2空web應用程序
3. 修改項目名稱為MvcMusicStore ,然后點擊確定

項目中默認新建了一些文件夾,它們的作用如下:
| 文件夾名稱 |
作用 |
| /Controllers |
存儲控制器文件,處理頁面傳入的請求,和返回數據庫處理文件 |
| /Views |
界面或頁面模板 |
| /Models |
數據庫業務實體類及數據類 |
| /Content |
存儲圖片,樣式表,或其它靜態文件 |
| /Scripts |
存放自定義javascript文件 |
| /App_Data |
存放數據庫文件 |
控制器(Controller)
添加一個HomeController
鼠標右擊Controller文件夾,à添加à控制器 打開添加控制器對話框,把控制器名稱修改為HomeController à點擊添加.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcMusicStore.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
}
}
為了更新簡單的認識控制器,我們修改HomeController 讓其返回一個字符串
1. 把Index函數返回的ActoinResult改為string
2. 修改return語句
修改后代碼為:
// GET: /Home/
public string Index()
{
return "Hello from Home";
}
運行項目查看效果

注明:請不要錄入上面的地址去瀏覽;在vs中自帶的服務器會隨機分配端口。
下面我們將為項目倉儲控制器它有三個模塊它們分別為
1. 倉儲首頁模塊
2. 列表模塊
3. 指定相冊的詳細模塊
添加控制器和方法

代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcMusicStore.Controllers
{
public class StoreController : Controller
{
//
// GET: /Store/
public string Index()
{
return "Hello from Store.Index()";
}
//
// GET: /Store/Browse
public string Browse()
{
return "Hello from Store.Browse()";
}
//
// GET: /Store/Details
public string Details()
{
return "Hello from Store.Details()";
}
}
}
再次運行項目,瀏覽/Store/Detials

從上面頁面中我們看到,僅僅傳地址而不傳參數是無法瀏覽特定相冊信息的。下面我們修改控制器的Details方法
// GET: /Store/Details/5
public string Details(int id)
{
string message = "Store.Details,ID=" + id;
return Server.HtmlEncode(message);
}
運行效果如下

在傳輸入參數時,為什么不是/store/detals/?id=6呢? 這里我們看一下Global.asax文件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace MvcMusicStore
{
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // 路由名稱
"{controller}/{action}/{id}", // 帶有iD參?數的URL
new { controller = "Home", action = "Index", id = UrlParameter.Optional } //參數默認值
);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
}
}
}
其中這段
routes.MapRoute(
"Default", // 路由名稱
"{controller}/{action}/{id}", // 帶有iD參?數的URL
new { controller = "Home", action = "Index", id = UrlParameter.Optional } //參數默認值
);
說明地址欄中第二個/后面的值就是參數id的默認值,所以當我瀏覽store/details/6時,就說明參數id的值為6
那么,我們要傳其它值時,怎么辦呢?還好.net mvc框架中早已經考慮到,我們不必再去寫相應的路由。 我們接着修改controller中的代碼。
//
// GET: /Store/Browse
public string Browse()
{
string message = "Store.Browse, Genre=" +
Server.HtmlEncode(Request.QueryString["genre"]);
return Server.HtmlEncode(message);
}
運行效果如下:

說明:在程序中我們應用到Server.HtmlEncode 方法來處理Request.Querystring[“genre”] 是為了防止javascript注入和修改瀏覽地址
視圖和視圖模塊
這里我們要引入一個概念視圖模塊;
在mvc項目中重點體現的是Model ,View 和Controller三個部分。這三個部分中View部分負責顯示,一般是一些顯示模板;
Controller控制器,類似於一個中間轉化器,處理瀏覽器發過來的請求,傳向指定的方法,調用Model 來和數據庫交互信息;
Model模塊層,處理數據庫信息。
在這個過程中出現一個問題就是View 和Model數據通過誰傳遞,怎么傳遞?
在.net mvc中增加了兩個數據類型,ViewData 和TempData
雖然ViewData和TempData都可以傳遞弱類型數據,但是兩者的使用是有區別的:
ViewData的生命周期和View相同, 只對當前View有效.
TempData保存在Session中, Controller每次執行請求的時候會從Session中獲取TempData並刪除
Session, 獲取完TempData數據后雖然保存在內部的字典對象中,但是TempData集合的每個條目訪問一次后就從字典表中刪除.
也就是說TempData的數據至多只能經過一次Controller傳遞.
為何TempData只能夠在Controll中傳遞一次? 因為SessionStateTempDataProvider.LoadTempData方法(在TempDataDictionary.Load中調用)在從ControllerContext的Session中讀取了TempData數據后, 會清空Session:
使用模板
使用mvc模板為程序公共元素設置信息
找到Views文件夾,選中Shared文件夾,右健單擊à添加à新建項—>選中Mvc2視圖母板
把文件名稱設置為Site.master à添加


添加成功后,向母板頁中添加樣式表 然后添加一些html標記。代碼如下:
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<link href="/Content/Site.css" rel="stylesheet" type="text/css" />
<title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
</head>
<body>
<div>
<div id="header">
<h1>ASP.NET MVC Music Store</h1>
<ul id="navlist">
<li class="first"><a href="/" id="current">Home</a></li>
<li> <a href="/Store/">Store</a></li>
</ul>
</div>
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
</div>
</body>
</html>
添加一個視圖模板
首先,我們要修改HomeController
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcMusicStore.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
}
}
選中函數Index() ,然后右鍵單擊Index 選擇添加視圖



修改添加Index視圖代碼如下:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>This is the Homepage</h2>
</asp:Content>
再次運行項目

使用ViewModel向View傳輸入信息
為項目創建一個新的文件夾,將其命名為ViewModels

在信息傳輸入時分為兩類一是簡單信息另一個是復雜信息兩類;通過綁定視力的強類型數據對應的類,來傳遞信息
1. 簡單信息傳輸
選中ViewModels文件夾,右鍵à添加類 StoreIndexViewModel
代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcMusicStore.ViewModels
{
public class StoreIndexViewModel
{
public int NumberOfGenres { get; set; }
public List<string> Genres { get; set; }
}
}
信息傳輸類改完之后,我們要修改Controller文件,使用Controller把數據傳輸入到視圖中;
找到StoreController 修改其index方法如下
// GET: /Store/
public ActionResult Index()
{
var genres=new List<string>{"Rock","Jazz","Country","Pop","Disco"};
var viewModel=new StoreIndexViewModel{
NumberOfGenres=genres.Count,
Genres=genres
};
return View(viewModel);
}
重新編譯整個項目
選中Index添加對應視圖,選中“創建強類型視圖“ 在“視圖數據類”里選中創建的ViewModels.StoreIndexViewModel類 à添加

修改視圖代碼如下:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<MvcMusicStore.ViewModels.StoreIndexViewModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Index
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Browse Genres</h2>
<p> select from <%:Model.NumberOfGenres %> Genres:</p>
<ul>
<%foreach (string genreName in Model.Genres)
{ %>
<li>
<%:genreName %>
</li>
<%} %>
</ul>
</asp:Content>

2. 復雜信息傳輸
首先我們在Models文件夾里添加兩個類。一是Albums.cs 另一個是Genre.cs
代碼分別如下:
Genre.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcMusicStore.Models
{
public class Genre
{
public string Name { get; set; }
}
}
Album.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcMusicStore.Models
{
public class Album
{
public string Title { get; set; }
public Genre Genre { get; set; }
}
}
向ViewModels文件里添加新類StoreBrowseViewModel,做為復雜信息傳輸的介質
引用類庫
using MvcMusicStore.Models;
修改StoreBrowseViewModel類
public class StoreBrowseViewModel
{
public Genre Genre { get; set; }
public List<Album> Albums { get; set; }
}
、
修改StoreController類
// GET: /Store/Browse
public ActionResult Browse()
{
string genreName =
Server.HtmlEncode(Request.QueryString["genre"]);
var genre = new Genre
{
Name = genreName
};
var albums = new List<Album>();
albums.Add(new Album { Title = genreName + "Album1" });
albums.Add(new Album { Title = genreName + "Album2" });
var viewModel = new StoreBrowseViewModel
{
Genre = genre,
Albums = albums
};
return View(viewModel);
}
然后選中Browse方法,右鍵單擊添加視圖 à創建強類型視圖à 選擇類為MvcMusicStore.ViewModels.StoreBrowseViewModelà添加
修改視圖代碼如下:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Browsing Genre: <%:Model.Genre.Name %></h2>
<ul>
<%foreach (var album in Model.Albums)
{ %>
<li><%:album.Title %></li>
<%} %>
</ul>
</asp:Content>
接着,我們再修改控制器StoreController里的Details方法
//
// GET: /Store/Details/5
public ActionResult Details(int id)
{
var album = new Album
{
Title = "Sample Album"
};
return View(album);
}
而后,選種Details方法,右鍵添加視圖,選擇強類型為Models.Album ,最后修改details視圖的代碼如下:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Album <%:Model.Title%></h2>
</asp:Content>
至此我們把StoreController里的Index ,Browse和Details模塊全部實現了。 可還有一個問題,就是頁面間如何連接。
下面我們接着修改代碼,為頁面間信息添加鏈接
找到Views文件夾里的Browse文件里的Index修改代碼如下:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Browse Genres</h2>
<p> select from <%:Model.NumberOfGenres %> Genres:</p>
<ul>
<%foreach (string genreName in Model.Genres)
{ %>
<li>
<%:Html.ActionLink(genreName,"Browse","Store",new {genre=genreName},null) %>
</li>
<%} %>
</ul>
</asp:Content>
說明:如果想通過ActionLink傳輸更多參數。
<%:Html.ActionLink(genreName,"Browse","Store",new {genre=genreName,gen="aa"},null) %>
運行結果為:/Store/Browse?genre=Jazz&gen=aa
重新運行整個項目,查看效果.
