Microsoft前后端不分离编程新风向:cshtml

文章目录

什么是CSHTML?

CSHTML是ASP.NET Razor视图引擎使用的文件扩展名,它是C# (CS)和HTML的混合体。这种文件类型允许开发者在HTML标记中直接嵌入C#代码,用于构建动态Web页面。CSHTML文件在服务器端处理,生成纯HTML发送到客户端浏览器。

基础语法

Razor语法是CSHTML的核心,它提供了在HTML中嵌入C#代码的简洁方式。

内联表达式

最基本的Razor语法是使用@符号将C#表达式直接嵌入HTML:

html 复制代码
<p>当前时间是:@DateTime.Now</p>

代码块

对于多行C#代码,可以使用代码块:

html 复制代码
@{
    var greeting = "欢迎来到我们的网站!";
    var weekDay = DateTime.Now.DayOfWeek;
}
<h1>@greeting 今天是 @weekDay</h1>

控制结构

Razor支持常见的C#控制结构:

html 复制代码
@if(DateTime.Now.Hour < 12)
{
    <p>早上好!</p>
}
else
{
    <p>下午好!</p>
}

循环结构示例:

html 复制代码
<ul>
@for(int i = 1; i <= 5; i++)
{
    <li>项目 @i</li>
}
</ul>

布局页面

ASP.NET Razor提供了布局系统,类似于Master Page的概念,但更加灵活。

_ViewStart.cshtml

这个特殊文件定义了所有视图的默认布局:

html 复制代码
@{
    Layout = "_Layout";
}

_Layout.cshtml

布局页面定义了网站的整体结构:

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>@ViewBag.Title</title>
    @RenderSection("styles", required: false)
</head>
<body>
    <header>
        <h1>我的网站</h1>
    </header>
    
    <div class="content">
        @RenderBody()
    </div>
    
    <footer>
        &copy; @DateTime.Now.Year
    </footer>
    
    @RenderSection("scripts", required: false)
</body>
</html>

使用布局

在具体视图中:

html 复制代码
@{
    ViewBag.Title = "主页";
}

<p>这是主页内容</p>

@section scripts {
    <script>
        console.log("页面加载完成");
    </script>
}

模型绑定

CSHTML强大的功能之一是模型绑定,可以将C#对象直接传递到视图。

强类型视图

html 复制代码
@model MyNamespace.Models.Product

<h2>@Model.Name</h2>
<p>价格: @Model.Price.ToString("C")</p>

模型集合

html 复制代码
@model IEnumerable<MyNamespace.Models.Product>

<ul>
@foreach(var product in Model)
{
    <li>@product.Name - @product.Price.ToString("C")</li>
}
</ul>

HTML辅助方法

ASP.NET提供了许多HTML辅助方法,简化了表单创建和其他常见HTML元素的生成。

基本表单

html 复制代码
@using(Html.BeginForm("Action", "Controller", FormMethod.Post))
{
    @Html.LabelFor(m => m.Name)
    @Html.TextBoxFor(m => m.Name)
    
    @Html.LabelFor(m => m.Price)
    @Html.TextBoxFor(m => m.Price)
    
    <input type="submit" value="保存" />
}

验证

html 复制代码
@Html.LabelFor(m => m.Email)
@Html.TextBoxFor(m => m.Email)
@Html.ValidationMessageFor(m => m.Email)

局部视图

局部视图是可重用的视图组件。

创建局部视图

_ProductCard.cshtml:

html 复制代码
@model Product

<div class="product-card">
    <h3>@Model.Name</h3>
    <p>@Model.Description</p>
    <span class="price">@Model.Price.ToString("C")</span>
</div>

使用局部视图

html 复制代码
@foreach(var product in Model.Products)
{
    @Html.Partial("_ProductCard", product)
}

高级特性

视图组件

视图组件类似于局部视图,但包含业务逻辑:

csharp 复制代码
public class ShoppingCartViewComponent : ViewComponent
{
    public IViewComponentResult Invoke()
    {
        var cart = GetShoppingCart();
        return View(cart);
    }
}

使用视图组件:

html 复制代码
@await Component.InvokeAsync("ShoppingCart")

依赖注入

可以直接在视图中注入服务:

html 复制代码
@inject IEmailService EmailService

<p>联系我们: @EmailService.GetSupportEmail()</p>

Tag Helpers

ASP.NET Core引入了Tag Helpers,使HTML更加自然:

html 复制代码
<form asp-controller="Account" asp-action="Login" method="post">
    <label asp-for="Email"></label>
    <input asp-for="Email" />
    <span asp-validation-for="Email"></span>
    
    <button type="submit">登录</button>
</form>

性能优化

缓存

html 复制代码
<cache expires-after="@TimeSpan.FromMinutes(30)">
    @await Component.InvokeAsync("PopularProducts")
</cache>

捆绑和压缩

html 复制代码
<environment include="Development">
    <script src="~/js/site.js" asp-append-version="true"></script>
</environment>
<environment exclude="Development">
    <script src="~/js/site.min.js" asp-append-version="true"></script>
