zoukankan      html  css  js  c++  java
  • ASP.NET MVC 入门5、View与ViewData

    本系列文章基于ASP.NET MVC Preview5.

    view在MVC模式中与用户进行最直接的接触,它负责数据的呈现。这里要注意一点就是,view只是负责数据的呈现,所以我们应该要尽量让view中不涉及业务逻辑的处理。

    我们来添加一个Blog首页的view。在安装了ASP.NET MVC后,我们在添加新项目的时候可以看到有MVC的view模板:

    image 
    注:如果你的是中文版的VS,安装完后可能会出现找不到这个模板的现象,你可以参考在中文版VS 08中安装MVC这篇文章设置一下。

    其中MVC View Content Page是有母版页的。我们在Views/Home目录下添加一个MVC View Content Page,并选择我们Views/Shared目录下的Site.Master母版页:

    public partial class Index : ViewPage
    {
    }

    ASP.NET MVC默认是使用WebForm来作为view的。所以我们看到新建的aspx页面继承自ViewPage,如果使用aspx页面作为ASP.NET MVC的视图引擎,则所有的aspx页面都必须继承自ViewPage。我们再看一下ViewPage:

    image

    我们看到ViewPage继承自ASP.NET WebForm的Page页,还实现了IViewDataContainer接口,同时还提供了一些Helper类的实例。我们可以使用ViewData来从Controller中往view页面中传递数据。下面我们在HomeController中的Index Action中取出Posts列表,然后在View中显示。我们先在Controller中取出数据,前面说过,为了方便,我们会直接使用BlogEngine的Model层来作为我们这个4mvcBlog的Model。所以我们的代码如下:

    public ActionResult Index(int? id)
    {
        ViewData[
    "Title"] = BlogSettings.Instance.Name;

        List
    <IPublishable> posts = BlogEngine.Core.Post.Posts
            .ConvertAll(
    new Converter<Post, IPublishable>(delegate(Post p) { return p as IPublishable; }));

       
    int pageIndex = (id != null && id.HasValue && id.Value > 0) ? id.Value : 1;
       
    int pageSize = Math.Min(posts.Count, BlogSettings.Instance.PostsPerPage);
       
    if ((pageIndex - 1) * pageSize + pageSize > posts.Count)
        {
           
    return ShowMsg(new List<string>() { "页码超出范围" });
        }
        posts
    = posts.GetRange((pageIndex - 1) * pageSize, pageSize);

        ViewData[
    "Posts"] = posts; //向ViewData中传数据

       
    //这里返回View给客户端,如果不指定要返回的View的名称,
       
    //就是返回和Action同名的View,
       
    //也就是相当于return View("Index");
        return View();
    }

    默认的WebFormView搜索View的顺序是按如下顺序搜索的:

    image

    其中{1}为ControllerName,{0}为ActionName。MasterLocationFormats为母版页的搜索顺序。

    在上面的代码中我们使用ViewData["Posts"]向View页面传递数据,然后我们就可以在View中取出数据并呈现给用户,Views/Home/Index.aspx页面的部分代码如下:

    image

    如上红色框中的代码,我们可以从ViewData中取出数据,并转换为相应的类型。在这里我们发现ViewData要做一个类型的转换,其实我们可以将ViewData.Model设置为强类型,只需将我们的View页面继承自ViewPage<TModel>就可以了:

    image

    然后在Controller里面return View()的时候直接给ViewData.Model传值,如下所示:

    image

    然后在View中我们可以直接从强类型的ViewData.Model中取值:

    image

    由上面的代码我看可以看出ViewData.Model就是List<IPublishable>类型,并不需要再进行类型的转换。

    ViewData还有一个Eval的方法,我们可以使用这个方法从ViewData中取值。假如我么在Action中使用return View(Post);给View传递一篇日志的数据。而Post有一个Previous的属性指向前一篇日志,则我们可以在View页面中可以这样来取值:

    <%= ViewData.Eval("Previous.Title")%>

    但是如果使用我最后提供的示例Blog程序的代码这样在取值的时候直接在里面使用"."来取值,你会发现取不了值。因为BlogEngine里面的BusinessBase类实现了IDataErrorInfo接口,而IDataErrorInfo有一个索引器,也就是说BusinessBase有一个索引器,就因为有一个索引器,使Eval中不能用点来取值(不知道是不是bug?)。

    补充:上面说到的不是Bug,是因为BusinessBase实现了IDataErrorInfo接口,该接口有个索引器,导致ViewData.Eval()方法调用时搜索索引器的值时返回String.Empty而使ViewData.Eval()认为是找到值了,从而失效。

    image

    我们可以将return string.Empty修改为return null,这样就可以了。

    好,这一部分就先到这里吧。Enjoy!Post by Q.Lee.lulu

    本文示例Blog的代码:4mvcBlog_5.rar

    ---------------------------------------------------------------------

    更多内容,请关注http://blog.51mvc.com/http://bbs.51mvc.com/

  • 相关阅读:
    URAL 2046 A
    URAL 2056 Scholarship 水题
    Codeforces Gym 100286I iSharp 水题
    Codeforces Gym H. Hell on the Markets 贪心
    Codeforces Gym 100286G Giant Screen 水题
    Codeforces Gym 100286B Blind Walk DFS
    Codeforces Gym 100286F Problem F. Fibonacci System 数位DP
    Codeforces Gym 100286A. Aerodynamics 计算几何 求二维凸包面积
    Codeforces Gym 100418K Cards 暴力打表
    Codeforces Gym 100418J Lucky tickets 数位DP
  • 原文地址:https://www.cnblogs.com/cxd4321/p/1565361.html
Copyright © 2011-2022 走看看