Razor布局页面 _ViewStart.cshtml

本文详细介绍了Razor布局页面(ViewStart.cshtml)的作用,混编HTML与C#,以及MVC视图加载顺序。重点讲解了视图的布局设置、代码段声明和如何通过ViewStart控制全局样式和脚本引用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Razor布局页面 _ViewStart.cshtml

知识点0:
标识符 @
Razor支持HTML和C#代码混编,意味着可以在代码块中插入HTML、在HTML中插入Razor语句都是可以的。
(0)在代码块中插入HTML、在HTML中插入Razor语句

@{    
int num1 =10;    
int num2 =5;     
int sum = num1 + num2;    
string color ="Red";    
<font color="@color">@sum</font>
}

输出@符号:@@
输出Email地址:Razor模板会自动识别出Email地址,所以不需要我们进行任何的转换。而在代码块中,只需要使用 @:Tom@gmail.com 即可。@:表示后面的内容为文本。
输出HTML代码(包含标签):直接输出,string html = “文本”; @html
输 出HTML内容(不包含标签):有两种方法,第一种:IHtmlString html=new HtmlString(“文本”); @html; 第二种:string html = “文本”; @Html.Raw(html);

(1)直接@后面跟变量(当遇到 HTML标签 、空格、换行符等特殊符号时 便认为@之后到特殊符号前为变量名,特殊符号后的内容原样输出)

<p>my name is @ViewBag.name</p>     
 
my job is @ViewBag.job 

以上代码输出了 ViewBag.name 和ViewBag.job 的值

(2)@后面跟大括号(代码段声明,代码段中代码全部当做C#代码 ,但是HTML标签会原样输出 ,输出变量同样适用@)

@{
    List<Employee> employees = new List<Employee>();
    for (int i = ; i < ; i++)
    {
        Employee employee = new Employee();
        employee.Name = "李二狗" + i;
        employee.Age =  + i;
        employee.Job = (Career)(i/);
        employees.Add(employee);
    }
}
 
<table>
    <tr>
        <td>姓名</td>
        <td>年龄</td>
        <td>职业</td>
    </tr>
    @* 从这里开始声明C#代码段 *@
    @foreach (Employee item in employees)
    {
        <tr>
             @*  在C#代码段中 HTML标签会被原样输出(混编的好处) 输出变量需要在前面加上@  *@
         <td>@item.Name</td>
              <td>@item.Age</td>
              <td>@item.Job.ToString()</td>
        </tr>
    }
</table>

知识点1:
MVC中执行任何一个视图之前都要先执行Views文件夹下的 _ViewStart.cshtml 视图的内容
注意点:想要上面的描述成立,则在action方法中必须以return View()来返回视图
如果是以PowerView() 方法来返回视图的话,则不会执行_ViewStart.cshtml 中的内容

 public class HomeController : Controller
    {
        public ActionResult Index()
        {
            //MVC中执行任何一个视图之前都要先执行Views文件夹下的_ViewStart.cshtml视图的内容
            //                   ↓↓
            return View(); //但是只有以return View()的形式返回视图,才会执行_ViewStart.cshtml视图中的内容
                      
            //return PartialView(); 如果如果是以PowerView() 方法来返回视图的话,则不会执行_ViewStart.cshtml 中的内容
        }
    }
}

知识点2:
_ViewStart.cshtml 视图文件的作用
_ViewStart.cshtml 文件的作用:一般是用于存放MVC网站中所有视图公用的js,css等文件。这样就不需要在每个视图中都拖一个js,css等文件进来了。
(1)引入静态文件
.net MVC提供一套静态文件打包工具
需要在/App_Start/BundleConfig.cs中先定义,例如

//在视图中引入Content/css相当于引入 bootstrap.css 和 site.css
bundles.Add(new StyleBundle("~/Content/css").Include(
            "~/Content/bootstrap.css",
            "~/Content/site.css"));

视图中使用

@Styles.Render("~/content/home")
//引入css
@Scripts.Render("~//bundles/jquery")
//引入js

项目相关结构如下:
在这里插入图片描述

_ViewStart.cshtml就是MVC中的布局页面/模板页面

_ViewStart.cshtml 文件内容举例:

@{
   Layout = "_Layout";
}

