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

ASP.NET MVC模型只读字段自动填充及角色权限配置问题

ASP.NET MVC + Identity 实现Entry模型字段控制方案

1. DevDate字段:只读+创建时自动填充当前时间

模型层配置

在Entry.cs模型中,给DevDate添加只读特性,可选配置数据库自动生成逻辑:

public class Entry
{
    public int Id { get; set; }

    [ReadOnly(true)]
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)] // 可选,数据库层面自动生成时间
    public DateTime DevDate { get; set; }

    // 其他字段...
}

视图层控制只读

在Create/Edit视图中,将DevDate改为显示控件+隐藏域,禁止手动编辑:

<div class="form-group">
    @Html.LabelFor(model => model.DevDate, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DisplayFor(model => model.DevDate)
        @Html.HiddenFor(model => model.DevDate)
    </div>
</div>

控制器层赋值(创建时)

若未使用数据库自动生成,在Create的POST方法中手动赋值当前时间:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,DevDate,dev_name,...")] Entry entry)
{
    if (ModelState.IsValid)
    {
        entry.DevDate = DateTime.UtcNow; // 推荐用UTC时间
        _context.Add(entry);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(entry);
}

2. dev_name字段:只读+自动填充当前用户名

模型层配置

添加只读特性标记:

public class Entry
{
    // 其他字段...

    [ReadOnly(true)]
    public string dev_name { get; set; }
}

视图层控制只读

同DevDate逻辑,用显示控件+隐藏域:

<div class="form-group">
    @Html.LabelFor(model => model.dev_name, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DisplayFor(model => model.dev_name)
        @Html.HiddenFor(model => model.dev_name)
    </div>
</div>

控制器层赋值(创建时)

通过Identity的User.Identity.Name获取当前登录用户名:

[HttpPost]
[ValidateAntiForgeryToken]
[Authorize] // 确保用户已登录
public async Task<IActionResult> Create([Bind("Id,DevDate,dev_name,...")] Entry entry)
{
    if (ModelState.IsValid)
    {
        entry.dev_name = User.Identity.Name;
        entry.DevDate = DateTime.UtcNow;
        _context.Add(entry);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
    return View(entry);
}

3. 基于角色控制非只读字段的编辑权限

假设前4个非只读字段为Field1、Field2、Field3、Field4,其余非只读字段为Field5至FieldN,需在视图和控制器层分别做权限控制:

视图层动态显示编辑控件

根据用户角色判断是否展示可编辑控件:

<!-- 前4个字段:仅角色X/Admin可编辑 -->
<div class="form-group">
    @Html.LabelFor(model => model.Field1, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @if (User.IsInRole("X") || User.IsInRole("Admin"))
        {
            @Html.EditorFor(model => model.Field1, new { htmlAttributes = new { @class = "form-control" } })
        }
        else
        {
            @Html.DisplayFor(model => model.Field1)
            @Html.HiddenFor(model => model.Field1)
        }
        @Html.ValidationMessageFor(model => model.Field1, "", new { @class = "text-danger" })
    </div>
</div>
<!-- 重复Field2、Field3、Field4的上述逻辑 -->

<!-- 其余字段:仅角色Y/Admin可编辑 -->
<div class="form-group">
    @Html.LabelFor(model => model.Field5, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @if (User.IsInRole("Y") || User.IsInRole("Admin"))
        {
            @Html.EditorFor(model => model.Field5, new { htmlAttributes = new { @class = "form-control" } })
        }
        else
        {
            @Html.DisplayFor(model => model.Field5)
            @Html.HiddenFor(model => model.Field5)
        }
        @Html.ValidationMessageFor(model => model.Field5, "", new { @class = "text-danger" })
    </div>
</div>
<!-- 重复Field6至FieldN的上述逻辑 -->

控制器层防篡改验证(可选)

为避免前端篡改数据,在Edit的POST方法中重置无权限字段的值:

[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = "X,Y,Admin")]
public async Task<IActionResult> Edit(int id, [Bind("Id,DevDate,dev_name,Field1,Field2,Field3,Field4,Field5,...")] Entry entry)
{
    if (id != entry.Id) return NotFound();

    var existingEntry = await _context.Entry.FindAsync(id);
    if (existingEntry == null) return NotFound();

    // 限制非X/Admin用户修改前4个字段
    if (!(User.IsInRole("X") || User.IsInRole("Admin")))
    {
        entry.Field1 = existingEntry.Field1;
        entry.Field2 = existingEntry.Field2;
        entry.Field3 = existingEntry.Field3;
        entry.Field4 = existingEntry.Field4;
    }

    // 限制非Y/Admin用户修改其余字段
    if (!(User.IsInRole("Y") || User.IsInRole("Admin")))
    {
        entry.Field5 = existingEntry.Field5;
        // 其余字段同理赋值
    }

    if (ModelState.IsValid)
    {
        try
        {
            _context.Update(entry);
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!EntryExists(entry.Id)) return NotFound();
            else throw;
        }
        return RedirectToAction(nameof(Index));
    }
    return View(entry);
}

private bool EntryExists(int id)
{
    return _context.Entry.Any(e => e.Id == id);
}

内容的提问来源于stack exchange,提问作者Alexander Barbu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 20:52:46