You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Razor中如何为Model变量名动态拼接循环变量后缀?

在Razor视图中动态拼接Model变量名称的实现方法

当然可以实现你的需求,但直接像你尝试的@Model.ContentSection+{a}这种写法是行不通的——因为C#是强类型语言,Model的属性访问是编译时确定的,没法直接通过字符串拼接来动态获取成员。不过有两种常用的解决办法,我给你详细说说:

方案1:使用反射动态获取属性值

反射可以让我们在运行时根据属性名称获取Model的对应值,刚好能满足你现有ViewModel结构不变的需求。

直接在视图中写反射逻辑

你可以在循环里通过反射拼接属性名并取值:

@for (var a = 1; a <= 5; a++)
{
    // 拼接属性名称,比如ContentSection1、ContentSection2
    var propertyName = $"ContentSection{a}";
    // 获取Model类型中对应的属性信息
    var propertyInfo = Model.GetType().GetProperty(propertyName);
    // 如果属性存在,获取其值
    var contentSection = propertyInfo?.GetValue(Model);
    
    if (contentSection != null)
    {
        <div class="content-section">@contentSection</div>
    }
}

封装成扩展方法简化代码

如果觉得视图里写反射逻辑太繁琐,可以把这个逻辑封装成一个扩展方法,让代码更整洁:
首先在项目里创建一个静态类:

public static class ViewModelExtensions
{
    public static T GetContentSection<T>(this YourViewModel model, int index)
    {
        var propertyName = $"ContentSection{index}";
        var propertyInfo = model.GetType().GetProperty(propertyName);
        return (T)propertyInfo?.GetValue(model);
    }
}

(注意把YourViewModel换成你实际的ViewModel类名,T换成ContentSection的类型)

然后在视图里就可以这样用:

@for (var a = 1; a <= 5; a++)
{
    var contentSection = Model.GetContentSection<ContentSection>(a);
    if (contentSection != null)
    {
        <div class="content-section">@contentSection</div>
    }
}

不过要注意,反射会有一定的性能开销,如果是高频访问的页面,这种方式可能不是最优解。

方案2:重构ViewModel(更推荐)

其实更优雅的做法是提前把这些内容模块整理成集合,这样完全不需要反射,代码也更符合C#的强类型设计。

修改ViewModel结构

把原来的ContentSection1、ContentSection2等单个属性,换成一个集合(比如List或者数组):

public class YourViewModel
{
    // 用集合存储所有内容模块
    public List<ContentSection> ContentSections { get; set; } = new List<ContentSection>();
    
    // 如果需要兼容旧代码,可以保留原来的单个属性,然后在构造函数里把它们加到集合中
    // public ContentSection ContentSection1 { get; set; }
    // public ContentSection ContentSection2 { get; set; }
    // ...
    // public YourViewModel()
    // {
    //     ContentSections.Add(ContentSection1);
    //     ContentSections.Add(ContentSection2);
    //     // 依次添加剩下的模块
    // }
}

在控制器中赋值

在控制器里给这个集合赋值(如果是兼容旧代码,就把原来的单个属性加入集合):

public IActionResult YourAction()
{
    var vm = new YourViewModel();
    // 添加内容模块,对应原来的ContentSection1到ContentSection5
    vm.ContentSections.Add(new ContentSection { /* 赋值内容 */ });
    vm.ContentSections.Add(new ContentSection { /* 赋值内容 */ });
    vm.ContentSections.Add(new ContentSection { /* 赋值内容 */ });
    vm.ContentSections.Add(new ContentSection { /* 赋值内容 */ });
    vm.ContentSections.Add(new ContentSection { /* 赋值内容 */ });
    
    return View(vm);
}

在视图中循环渲染

现在视图里的循环就非常简洁了:

@foreach (var section in Model.ContentSections)
{
    if (section != null)
    {
        <div class="content-section">@section</div>
    }
}

如果需要按索引控制(比如只渲染前5个),也可以用for循环:

@for (var a = 0; a < Model.ContentSections.Count && a < 5; a++)
{
    var section = Model.ContentSections[a];
    if (section != null)
    {
        <div class="content-section">@section</div>
    }
}

这种方式不仅代码更整洁,还避免了反射的性能问题,是长期维护的最优选择。

内容的提问来源于stack exchange,提问作者Paul Almond

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:15:56