@*利用Razor视图开始(_ViewStart)批量配置布局
有非常多视图都需要引入相同的布局时,在_ViewStart中编写的引用在其作用域下所有的视图都会被加上相应的代码,引用其规定的Razor布局
*@

@*当相同文件夹内的文件要使用不同布局时,只能在内容页里使用Layout属性
当不同的文件夹内的如果要使用不同的布局时,可以在相应的文件夹下新建_ViewStart.cshtml文件
*@

@*在视图中使用@{Layout}的引用>写在与视图同目录的视图开始中的引用>写在父目录的视图开始的引用
即如果某一页需要单独引用不同的视图布局,则可以使用优先级更高的方式覆盖优先级低的方式。
*@

@{
   Layout = "teacher/_Layout";
}

模板渲染过程

Views/_Layout.cshtml

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
 
 
    <!--每个虚拟路径下面的物理文件是在MVC网址启动的时候就调用了Global.asax文件下的Application_Start()方法中的BundleConfig.RegisterBundles(BundleTable.Bundles)方法,这样就将每个虚拟路径映射好了具体的物理文件-->
 
 
    <!--Styles.Render(""虚拟路径"") :输出此虚拟路径下包含的物理css文件-->
    @Styles.Render("~/Content/css")
    <!--Scripts.Render(""虚拟路径"") :输出此虚拟路径下包含的物理js文件-->
    @Scripts.Render("~/bundles/jquery")
 
 
 
 
    <!--RenderSection()也是一个占位符,它是一个带有标识的占位符。将来会被使用了此模板页的子页面带有指定标识的内容来替换-->
    <!--它可以有多个。-->
    <!--required: false表示在使用模板页中的子页面中不重写这个节点,如果是true则必须重写-->
    @RenderSection("scripts", required: false)
 
    <!--比如,这里我再自定义一个RenderSection()-->
    @RenderSection("Mycss",required:true)
 
</head>
<body>
    <div style="width:800px;margin:0px auto">
        <div style="border:1px solid red; height:50px">顶部内容</div>
        <div>
            <div style="float:left; width:150px; height:500px; border:1px solid blue"  >
                <ul>
                    <li>菜单1</li>
                    <li>菜单2</li>
                    <li>菜单3</li>
                </ul>
            </div>
            <div style="float: right; width: 640px; height: 500px; border: 1px solid blue">
                <!--这个RenderBody()就是占位符,将来会被使用了模板页的子页面的内容给替换掉-->
                <!--这个RenderBody()占位符,只能在布局也中出现一次-->
                @RenderBody()
                @RenderSection("bodyArea", required: false)
            </div>
        </div>
    </div>      
</body>
</html>

Views/Home/Index.cshtml

在看看我们继承这个模板页的子页面 (Home控制器下的Index视图,它使用了上面这个模板页)

@{
    ViewBag.Title = "Index";
}
 <!-- 子页面中所有没有使用@section地方都是对应Layout中@RenderBody()-->
<h2>Index</h2>
@section scripts{
        <script type="text/javascript">
            alert("你好");
        </script>
    }
 
@section Mycss{
    <style type="text/css">
        * {
         color:red;
        }
    </style>
    }
<!--对应Layout中@RenderSection("bodyArea", required: false) ,required: false不是必填-->
@section headArea{
required: false不是必填
}

image-20221109175859608

渲染出来的HTML页面

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
 
 
    <!--每个虚拟路径下面的物理文件是在MVC网址启动的时候就调用了Global.asax文件下的Application_Start()方法中的BundleConfig.RegisterBundles(BundleTable.Bundles)方法,这样就将每个虚拟路径映射好了具体的物理文件-->
 
 
    <!--Styles.Render(""虚拟路径"") :输出此虚拟路径下包含的物理css文件-->
    <link href="/Content/site.css" rel="stylesheet"/>
 
    <!--Scripts.Render(""虚拟路径"") :输出此虚拟路径下包含的物理js文件-->
    <script src="/Scripts/jquery-1.8.2.js"></script>
 
 
 
 
 
    <!--RenderSection()也是一个占位符,它是一个带有标识的占位符。将来会被使用了此模板页的子页面带有指定标识的内容来替换-->
    <!--它可以有多个。-->
    <!--required: false表示在使用模板页中的子页面中不重写这个节点,如果是true则必须重写-->
    
        <script type="text/javascript">
            alert("你好");
        </script>
    
 
    <!--比如,这里我再自定义一个RenderSection()-->
    
    <style type="text/css">
        * {
         color:red;
        }
    </style>
    
 
