ASP.NET MVC 模型在视图中的传递

      最近刚学ASP.NET MVC,虽然只是敲了个简单的例程,但收获还是有的。

      MVC中最基本的东西就是:Model(模型),View(视图),Controller(控制器)。对于这三者的关系必须要非常清楚,尤其是在程序的运行中,这三者是怎样相互配合。简单来讲,控制器决定行为,模型存放数据,视图显示行为处理数据后的结果(或者是单纯的显示数据),实际上远比这个复杂得多。

      控制器由一系列操作组成,这些操作一般都是返回一个ActionResult,而ActionResult包括Json,View等等。先说说View。

      View()方法的使用非常简单。默认无参的重载版本返回的是与操作同名的视图,像是下面这样:

public ShoppingController : Controller{
    public ActionResult Index(){
         return View();
    }
}

      返回的就是/Views/Shopping/Index.cshtml。良好的MVC编程方式就是将相关的东西放在一起,像是将与ShoppingController有关的视图放在一个单独的文件夹Shopping就比较方便了。

      但是我们也可以指定该操作显示的视图,像是这样:

return View("Shopping");

      就不是显示默认的Index.cshtml,而是Shopping.cshtml。

      神奇的是,我们还可以通过View()传递模型给相应的视图。

      像是这样:

public ActionResult Index(int id){
    return View(id);
}

      就能将模型项System.Int32传递给视图Index.cshtml。神奇吧,int竟然是模型项!这没有什么好惊讶的,因为在MVC中,所谓的模型就只是一些C#类型,而System.Int32本身就是一个类型,所以,可以被当做模型项处理也是很正常的。
      传递模型项的目的当然就是使用该模型项,像是下面这样:

@model System.Int32

   ...

<h2>@Model</h2>

      我们就可以在视图中使用该模型项了,但是必须导入该模型,就是通过@(相当于C#的using,java的import)。导入模型必须指定命名空间,Int32的命名空间就是System.Int32,但如果是我们自定义的类型,就必须完整的指定该类型的命名空间。使用的时候,也是使用@(也就是Razor语法),@Model就是使用该模型id的值。当然,如果是自定义的类型,而且是包含有方法的类型,我们可以通过@Model.+ method来调用相关的方法。
      在写例程的时候,我就发现一个问题,就是会有这样的错误提示:未将对象引用设置为对象实例(NullReference)。这时我们就要细心的检查,是否有导入相关的模型,操作中有没有传参,参进来的模型项是否是null。

      向视图传递模型非常重要,比如说,我们想要在视图中显示一个模型的状态,那么,我们就必须将当前状态的模型传递给视图,这些都是通过简简单单的传参动作就能搞定。也许,我们可以在视图中引用该模型。确实,我们可以通过jQuery来通过HttpContext来获得该模型的相关状态,像是这样:

 function handleUpdate()
    {

        //Load and deserialize the returned JSON data
        var json = context.get_data();
        var data = Sys.Serialization.JavaScriptSerializer.deserialize(json);

        //Update the page elements
        if (data.ItemCount == 0) {
            $("#row-" + data.DeleteId).fadeOut("slow");
        }
        else
        {
            $("#item-count-" + data.DeleteId).text(data.ItemCount);
        }

        $("#cart-total").text(data.CartTotal);
        $("#update-message").text(data.Message);
        $("#cart-status").text("Cart(" + data.CartCount + ")");
    }

         相应的视图部分代码如:

 @foreach (var item in Model.CartItems)
    {
        <tr id ="row-@item.RecordId">
            <td>
                @Html.ActionLink(item.Album.Title, "Details", "Store", new{ id = item.AlbumId }, null)
            </td>
            <td>
                @item.Album.Price
            </td>
            <td id ="item-count-@item.RecordId">
                @item.Count
            </td>
            <td>
                <a href ="#" class ="RemoveLink" data-id ="@item.RecordId">Remove from cart</a>
            </td>
        </tr>
    }
    <tr>
        <td>
            Total
        </td>
        <td></td>
        <td></td>
        <td id ="cart-total">
            @Model.CartTotal
        </td>
    </tr>

       可以看到,jQuery是通过$来执行的,像是$("#cart-total")就是获取id为cart-total的HTML元素(好吧,这类似于javascript,但jQuery本来也就是一个javascript的开源库)。$并不是一个符号,它是一个函数名,就是一个函数的别名,像是这样:

$(function(){
   ...
});

      它就是参数中匿名函数的别名。当我们传递一个匿名函数作为参数的时候,就相当于我们假定该函数是在浏览器完成构建HTML的文档对象模型后立即执行的函数。这样的假定是有好处的,防止函数中与DOM(Document Object Model,即文档对象模型)相冲突的脚本,导致DOM无法顺利加载。
      如果认为$只是单纯的函数别名那就错了,它的作用远非如此。像是上面的获取元素id,就发挥了选择器的作用,我们还可以进一步指定相关元素中的子元素:

$("#cart-total img")

      这样就是指定id为cart-total的HTML元素中的img元素。如果是javascript,就需要好几个函数了。
      $的神奇之处就是,当它作为选择器的时候,会返回一个包含零个或多个匹配元素的封装集(wrapped set),我们还可以在该封装集上继续调用相关的方法(这些方法必须是依赖于封装集的方法,当然,它们同样是返回封装集)。这就是方法链。

     我不知道该原因是否是VS2012的问题,有时候我通过View()传递模型项的时候,会出现模型项为空的情况。可怕的是,我的模型传递并没有错误,视图也是该模型的强类型视图,就算调试也调试不出什么错误,结果我就关机重启,然后所有的问题都消失了!关机重启并不是解决问题的方式,只是因为那时候我想要睡觉了而已!如果有遇到类似问题的同学,也可以考虑和我一样:先关机睡一觉,然后再看看情况。

     


     

原文地址:https://www.cnblogs.com/wenjiang/p/2995676.html