文章出處

過完年, 大家都忙碌起來了, 我也不例外. 不過并不是忙碌于去面試找工作, 而是忙碌于現在手上的工作. 閑話不多說了, 進入今天的主題.

一、Index頁面在哪里

很奇怪, 在目錄bin下面的dll文件中, 都沒有看見過視圖的具體內容, 那么他們都去哪里了呢?

首先在Index頁面中, 加入一句話: @this.GetType().Assembly.Location

當程序運行起來之后, 就可以在頁面上看到運行的目錄. 

我的目錄是這個:

C:\Users\xxxxx\AppData\Local\Temp\Temporary ASP.NET Files\vs\31cf6113\79f9587c\App_Web_xwp5b05u.dll

后面我標黃的這一段, 是隨機數, 不用去管它. 拿到他直接反編譯, 來看一下效果: 

[Dynamic(new bool[] { false, true })]
public class _Page_Views_Home_Index_cshtml : WebViewPage<object>
{
    // Methods
    public override void Execute()
    {
        ((dynamic) base.ViewBag).Title = "Index";
        base.BeginContext("~/Views/Home/Index.cshtml", 0x23, 4, true);
        this.WriteLiteral("\r\n\r\n");
        base.EndContext("~/Views/Home/Index.cshtml", 0x23, 4, true);
        base.BeginContext("~/Views/Home/Index.cshtml", 40, 0x20, false);
        this.Write(base.GetType().Assembly.Location);
        base.EndContext("~/Views/Home/Index.cshtml", 40, 0x20, false);
        base.BeginContext("~/Views/Home/Index.cshtml", 0x48, 0x33, true);
        this.WriteLiteral("\r\n\r\n<h2>Index</h2>\r\n<table>\r\n    <tr>\r\n        <td>");
        base.EndContext("~/Views/Home/Index.cshtml", 0x48, 0x33, true);
        base.BeginContext("~/Views/Home/Index.cshtml", 0x7c, 10, false);
        this.Write(((dynamic) base.Model).Name);
        base.EndContext("~/Views/Home/Index.cshtml", 0x7c, 10, false);
        base.BeginContext("~/Views/Home/Index.cshtml", 0x86, 40, true);
        this.WriteLiteral("</td>\r\n    </tr>\r\n    <tr>\r\n        <td>");
        base.EndContext("~/Views/Home/Index.cshtml", 0x86, 40, true);
        base.BeginContext("~/Views/Home/Index.cshtml", 0xaf, 9, false);
        this.Write(((dynamic) base.Model).Age);
        base.EndContext("~/Views/Home/Index.cshtml", 0xaf, 9, false);
        base.BeginContext("~/Views/Home/Index.cshtml", 0xb8, 0x2c, true);
        this.WriteLiteral("</td>\r\n    </tr>\r\n</table>\r\n\r\n<script>\r\n    ");
        base.EndContext("~/Views/Home/Index.cshtml", 0xb8, 0x2c, true);
        base.BeginContext("~/Views/Home/Index.cshtml", 0x160, 11, true);
        this.WriteLiteral("\r\n</script>");
        base.EndContext("~/Views/Home/Index.cshtml", 0x160, 11, true);
    }

    // Properties
    protected global_asax ApplicationInstance
    {
        get
        {
            return (global_asax) this.Context.ApplicationInstance;
        }
    }
}

從這里看, 頁面上的那些普通的標簽語句都通過 this.WriteLiteral() 方法, 解析成字符串了. 而@Model.Name也解析出來了.

這里注意到, 是將Model轉成dynamic變量的. 那么, 我在View這里能不能傳一個dynamic的值呢? 這個在后面會給出demo.

在上一篇的 System.Web.Mvc.RazorView.RenderView()方法中, 有一句:WebPageRenderingBase startPage = null;

這里的 _Page_Views_Home_Index_cshtml 類, 就是間接繼承自 WebPageRenderingBase 類.

 

二、Razor的基本用法

在MVC中, 在前臺頁面, 可以借助Razor像后臺那樣編程. 然后通過 @變量 來輸出. 如:

@if (true)
{
    <table>
        <tr>
            <td>@Model.Name</td>
        </tr>
        <tr>
            <td>@Model.Age</td>
        </tr>
    </table>
}

括號里面, 可以直接寫html是因為編譯器能識別標簽, 知道該怎么去解析.

那么如果我在<script>標簽里面也這么寫, 如:

@if (true)
{
    alert(1);
}

這個是不行的, 因為沒有明顯的標志, 來讓編譯器識別, 里面的alert(1)是屬于html里面的還是C#語句. 識別不出來的.

那么這時候, 就需要借助別的東西來幫助識別了. 兩種方式 : 1. <text></text>  2. @:

<script>
    @if (true)
    {
        @: alert(1);
        <text>alert(2);</text>
    }
    else
    {
        @: alert('@DateTime.Now.ToString()');
    }
</script>

這兩種方式都是可以的, 就看個人習慣吧. 在使用<text>的時候, vs縮進的讓人看著難受. 就像下面這樣:

<script>
    @if (true)
    {
        @: alert(1);

        <text>
    alert(2);
    </text>

    }
    else
    {
        @: alert('@DateTime.Now.ToString()');

    }
</script>

兩種方式各有優缺點. <text></text>中間可以放很多內容. @:遇到多行時, 每一行都要加.

 

三、Model傳值

在View(model)這里可以傳遞后臺的變量, 那么這個model是存放在哪里的呢?

public TModel Model
{
    get
    {
        return this.ViewData.Model;
    }
}

看這里, 是存放在ViewData里面的. 那么也就是說, 我可以在后臺通過 ViewData.Model的方式來替換View(model)的方式來傳值. 事實上也是可以的.

那么一般類型的值, 肯定都是可以傳遞的. 上面也說到, 能不能傳遞dynamic的值呢?

答案是不可以直接傳遞的, 也就是說我不能這么傳遞: return View(dynamic), 那能不能傳遞匿名類型呢:return View(new {name="haha"}) ?

答案也是不可以直接傳遞. 

那么有沒有辦法來傳遞這些值呢? 當然可以, 不然我也不會這么問了. 

Demo1:

public ActionResult Index()
{
    dynamic model1 = new ExpandoObject();
    model1.Name = "ExpandoObject";
    model1.Age = 12;
    var res =   JsonConvert.DeserializeObject(JsonConvert.SerializeObject(model1));
    return View(res);
}

Index頁面還是上面的那個. 看一下結果:

這里我一遍序列化與反序列化, 就可以了. 這里的model1當然也可以是匿名類型. 

不過這種方式并不推薦使用吧, 也挺麻煩的, 多了一道序列化與反序列化.

 

目錄已同步


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()