• MVC中的View2(转)


    MVC中View是专门用来向浏览器显示结果的,它只负责把传入到View的数据展现给用户;

    一,自定义view引擎:实现IViewEngine接口

    namespaceSystem.Web.Mvc

    {

    publicinterface IViewEngine

    {

    ViewEngineResultFindView(ControllerContext controllerContext, string viewName,

    stringmasterName, bool useCache);

    ViewEngineResultFindPartialView(ControllerContext controllerContext,

    stringpartialViewName, bool useCache);

    voidReleaseView(ControllerContext controllerContext, IView view);

    }

    }

    ViewResult被处理时,.net会调用FindView或FindPartialView,最后返回的ViewEngineResult用来负责当.net需要一个view时的工作;

    ReleaseView是一个view生成结束后调用的

    publicViewEngineResult(IView view, IViewEngine viewEngine):正常处理

    或者public ViewEngineResult(IEnumerable<string>searchedLocations):当对应的view找不到时,反馈给用信息

    namespaceSystem.Web.Mvc

    {

    usingSystem.IO;

    publicinterface Iview

    {

    voidRender(ViewContext viewContext, TextWriter writer);

    }

    }

    1,自定义view

    using System.IO;

    using System.Web.Mvc;

    namespaceViews.Infrastructure.CustomViewEngine

    {

    publicclass DebugDataView : IView

    {

    publicvoid Render(ViewContext viewContext, TextWriter writer)

    {

    Write(writer,"---Routing Data---");

    foreach(string key in viewContext.RouteData.Values.Keys)

    {

    Write(writer,"Key: {0}, Value: {1}",

    key,viewContext.RouteData.Values[key]);

    }

    Write(writer,"---View Data---");

    foreach(string key in viewContext.ViewData.Keys)

    {

    Write(writer,"Key: {0}, Value: {1}", key,

    viewContext.ViewData[key]);

    }

    }

    privatevoid Write(TextWriter writer, string template, params object[] values)

    {

    writer.Write(string.Format(template,values) + "<p/>");

    }

    }

    }

    2,自定义ViewEngine

    namespaceViews.Infrastructure.CustomViewEngine

    {

    publicclass DebugDataViewEngine : IViewEngine

    {

    publicViewEngineResult FindView(ControllerContext controllerContext,

    stringviewName, string masterName, bool useCache)

    {

    if(viewName == "DebugData")

    {

    returnnew ViewEngineResult(new DebugDataView(), this);

    }

    else{

    returnnew ViewEngineResult(new string[] { "Debug Data View Engine" });

    }

    }

    publicViewEngineResult FindPartialView(ControllerContext controllerContext,

    stringpartialViewName, bool useCache)

    {

    returnnew ViewEngineResult(new string[] { "Debug Data View Engine" });

    }

    publicvoid ReleaseView(ControllerContext controllerContext, IView view)

    {

    //do nothing

    }

    }

    }

    3,注册自定义的ViewEngine

    protected voidApplication_Start()

    {

    AreaRegistration.RegisterAllAreas();

    ViewEngines.Engines.Add(newDebugDataViewEngine());

    RegisterGlobalFilters(GlobalFilters.Filters);

    RegisterRoutes(RouteTable.Routes);

    }

    二:通过MVC提供的EngineRazir

    1Razir中,view被转换成C#

    @model string[]

    @{

    ViewBag.Title ="Index";

    }

    This is a list offruit names:

    @foreach (string namein Model)

     {

    <span><b>@name</b></span>

    }

    被转换为:

    namespace ASP

    {

    usingSystem;

    usingSystem.Collections.Generic;

    usingSystem.IO;

    usingSystem.Linq;

    usingSystem.Net;

    usingSystem.Web;

    usingSystem.Web.Helpers;

    usingSystem.Web.Security;

    usingSystem.Web.UI;

    usingSystem.Web.WebPages;

    usingSystem.Web.Mvc;

    usingSystem.Web.Mvc.Ajax;

    usingSystem.Web.Mvc.Html;

    usingSystem.Web.Routing;

    publicclass _Page_Views_Home_Index_cshtml :System.Web.Mvc.WebViewPage<string[]>

    {

    public_Page_Views_Home_Index_cshtml()

    {

    }

    publicoverride void Execute()

    {

    WriteLiteral(" ");

    ViewBag.Title= "Index";

    WriteLiteral(" Thisis a list of fruit names: ");

    foreach(string name in Model)

    {

    WriteLiteral("<span><b>");

    Write(name);

    WriteLiteral("</b></span> ");

    }

    }

    }

    }

    当第一个请求viewrequest到达时,Razor会把所有的view.cshtml文件转化为相应的C#类,且类名和.csthml文件名相关,Razor通过对应的map,得到C#类;

    转换方式:@直接被转换为C#语句开始;

    Razor通过该完整的C#类,形成静态和动态内容,并且通过TextWrite把内容写到客户端

    2,向Razor view中注入自定义的接口,通过属性注入的方式,取消接口依赖注入:

    ①定义抽象类继承自:WebViewPage

    using System.Web.Mvc;

    using Ninject;

    namespaceViews.Models.ViewClasses

    {

    publicabstract class CalculatorView : WebViewPage

    {

    [Inject]

    publicICalculator Calulator { get; set; }

    }

    }

    ②在View中进行相关的声明:

    @inheritsViews.Models.ViewClasses.CalculatorView

    @{

    ViewBag.Title ="Calculate";

    }

    <h4>Calculate</h4>

    The calculationresult for @ViewBag.X and @ViewBag.Y is @Calulator.Sum(ViewBag.X, ViewBag.Y)

    通过@inherits Views.Models.ViewClasses.CalculatorView来指定此viewC#类继承自我们声明的抽象类;

    View被转换的C#类如下:

    public class_Page_Views_Home_Calculate_cshtml : Views.Models.ViewClasses.CalculatorView {

    ...

    }

    3改变RazorEngine的一些设置,比如默认的view的寻找位置

    ①声明一个类,继承自RazorViewEngine();在类的构造方法里改变RazorViewEngine的相关属性值

    ②在app_start()里注册:

    protected voidApplication_Start()

    {

    AreaRegistration.RegisterAllAreas();

    ViewEngines.Engines.Clear();

    ViewEngines.Engines.Add(newCustomRazorViewEngine());

    RegisterGlobalFilters(GlobalFilters.Filters);

    RegisterRoutes(RouteTable.Routes);

    }

    4,向Razor View中应用动态数据:

    ①:通过内置的代码行:@

        webForm中,ASPX页面通过把标记和过程逻辑相分离,而Razor中则是把表现和逻辑相分离,在View中只负责内容的表现

            View中添加引用:

            i,向View中添加引用:@using

           ii,通过配置viewsweb.Config

    <system.web.webPages.razor>

    <pagespageBaseType="System.Web.Mvc.WebViewPage">

    <namespaces>

    <addnamespace="System.Web.Mvc" />

    <addnamespace="System.Web.Mvc.Ajax" />

    <addnamespace="System.Web.Mvc.Html" />

    <addnamespace="System.Web.Routing" />

    <addnamespace="DynamicData.Infrastructure"/>

    </namespaces>

    </pages>

    </system.web.webPages.razor>

             通过@语句块输出的内容,会被Razor进行转义后输出:<>...可能会和相关标记混淆的地方均用html专业标记输出;

            要返回原本期望的字符串,可通过以下几种方法:

            i:MvcHtmlString();

            ii:@Html.Raw

            Html helper:来实现重复代码的减少,即定义相关的方法:

            i:通过内置的代码行:@helper

           

    @helperCreateList(string[] items)

    {

    <ul>

    @foreach(string item in items)

    {

    <li>@item</li>

    }

    </ul>

    }

     

    ii:通过扩展方法:

    usingSystem.Web.Mvc;

    namespaceDynamicData.Infrastructure.HtmlHelpers

    {

    publicstatic class CustomHtmlHelpers

    {

    publicstatic MvcHtmlString List(this HtmlHelper html, string[] listItems)

    {

    TagBuildertag = new TagBuilder("ul");

    foreach(string item in listItems)

    {

    TagBuilderitemTag = new TagBuilder("li");

    itemTag.SetInnerText(item);

    tag.InnerHtml+= itemTag.ToString();

    }

    return new MvcHtmlString(tag.ToString());

    }

    }

    }

        5使用创建好的HTML Helpers

         1,创建表单Form:Html.BeginForm和Html.EndForm

          @{Html.BeginForm("Action","Controller")}:创建<form>标签

          @{Html.EndForm()}:创建</form>

          或者

          @using(Html.BeginForm("Action","Controller"))

           {

           }

         等效于:

          <form action="通过路由系统反映射出的路径" method="Post">

          </form>

        

         Html.BeginForm会创建一个MvcForm类的实例,用来生成form的开始标签,而且该类实现了IDispose接口,会在Dispose时自动创建form的结束标签

         当不指定 Html.BeginForm的参数时,该表单默认会提交在原页面路径(即其提交的ControllerAction都不变)。在MVC模式中,一个表单的初次显示和需要提交数据时的可以是同一个路径,在Controller里可以创建两个Action,分别应用[HttpPost][HttpGet]属性,其中,get属性的Action用来显示Form内容,PostAction则用来显示和处理提交的表单

        2,创建input元素,包括普通的input和与Module相关联的input元素;

        3,添加Attributehtml标记中:

        @htmlHelp的方法里,都有接受属性的参数new{@class="MyCss",CustomAttr="SomeValue"}

        4,创建DropDownList

       

    Drop-down listHtml.DropDownList("myList", new SelectList(new [] {"A","B"}), "Choose")

    Output:

    <selectid="myList" name="myList">

    <optionvalue="">Choose</option>

    <option>A</option>

    <option>B</option>

    </select>

        5,创建Grid

        

    @modelIEnumerable<DynamicData.Models.Product>

    @{

    var grid = newWebGrid(

    source: Model,

    rowsPerPage: 4);

    }

    @grid.GetHtml(

    tableStyle:"grid",

    headerStyle:"header",

    rowStyle:"row",

    footerStyle:"footer",

    alternatingRowStyle:"altRow",

    columns: grid.Columns(

    grid.Column("Name","Item", style:"textCol"),

    grid.Column("Price",style: "numberCol",

    format:@<text>$@string.Format("{0:F2}", item.Price) </text>)

    ))

    6,使用SectionPartView

    @RenderSection和@Html.PartView

     

    7ChildAction:当需要在许多页面中包含某一逻辑处理,但不想在每一个一面中重复此段功能代码时,可创建ChildActionChildAction返回一个PartView或者其他结果,可以在View中直接调用;

    [ChildAction]

    …..ActionName()….

     

    View中,直接通过@Html.Action("ActionName"),即可嵌入此结果

  • 相关阅读:
    密码朋克的社会实验(一):开灯看暗网
    ThinkPHP5框架缺陷导致远程命令执行(POC整合帖)
    SQL基本注入演示
    从SQL注入到内网漫游
    业务逻辑漏洞探索之敏感信息泄露
    Web安全之XSS Platform搭建及使用实践
    iOS URL Schemes与漏洞的碰撞组合
    phpcms2008远程代码执行漏洞
    使用RSA加密在Python中逆向shell
    源码级调试的XNU内核
  • 原文地址:https://www.cnblogs.com/tianma3798/p/4372204.html
Copyright © 2020-2023  润新知