ASP.NET Web Pages – 帮助器

ASP.NET Web Pages 中最强大、最实用的「帮助器(Helpers)」完全攻略

(2025 年依然是 Razor 页面的杀手锏)

什么是帮助器?

帮助器 = 用 Razor 语法写的、可重复使用的「HTML + C#」代码块
放在 App_Code 文件夹里,全站任何一个 .cshtml 页面都能直接调用!

一、创建帮助器的 2 种方式(推荐第 1 种)

方式 1:@helper 语法(最常用、最灵活)
文件必须放在 App_Code 文件夹,文件名随意(建议 xxx.cshtml)

<!-- App_Code/MyHelpers.cshtml -->
@helper Pager(int currentPage, int totalPages, string url = "") 
{
    if(totalPages <= 1) return;

    var baseUrl = url.IsEmpty() ? Request.Url.PathAndQuery : url;

    <div class="pagination">
        @if(currentPage > 1){
            <a href="@baseUrl?page=@(currentPage-1)">上一页</a>
        }else{
            <span>上一页</span>
        }

        @for(int i=1; i<=totalPages; i++){
            if(i == currentPage){
                <strong>[@i]</strong>
            }else{
                <a href="@baseUrl?page=@i">@i</a>
            }
        }

        @if(currentPage < totalPages){
            <a href="@baseUrl?page=@(currentPage+1)">下一页</a>
        }else{
            <span>下一页</span>
        }
    </div>
}

@helper FormatMoney(decimal money)
{
    <span style="color:#c00;font-weight:bold">¥@money.ToString("N2")</span>
}

@helper StarRating(int score)   // 1-5星评分
{
    for(int i=1; i<=5; i++){
        if(i <= score){
            <text>★</text>
        }else{
            <text>☆</text>
        }
    }
    <span>(@score 分)</span>
}

页面中直接调用(超级简单):

@MyHelpers.FormatMoney(999.99)
@MyHelpers.StarRating(4)
@MyHelpers.Pager(currentPage: 3, totalPages: 15)

方式 2:返回 IHtmlString(适合复杂逻辑)

<!-- App_Code/AdvancedHelpers.cshtml -->
@using System.Web;
@helper Gravatar(string email, int size = 80)
{
    var hash = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(email.Trim().ToLower(), "MD5").ToLower();
    var url = "https://gravatar.loli.net/avatar/" + hash + "?s=" + size + "&d=mp";
    <img src="@url" alt="头像" width="@size" height="@size" style="border-radius:50%;" />
}

二、10 个生产环境必备帮助器(直接复制进 App_Code)

<!-- App_Code/SiteHelpers.cshtml -->
@helper Truncate(string text, int length = 100, string suffix = "...")
{
    if(text.IsEmpty() || text.Length <= length){
        @text
    }else{
        @(text.Substring(0, length) + suffix)
    }
}

@helper TimeAgo(DateTime dt)
{
    var span = DateTime.Now - dt;
    if(span.TotalDays > 30)        { @dt.ToString("yyyy-MM-dd") }
    else if(span.TotalDays >= 1)   { @(span.Days)天前 }
    else if(span.TotalHours >= 1)  { @(span.Hours)小时前 }
    else if(span.TotalMinutes >= 1){ @(span.Minutes)分钟前 }
    else                           { 刚刚 }
}

@helper IsActive(string controller, string action = "")
{
    var curAction = UrlData[0].IsEmpty() ? "Index" : UrlData[0];
    var isActive = (curAction == action || (action.IsEmpty() && curAction == controller));
    if(isActive) { <text>class="active"</text> }
}

@helper YesNo(bool value)
{
    if(value){
        <span style="color:green">是</span>
    }else{
        <span style="color:red">否</span>
    }
}

@helper Badge(string text, string type = "default")
{
    var colors = new Dictionary<string,string>{
        {"success","green"}, {"warning","orange"}, {"danger","red"}, {"info","blue"}
    };
    var color = colors.ContainsKey(type) ? colors[type] : "gray";
    <span style="background:@color;color:white;padding:2px 8px;border-radius:3px;font-size:12px;">@text</span>
}

使用示例:

<div>@SiteHelpers.Truncate(veryLongContent, 150)</div>
<p>发布于:@SiteHelpers.TimeAgo(article.AddTime)</p>
<a href="/Products" @SiteHelpers.IsActive("Products")>产品中心</a>
@SiteHelpers.YesNo(user.IsVip)
@SiteHelpers.Badge("热销", "danger")

三、带参数的复杂帮助器(实战级)

@helper ProductCard(dynamic product)
{
    <div class="product-card" style="border:1px solid #ddd;padding:15px;margin:10px;float:left;width:200px;">
        <img src="@product.Image" width="100%" />
        <h3>@product.Title</h3>
        <p>@SiteHelpers.Truncate(product.Description, 60)</p>
        <div style="color:red;font-size:20px;">
            @MyHelpers.FormatMoney(product.Price)
        </div>
        <a href="/Product/Detail/@product.Id">查看详情</a>
    </div>
}

页面循环调用:

@foreach(var p in products){
    @SiteHelpers.ProductCard(p)
}

四、终极技巧:帮助器里调用帮助器(完全支持)

@helper ArticleItem(dynamic a)
{
    <div class="article">
        <h2><a href="/Article/@a.Id">@a.Title</a></h2>
        <p>@SiteHelpers.Truncate(a.Content, 200)</p>
        <div class="meta">
            @SiteHelpers.TimeAgo(a.AddTime) 发布 • 
            @SiteHelpers.Badge(a.CategoryName, "info")
        </div>
    </div>
}

五、帮助器最佳实践总结

项目推荐做法
文件存放位置全部放在 App_Code 文件夹
文件命名一个功能一个文件(如 MyHelpers.cshtml、AdminHelpers.cshtml)
命名空间文件名就是命名空间(上面例子是 MyHelpers、SiteHelpers)
复杂帮助器用 @helper + dynamic 参数,超级灵活
性能自动编译成类,性能几乎和写在页面里一样快
团队协作所有人都能直接 @Xxx.方法名 调用,代码极度复用

掌握了帮助器,你写 Razor 页面会从「写一堆重复 HTML」变成「像搭积木一样优雅」!

需要我打包一个「终极帮助器合集」(50+ 个生产级帮助器:分页、导航、表单、图表、微信分享、SEO、Markdown 渲染……)发给你吗?
一个 SiteHelpers.cshtml 文件搞定全站 90% 重复代码,复制即用,2025 年最新版!随时说一声就发!

文章已创建 2863

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部