根据从 db 获取的信息动态地为 @Html.TextBoxFor( ) 设置 属性 "readonly"

Set property "readonly" for @Html.TextBoxFor( ) dynamically based on fetched information from db

我使用@Html.TextBoxFor() 定义了多个文本框。现在我希望其中一些只是 "readonly" 而其中一些是可编辑的,这取决于访问页面的用户的角色。

我试过使用以下

@Html.TextBoxFor(f => f.VSSLabel, new { style = "height:19px", @Value = @ViewBag.fetchf.VSSLabel, @readonly="readonly" })

有没有什么方法可以设置@readonly="false" 并且它变得可编辑,或者任何其他方法所以我将它切换到 "readonly" 并根据存储在 ViewBag 中的值进行编辑来自控制器的变量?

不幸的是,以下所有标记将呈现只读文本框输入

<input type="text" name="s1" readonly="readonly"/>
<input type="text" name="s2" readonly="no" />
<input type="text" name="s2" readonly="reallyDoNotWant" />
<input type="text" name="s3" readonly="false" />
<input type="text" name="s4" readonly />

readonly 属性的存在使输入元素只读。值无所谓。

所以你应该有条件地渲染它

if (yourExpressionWhichGivesBooleanValue)
{
    @Html.TextBoxFor(a => a.VSSLabel)
}
else
{
    @Html.TextBoxFor(a => a.VSSLabel, new { @readonly = "readonly" })
}

如果你想对照 viewbag 字典项检查它

if (ViewBag.IsAdmin !=null && ViewBag.IsAdmin)
{
    @Html.TextBoxFor(a => a.VSSLabel)
}
else
{
    @Html.TextBoxFor(a => a.VSSLabel, new { @readonly = "readonly" })
}

假设您在操作方法中将 ViewBag.IsAdmin 设置为一个布尔值。

为了使您的代码更易于阅读,您可以使用可以声明的函数:

@functions
{
    private object GetAttributes()
    {
        if (ViewBag.IsAdmin !=null && ViewBag.IsAdmin)
        {
            return null;
        }

        return new { @readonly = "readonly" };
    }
}

然后你可以这样使用它:

@Html.TextBoxFor(a => a.VSSLabel, GetAttributes())

在函数中,您可以添加任何需要添加到元素的属性:

return new { @class = "form-control", @readonly = "readonly", @required = "required" }

而且效果很好

你可以这样写一个扩展方法:

/* for .NET Core       */ using Microsoft.AspNetCore.Mvc.ViewFeatures;
/* for .NET Framework: */ using System.Web.WebPages.Html;

public static class HtmlHelpers
{
    public static object MakeReadonly(this object htmlAttributes, bool isReadonly)
    {
        if (isReadonly)
        {
            var dynamicHtmlAttributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
            dynamicHtmlAttributes["readonly"] = "readonly";
            return dynamicHtmlAttributes;
        }

        return htmlAttributes;
    }
}

用法:

@Html.TextBoxFor(..., new { @class = "form-control" }.MakeReadonly(true))

这种方法的一个缺点是,object 上的扩展方法有点可疑,因为它们会在 IntelliSense 中随处弹出。

如果您不喜欢这样,我建议将 htmlAttributes 从匿名对象更改为 ViewDataDictionary 并使扩展方法与之配合使用。

Shyju 的说法是正确的,但是 Shariq Ali 是正确的,如果你有很多字段要做,Razor 代码会变得非常低效。

在我的例子中,我有一个完整的表单,我想在某些情况下将其设置为只读。我发现的一种方法可以用更少的代码解决您的问题。

@{
object htmlAttr = null;

if ( ViewBag.AllowEdit != null && !ViewBag.AllowEdit ){
    htmlAttr = new { @class="CSS", @readonly="readonly"};
}
else {
    htmlAttr = new { @class="CSS" };
}

@Html.TextBoxFor( m => m.Field, htmlAttr)

由于表单中的大多数编辑控件都带有相同的 CSS class 这应该可以满足大部分需求。如果您发现某些控件需要更多 classes,只需添加额外的 htmlAttribute 对象来携带不同的 class 配置。

通过使用描述性变量名,这集中了只读逻辑并使您的剃刀页面更加简洁。