• ASP.NET MVC 浅析


    学习ASP.NET已经很久了,一直以来觉得ASP.NET 的MVC模式和WinForm的三层架构差不多。每次老师讲到MVC的时候都是略过不讲的,所以仅仅凭自己的一点点浅薄的认识,就以为MVC就是三层架构。这种想法不仅仅是错的,更是一种不负责任,不求甚解,人云亦云的不端正的科学态度。作为一名IT工作者,更应该以一种科学严谨的态度对待知识和学问,更应该学会独立的思考,而不是随波逐流,人云亦云。

    这些天花了一些时间来把ASP.NET MVC 模式了解了下,觉得自己之前的认识实在是大错特错了。三层架构的模式在WinFom程序里边运用的比较多,现在的开发已经不拘于具体的模式了,甚至有N层架构的出现,我们要做的是如何在不拘于具体模式的前提下,提高软件系统的性能、开发的高效性、代码的复用性。MVC模式,ASP.NET MVC Framework是微软官方提供的MVC模式编写ASP.NET Web应用程序的一个框架,MVC(Model-View-Controller)用于表示一种软件架构模式.它把软件系统分为三个基本部分:模型(Model),视图(View)和控制器(Controller).,和三层架构的相似之处在于分层的思想,MVC模式很好的实现了UI、业务逻辑、数据库访问的分层,在mvc中这三部分分别被称之为视图(View)

    控制器(Controller)和模型(Model),下面就这三部分的内容一一介绍。

    与ASP.NET项目不同,ASP.NET MVC 项目建成之后项目文件目录如下:

    (基本的文件夹的 用途):

    • App_Data :这个目录跟我们一般的ASP.NET website是一样的,用于存放数据。
    • Content :这个目录是建议用来存放一下资源文件的。例如CSS、JS、图片等等。当然你不愿意的话,完全可以不放到这里来。
    • Controllers :这个目录是建议将Controller类都放到这里来,方便管理。Controller类的命名必须以Controller结尾,例如一个名为Home的Controller则要命名为HomeController。
    • Models :这个目录是建议用来存放你的业务实体、数据访问层代码的类的。当然,更好的做法我觉得应该是将Models独立为一个类库。
    • Views :在默认情况下,所有的 view文件都必须放到这个目录下来,每一个Controller对应一个子目录,而且子目录的命名必须以Controller的命名一样。例如,HomeController的view就应该放到Home子目录中。我们见到Views目录下还有一个Shared的子目录,这个子目录是用于存放一些共享的view的,例如Error.aspx和Site.Master。Controller在Views\ControllerNmae 中找不到指定的view的时候,会到Shared中去寻找

    下面进入具体的学习:

    一、路由。

    谈到MVC模式就不得不谈到路由,和传统的WebForm模式不同,WebFrom采用的是事件驱动模式,MVC采用的是路由驱动模式。ASP.NET路由模块负责将即将到来的浏览器请求映射到特定的MVC控制器动作,然后再由控制器进行调配,采取一些列的动作最后再将相应的视图呈现给大家。

    在一个route中,通过在大括号中放一个占位符来定义( { and } )。当解析URL的时候,符号"/""."被作为一个定义符来解析,而定义符之间的值则匹配到占位符中。route定义中不在大括号中的信息则作为常量值。下面是一些示例URL

    Valid route definitions

    Examples of matching URL

    {controller}/{action}/{id}

    /Products/show/beverages

    {table}/Details.aspx

    /Products/Details.aspx

    blog/{action}/{entry}

    /blog/show/123

    {reporttype}/{year}/{month}/{day}

    /sales/2008/1/5

    通常,我们在Global.asax文件中的Application_Start事件中添加routes,这确保routes在程序启动的时候就可用,而且也允许在你进行单元测试的时候直接调用该方法。

    下面的示例是Global.asax中的代码,演示了添加一个包含两个URL参数actioncategoryName的Route对象:

        public class MvcApplication : System.Web.HttpApplication     {         public static void RegisterRoutes(RouteCollection routes)         {             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

                routes.MapRoute(                 "Default", // 路由名称                 "{controller}/{action}/{id}", // 带有参数的 URL                 new                 {                     controller = "Home",                     action = "Index",                     id = UrlParameter.Optional                 } // 参数默认值             );

            }

            protected void Application_Start()         {             AreaRegistration.RegisterAllAreas();

               //在程序启动的时候注册我们前面定义的Route规则

                RegisterRoutes(RouteTable.Routes);         } }

    这些均为默认的设置

    如果有特殊的需要也可以自定义配置路由规则,如下所示:(自定义路由)

    routes.MapRoute(                "Category",                                              // Route name                "Category/{Detailid}",                           // URL with parameters                new{ controller ="Category", action ="Details" }  // Parameter defaults

                );

    自定义路由添加到路由表中的路由顺序非常重要。新自定义Category路由在现有的Default路由前面。如果你将这个顺序颠倒过来,那么Default路由将总是被调用,而不是自定义路由。

    当一个MVC应用程序首次运行时,会调用Application_Start()方法。这个方法随后调用了RegisterRoutes()方法。RegisterRoutes()方法创建了路由表。

    默认的路由表包含了一个路由(名叫Default)。Default路由将URL的第一部分映射到控制器名,URL的第二部分映射到控制器动作,第三个部分映射到一个叫做id的参数。

    假设你在浏览器的地址栏输入了下面的URL:

    /Home/Index/1

    默认的路由将这个URL映射为下面的参数:

    Controller = Home

    Action = Index

    id = 1

    当你请求URL /Home/Index/1时,将会执行下面的代码:

    HomeController.Index(1)

    Default路由包含了所有三个参数的默认值。如果你不提供控制器,那么控制器参数默认值为Home。如果你不提供动作,动作参数默认为值Index。最后,如果你不提供id,id参数默认为空字符串

    此时对应的控制器中的方法为HomeController.cs

    public ActionResult Index()         {              // imgDBEntity = new ImageDBEntity();             //ViewData["Message"] = "欢迎使用 ASP.NET MVC!";             //ViewData["Images"] = imgDBEntity.Imgs.ToList();             //return View(reporsitory.ListAll());

                 return View();         }

    另外在有些地方需要建立相应的路由约束,比如上面新添的路由Category,控制器公布的行动Details(int DetaillID)需要传入参数DetailID

    public class ProductController : Controller     {         public ActionResult Details(int DetaillID)         {             return View();         }     } 代码会匹配:

    /Category/12

    /Category/333

    等URL

    但是如果有非数字字符出现的URL

    /Category/abc

    则会提示报错访问的URL不存在

    另外比如你的Admin页不希望被访问到,这时就需要阻止某个路径匹配,这时候可以自定义一个路由,可以通过实现IRouteConstraint接口来实现一个自定义路由,它只描述了一个方法:

    bool Match(     HttpContextBase httpContext,     Route route,     string parameterName,     RouteValueDictionary values,     RouteDirection routeDirection )

    这个方法返回一个布尔值。如果返回了false,与约束相关联的路由将不会匹配浏览器请求

    实现接口

    public class LocalhostConstraint : IRouteConstraint     {         public bool Match             (                 HttpContextBase httpContext,                 Route route,                 string parameterName,                 RouteValueDictionary values,                 RouteDirection routeDirection             )         {             return httpContext.Request.IsLocal;         }

    同时在Globle.cs中做如下配置

    routes.MapRoute(                 "Admin",                 "Admin/{action}",                 new {controller="Admin"},                 new {isLocal=new LocalhostConstraint()}             );

    这样如果不是本机访问就无法访问到Admin页。

    二、视图(View)

    与ASP.NET不同的是它本身并没有具体呈现的某个页,它仅仅是将要到达浏览器的URL请求映射为一个控制器动作,然后控制器动作进行一些列的动作将视图返回

    例如:HomeController.cs中的Index动作

    public ActionResult Index()         {             ViewData["Message"] = "欢迎使用 ASP.NET MVC!";             return View();         }

    这个动作返回的是Index视图。我们所创建的大多动作都返回一个视图,但是动作是可以返回任何类型的动作结果的。

    Index()动作包含了下面一行代码:

    return View();

    这行的代码返回了一个视图,该视图在服务器上的路径必须和下面的路径一样:

    ViewsHomeIndex.aspx

    视图的路径由控制器和控制器动作的名称推断得出。

    与此同时你也可以显式地指明视图。下面一行代码返回了一个视图名为“Add”:

    return View("Add");

    当执行这行代码时,将会从下面的路径返回一个视图:

    ViewsHomeAdd.aspx

    接下来讲创建视图,视图的创建很简单,在View文件夹下建立和控制器同名的文件夹,比如本例的“Home”文件夹,然后在Home文件夹下点击右键添加,然后选择视图就可以了。

    一般我们来向视图添加内容的时候会用到<%%>,在试图页,我们可以通过<%%>脚本执行一条或多条语句,例如:

    <% Response.Write(DateTime.Now);%>

    因为我们可能要频繁的使用Response.Wirte()这个方法,所以微软对此进行的封装<%= %>与<% Response.Write();%>是等效的。

    除此之外,我们还可以通过HtmlHelper来生成视图内容,

    例如:

    <div >             <%using (Html.BeginForm())               { %>             <label for="firstName">First Name:</label>             <%=Html.TextBox("firstName")%>             <br />             <label for="lastName">Last Name:</label>             <%=Html.TextBox("lastName")%>             <%} %>             <br />             <input type="submit" value="Submit" />            </div>

    生成如下效果:

    在MVC3框架下可以直接这样用

    @using (Html.BeginForm())         {             @Html.ValidationSummary()             <P>Your Name:@Html.TextBoxFor(x=>x.Name)</P>             <p>Your Email:@Html.TextBoxFor(x=>x.Email)</p>             <p>Your Phone:@Html.TextBoxFor(x=>x.Phone)</p>       }         <input type="submit" value="Submit RSVP" />       

    在MVC中,构建数据是controller的工作,将数据作为HTML的呈现是View的工作,很明显这里有一个将数据从Controller传递到View的过程。可以通过ViewData属性来传递视图,

    HomeController.cs中  

    public ActionResult Index()         {             imgDBEntity = new ImageDBEntity();             ViewData["Message"] = "欢迎使用 ASP.NET MVC!";                         return View();         }

    在Index.aspx页

        <h2><%= Html.Encode(ViewData["Message"]) %></h2>

    这样就可以显示数据。

    与此同时,其中的一种方式就是通过ViewBag,ViewBag是Controller基类的一个成员,它是一个动态的对象,我们可以给它赋予任意的属性值,并在View中呈现

    public ViewResult Index()         {               ViewBag.Hello ="Olive";             return View();         }

    在Index.aspx

        <h2><%= Html.Encode(ViewBag.Hello) %></h2>

    三、控制器(Controller)

    在MVC模式中,控制器就相当于一个分发器,通过响应相应的行为,然后和Model层进行交互,提取请求所需的内容,进而返回一个视图,或者另一个行为。

    控制器的创建可以在项目的Controller文件下,点击右键添加Controller文件即可。

    例如HomeController.cs

    [HandleError]     public class HomeController : Controller     {         public ActionResult Index()         {             ViewData["Message"] = "欢迎使用 ASP.NET MVC!";             return View();         }         [AcceptVerbs(HttpVerbs.Post)]         public ActionResult Index(FormCollection formCollection)         {             var move=new  Movie();             move.ID = 3;             TryUpdateModel(move, new string[] { "firstName", "lastName" }, formCollection.ToValueProvider());             MoviesDataContext mv = new MoviesDataContext();             mv.Movie.InsertOnSubmit(move);                         return View("Index");

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

    我们上边所说的动作就是控制器的一个方法,当你在浏览器输入一个Url时,相应的控制器会执行相应的动作,也就是相应的方法。例如:

    http://localhost/Home/Index

    在本例中,Index()方法在HomeController类上被调用。一个控制器动作必须是控制器类的一个公共方法。控制器动作来使用的方法不能够重载。另外,控制器动作不能为静态方法。

    控制器动作执行完以后需要返回给浏览器一些东西,即我们所说的控制动作结果

    ASP.NET MVC框架支持六种标准类型的动作结果:

    1. ViewResult – 代表HTML及标记。
    2. EmptyResult – 代表无结果。
    3. RedirectResult – 代表重定向到一个新的URL。
    4. RedirectToRouteResult – 代表重定向到一个新的控制器动作。
    5. JsonResult – 代表一个JSON(Javascript Object Notation)结果,它可以用于AJAX应用程序。
    6. ContentResult – 代表着文本结果。

    所有这些动作结果都继承自ActionResult基类。在大多数情况下,控制器动作 ViewResult。ContentResult动作结果很特别。你可以使用ContentResult动作结果来将动作结果作为纯文本返回。

    四、模型(Model)

    MVC模型包含了所有MVC视图或者MVC控制器没有包含的应用程序逻辑,一个MVC模型包含了所有的应用程序业务和数据访问逻辑,所以模型往往被称作是MVC的核心。

    构建数据访问类的方法有很多,而且ASP.NET与任何数据访问都可以很好的融合,这里主要讲Liinq to Sql与MS数据库交互。

    首先在App_Data文件夹下创建数据库,然后再创建一个文件表 Imgs,具体如下:

    主键自增。

    下边接着创建Linq to Sql 类,在Model文件夹下右键添加,然后选中左侧列表里的Data项,选中里边的Linq to Sql 将会立即出现“对象关系设计器(Object Relational Designer)”。此时,你可以将数据库表从“服务器资源管理器(Server Explorer)”窗口中拖曳到“对象关系设计器”中,来创建代表着特定数据库表的LINQ to SQL类。这里我们添加Imgs 表。如图:


              public ActionResult Index(){
                   var dataContext = new ImgsDataContext();                var imgs = from m in dataContext.Imgs                     select m;                return View(imgs.ToList());           } 此时同时也要修改Index页的内容,进行数据的显示:

    代码如下:Index.aspx

                <div>            <%foreach (Imgs im in (IEnumerable)ViewData.Model)//要注意此出需要将ViewData.Model进行强制转换下否则无法进行佛reach遍历              {%>              <%=im.Name %>              <%=im.Title %>           <img src=" <%=im.Url %> " />

    <div>

    同时还要在页面的开始部位引入<%@ Import Namespace="MVC1.Models" %>命名空间 这样就可以很好的显示数据了

    效果如图:

    后记:这篇算是对这几天的学习的一个总结和反思吧,希望能对有兴趣的朋友有一点帮助。如果有说的不对的地方还请拍砖!

  • 相关阅读:
    ubuntu18安装paddle的cpu版本错误
    博客园的推荐150名大牛的地址
    课堂翻译
    小组介绍
    Sunshine小组
    项目进程
    总结
    布置的开发项目
    一周总结
    每周学习
  • 原文地址:https://www.cnblogs.com/Olive116/p/MVC.html
Copyright © 2020-2023  润新知