</head>
<body>
    <div style="width:800px;margin:0px auto">
        <div style="border:1px solid red; height:50px">顶部内容</div>
        <div>
            <div style="float:left; width:150px; height:500px; border:1px solid blue"  >
                <ul>
                    <li>菜单1</li>
                    <li>菜单2</li>
                    <li>菜单3</li>
                </ul>
            </div>
            <div style="float: right; width: 640px; height: 500px; border: 1px solid blue">
                <!--这个RenderBody()就是占位符,将来会被使用了模板页的子页面的内容给替换掉-->
                <!--这个RenderBody()占位符,只能在布局也中出现一次-->
                
 
 
 
<h2>Index</h2>
 
 
            </div>
        </div>
    </div>      
</body>
</html>

即:将模板_Layout.cshtml中的占位符替换成HOME/index.cshtml中对应的模块所替换

子页面不使用布局页面

所有的视图页面都使用了布局页面,因为每次请求都会执行【_ViewStart.cshtml页面】,【_ViewStart.cshtml页面】对页面的Layout属性赋值了。

很多不使用布局页面的都会清空Layout

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>TransData</title>
</head>
<body>
</body>
</html>

那么这个页面中就不会使用到各级模板_Layout.cshtml中所提供的页面布局,只用它自己的页面(常可用于系统中的登录页面)。

用户访问流程图:

image-20221109175859608

原理:先去执行Views文件夹下【_ViewStart.cshtml】页面,然后同级目录文件夹(上图中的home文件夹)下执行【_ViewStart.cshtml】页面(如果同级目录文件夹下有【_ViewStart.cshtml】页面),最后执行请求视图(上图Index.cshtml页面)。

那么当存在多个ViewStart.cshtml文件的时候执行顺序是什么呢?
答:
1>首先是执行Views文件夹下的ViewStart.cshtml视图文件的内容。当我们访问的是Home文件夹下的的视图的时候,Home文件夹下的ViewStart.cshtml文件才会被执行。
也就是先执行了Views文件夹下的ViewStart.cshtml视图文件内容,后才执行Home文件夹下的ViewStart.cshtml视图内容
2>当我们访问的是Test文件下的视图的时候,就仅仅是执行Views文件夹下的ViewStart.cshtml视图内容(因为Test文件夹下不存在ViewStart.cshtml视图文件)

举例

MVC中任何视图页面最终都会被创建成一个页面类对象,【_ViewStart.cshtml】页面也不例外,它是被创建【继承StartPage抽象类的一个页面类对象】,所以它可以使用StartPage抽象类中的属性和方法。

StartPage抽象类图

image-20221109175859608

布局页面传值可以使用PageData

c#中前后端进行数据交互的常见三种方式:

  1. ViewData 字典类型,存放键值对an
  2. ViewBag 非键值对数据,而是dynamic动态数据
  3. TempData 默认保存Session中,控制器每次从Session中获取TempData,然后清除Session。

eg:
控制器中:
ViewBag.a=“a”;
ViewData[“b”]=“b”;
TempData[“c”]=“c”;
视图中:
@ViewBag.a
@ViewData[“b”]
@TempData[“c”]
运行后显示:
abc

PS:其中ViewBag和ViewData是可以混用的例如控制器中ViewBag.a=“a”,视图中@ViewData[“a”],运行后也可以输出a,反之亦然(两者是一个继承关系,所以可以混用)

①Views文件夹下的_ViewStart.cshtml

image-20221109175859608

②Views /Teacher文件夹下的_ViewStart.cshtml

image-20221109175859608

③Views/Teacher文件夹下的Index.cshtml(注:Index.cshtml没有使用_ViewStart.cshtml布局页面)

image-20221109175859608

结果:执行顺序 Views 下ViewStart.cshtml =>Teacher下ViewStart.cshtml => Teacher下Index.cshtml

image-20221109175859608

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值