Mvc项目实例 MvcMusicStore

原文链接: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 { getset; }

        public List<string> Genres { getset; }

    }

}

 

 

信息传输类改完之后,我们要修改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 { getset; }

    }

}

 

Album.cs

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

 

namespace MvcMusicStore.Models

{

    public class Album

    {

        public string Title { getset; }

        public Genre Genre { getset; }

    }

}

 

向ViewModels文件里添加新类StoreBrowseViewModel,做为复杂信息传输的介质

引用类库

using MvcMusicStore.Models;

 

修改StoreBrowseViewModel类

    public class StoreBrowseViewModel

    {

        public Genre Genre { getset; }

        public List<Album> Albums { getset; }

    }

修改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

重新运行整个项目,查看效果.

posted @ 2012-05-18 16:35  bdstjk  阅读(13917)  评论(0编辑  收藏  举报