</environment>

安全考虑

防跨站请求伪造(CSRF)

html 复制代码
<form asp-action="UpdateProfile" method="post">
    @Html.AntiForgeryToken()
    <!-- 表单内容 -->
</form>

HTML编码

Razor自动对输出进行HTML编码:

html 复制代码
<!-- 用户输入会被自动编码 -->
<p>@userInput</p>

<!-- 如果需要原始HTML -->
<p>@Html.Raw(userInput)</p> <!-- 谨慎使用 -->

实际应用示例

电子商务产品页面

html 复制代码
@model ProductDetailViewModel

@section styles {
    <link rel="stylesheet" href="~/css/product.css" />
}

<div class="product-container">
    <div class="product-images">
        <img src="@Model.MainImageUrl" alt="@Model.Name" />
        <div class="thumbnails">
            @foreach(var image in Model.AdditionalImages)
            {
                <img src="@image.Url" alt="@image.AltText" />
            }
        </div>
    </div>
    
    <div class="product-details">
        <h1>@Model.Name</h1>
        <div class="price">
            @if(Model.IsOnSale)
            {
                <span class="original-price">@Model.OriginalPrice.ToString("C")</span>
                <span class="sale-price">@Model.Price.ToString("C")</span>
                <span class="discount">节省 @Model.DiscountPercentage.ToString("P0")</span>
            }
            else
            {
                <span>@Model.Price.ToString("C")</span>
            }
        </div>
        
        <div class="rating">
            @for(int i = 1; i <= 5; i++)
            {
                <span class="@(i <= Model.AverageRating ? "filled" : "")">★</span>
            }
            <span>(@Model.ReviewCount 条评价)</span>
        </div>
        
        <form asp-action="AddToCart" method="post" class="add-to-cart">
            @Html.AntiForgeryToken()
            <input type="hidden" asp-for="ProductId" />
            
            <div class="quantity">
                <label asp-for="Quantity"></label>
                <select asp-for="Quantity">
                    @for(int i = 1; i <= 10; i++)
                    {
                        <option value="@i">@i</option>
                    }
                </select>
            </div>
            
            <button type="submit">加入购物车</button>
        </form>
        
        <div class="product-description">
            <h3>产品描述</h3>
            <p>@Html.Raw(Model.Description)</p>
        </div>
    </div>
</div>

@section scripts {
    <script src="~/js/product.js"></script>
}

调试技巧

使用@functions

可以在视图中定义函数:

html 复制代码
@functions {
    public string GetCssClassForRating(int star, double averageRating)
    {
        return star <= averageRating ? "filled" : "";
    }
}

调试视图

html 复制代码
@{
    // 设置断点可以调试
    var debugInfo = Model;
}

最佳实践

  1. 保持视图简单:将复杂逻辑移入控制器或服务层
  2. 使用强类型视图:避免使用ViewBag/ViewData
  3. 重用组件:利用局部视图和视图组件
  4. 关注安全:始终对用户输入进行验证和编码
  5. 优化性能:使用缓存和捆绑等技术
  6. 保持一致性 :遵循项目约定的代码风格

结语

CSHTML作为ASP.NET Razor视图引擎的核心,提供了强大的功能来创建动态Web应用程序。从简单的内联表达式到复杂的布局系统和视图组件,它能够满足从简单到复杂的所有Web开发需求。通过遵循最佳实践并充分利用其特性,开发者可以构建出高效、安全且易于维护的Web应用程序。

掌握CSHTML需要实践和经验积累。建议从简单的页面开始,逐步尝试更复杂的特性,最终你将能够充分利用ASP.NET Razor视图引擎的全部潜力,构建出功能丰富、响应迅速的现代Web应用程序。

相关推荐
qb_jiajia10 分钟前
微软认证考试科目众多?该如何选择?
人工智能·microsoft·微软·云计算
漫谈网络13 分钟前
TypeScript 编译 ES6+ 语法到兼容的 JavaScript介绍
javascript·typescript·es6
bin915335 分钟前
DeepSeek 助力 Vue3 开发:打造丝滑的日历(Calendar),日历_天气预报日历示例(CalendarView01_18)
前端·javascript·vue.js·ecmascript·deepseek
江城开朗的豌豆36 分钟前
JavaScript篇:反柯里化:让函数'反悔'自己的特异功能,回归普通生活!
前端·javascript·面试
江城开朗的豌豆44 分钟前
JavaScript篇:数字千分位格式化:从入门到花式炫技
前端·javascript·面试
十年砍柴---小火苗1 小时前
原生js操作元素类名(classList,classList.add...)
javascript·css·css3
站在风口的猪11088 小时前
《前端面试题:CSS对浏览器兼容性》
前端·css·html·css3·html5
JohnYan8 小时前
Bun技术评估 - 04 HTTP Client
javascript·后端·bun
拉不动的猪10 小时前
TS常规面试题1
前端·javascript·面试
穗余10 小时前
NodeJS全栈开发面试题讲解——P5前端能力(React/Vue + API调用)
javascript·vue.js·react.js