Mvc项目实例 MvcMusicStore【原文:https://www.cnblogs.com/bdstjk/archive/2012/05/18/2519850.html】
原文链接: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 à点击添加.
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Web;
usingSystem.Web.Mvc;
namespaceMvcMusicStore.Controllers
{
publicclassHomeController:Controller
{
//
// GET: /Home/
publicActionResultIndex()
{
returnView();
}
}
}
为了更新简单的认识控制器,我们修改HomeController 让其返回一个字符串
1. 把Index函数返回的ActoinResult改为string
2. 修改return语句
修改后代码为:
// GET: /Home/
publicstringIndex()
{
return"Hello from Home";
}
运行项目查看效果
注明:请不要录入上面的地址去浏览;在vs中自带的服务器会随机分配端口。
下面我们将为项目仓储控制器它有三个模块它们分别为
1. 仓储首页模块
2. 列表模块
3. 指定相册的详细模块
添加控制器和方法
代码如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Web;
usingSystem.Web.Mvc;
namespaceMvcMusicStore.Controllers
{
publicclassStoreController:Controller
{
//
// GET: /Store/
publicstringIndex()
{
return"Hello from Store.Index()";
}
//
// GET: /Store/Browse
publicstringBrowse()
{
return"Hello from Store.Browse()";
}
//
// GET: /Store/Details
publicstringDetails()
{
return"Hello from Store.Details()";
}
}
}
再次运行项目,浏览/Store/Detials
从上面页面中我们看到,仅仅传地址而不传参数是无法浏览特定相册信息的。下面我们修改控制器的Details方法
// GET: /Store/Details/5
publicstringDetails(intid)
{
stringmessage ="Store.Details,ID="+ id;
returnServer.HtmlEncode(message);
}
运行效果如下
在传输入参数时,为什么不是/store/detals/?id=6呢? 这里我们看一下Global.asax文件
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Web;
usingSystem.Web.Mvc;
usingSystem.Web.Routing;
namespaceMvcMusicStore
{
publicclassMvcApplication: System.Web.HttpApplication
{
publicstaticvoidRegisterRoutes(RouteCollectionroutes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",// 路由名称
"{controller}/{action}/{id}",// 带有iD参?数的URL
new{ controller ="Home", action ="Index", id =UrlParameter.Optional }//参数默认值
);
}
protectedvoidApplication_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
publicstringBrowse()
{
stringmessage ="Store.Browse, Genre="+
Server.HtmlEncode(Request.QueryString["genre"]);
returnServer.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标记。代码如下:
<%@MasterLanguage="C#"Inherits="System.Web.Mvc.ViewMasterPage"%>
ASP.NET MVC Music Store
Home
添加一个视图模板
首先,我们要修改HomeController
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Web;
usingSystem.Web.Mvc;
namespaceMvcMusicStore.Controllers
{
publicclassHomeController:Controller
{
//
// GET: /Home/
publicActionResultIndex()
{
returnView();
}
}
}
选中函数Index() ,然后右键单击Index 选择添加视图
修改添加Index视图代码如下:
This is the Homepage
再次运行项目
使用ViewModel向View传输入信息
为项目创建一个新的文件夹,将其命名为ViewModels
在信息传输入时分为两类一是简单信息另一个是复杂信息两类;通过绑定视力的强类型数据对应的类,来传递信息
1. 简单信息传输
选中ViewModels文件夹,右键à添加类StoreIndexViewModel
代码如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Web;
namespaceMvcMusicStore.ViewModels
{
publicclassStoreIndexViewModel
{
publicintNumberOfGenres {get;set; }
publicList Genres {get;set; }
}
}
信息传输类改完之后,我们要修改Controller文件,使用Controller把数据传输入到视图中;
找到StoreController 修改其index方法如下
// GET: /Store/
publicActionResultIndex()
{
vargenres=newList{"Rock","Jazz","Country","Pop","Disco"};
varviewModel=newStoreIndexViewModel{
NumberOfGenres=genres.Count,
Genres=genres
};
returnView(viewModel);
}
重新编译整个项目
选中Index添加对应视图,选中“创建强类型视图“ 在“视图数据类”里选中创建的ViewModels.StoreIndexViewModel类 à添加
修改视图代码如下:
<%@PageTitle=""Language="C#"MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage"%>
Index
Browse Genres
select from <%:Model.NumberOfGenres %> Genres:
<%foreach(stringgenreNameinModel.Genres)
{ %>
<%:genreName %>
<%} %>
2. 复杂信息传输
首先我们在Models文件夹里添加两个类。一是Albums.cs 另一个是Genre.cs
代码分别如下:
Genre.cs
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Web;
namespaceMvcMusicStore.Models
{
publicclassGenre
{
publicstringName {get;set; }
}
}
Album.cs
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Web;
namespaceMvcMusicStore.Models
{
publicclassAlbum
{
publicstringTitle {get;set; }
publicGenreGenre {get;set; }
}
}
向ViewModels文件里添加新类StoreBrowseViewModel,做为复杂信息传输的介质
引用类库
usingMvcMusicStore.Models;
修改StoreBrowseViewModel类
publicclassStoreBrowseViewModel
{
publicGenreGenre {get;set; }
publicList Albums {get;set; }
}
、
修改StoreController类
// GET: /Store/Browse
publicActionResultBrowse()
{
stringgenreName =
Server.HtmlEncode(Request.QueryString["genre"]);
vargenre =newGenre
{
Name = genreName
};
varalbums =newList();
albums.Add(newAlbum{ Title = genreName +"Album1"});
albums.Add(newAlbum{ Title = genreName +"Album2"});
varviewModel =newStoreBrowseViewModel
{
Genre = genre,
Albums = albums
};
returnView(viewModel);
}
然后选中Browse方法,右键单击添加视图 à创建强类型视图à 选择类为MvcMusicStore.ViewModels.StoreBrowseViewModelà添加
修改视图代码如下:
Browsing Genre: <%:Model.Genre.Name %>
<%foreach(varalbuminModel.Albums)
{ %>
<%} %>
接着,我们再修改控制器StoreController里的Details方法
//
// GET: /Store/Details/5
publicActionResultDetails(intid)
{
varalbum =newAlbum
{
Title ="Sample Album"
};
returnView(album);
}
而后,选种Details方法,右键添加视图,选择强类型为Models.Album ,最后修改details视图的代码如下:
Album <%:Model.Title%>
至此我们把StoreController里的Index ,Browse和Details模块全部实现了。 可还有一个问题,就是页面间如何连接。
下面我们接着修改代码,为页面间信息添加链接
找到Views文件夹里的Browse文件里的Index修改代码如下:
Browse Genres
select from <%:Model.NumberOfGenres %> Genres:
<%foreach(stringgenreNameinModel.Genres)
{ %>
<%:Html.ActionLink(genreName,"Browse","Store",new{genre=genreName},null) %>
<%} %>
说明:如果想通过ActionLink传输更多参数。
<%:Html.ActionLink(genreName,"Browse","Store",new{genre=genreName,gen="aa"},null) %>
运行结果为:/Store/Browse?genre=Jazz&gen=aa
重新运行整个项目,查看效果.