Asp.net MVC动态Html属性

Bar*_*art 5 html c# asp.net-mvc

我的视图文本框,下拉列表等中的元素很少.所有元素都有一些像这样创建的独特属性

<%: Html.DropDownListFor(model => model.MyModel.MyType, EnumHelper.GetSelectList< MyType >(),new { @class = "someclass", @someattrt = "someattrt"})%>
Run Code Online (Sandbox Code Playgroud)

我想通过设置另一个属性禁用来创建我的页面的只读版本.

有人知道我怎么能使用可以全局设置的变量来做到这一点?

就像是:

If(pageReadOnly){
isReadOnlyAttr  = @disabled = "disabled";
}else 
{
isReadOnlyAttr   =”” 
} 

<%: Html.DropDownListFor(model => model.MyModel.MyType, EnumHelper.GetSelectList< MyType >(),new { @class = "someclass", @someattrt = "someattrt",isReadOnlyAttr})%>
Run Code Online (Sandbox Code Playgroud)

我不想使用JavaScript来做到这一点

Jay*_*neT 6

在我想到之后,我做了类似于你的事情 - 基本上我有几个不同的系统用户,一套在网站上拥有只读权限.为了做到这一点,我在每个视图模型上都有一个变量:

public bool Readonly { get; set; }
Run Code Online (Sandbox Code Playgroud)

根据其角色权限在我的模型/业务逻辑层中设置.

然后我创建了DropDownListFor Html Helper的扩展,它接受一个布尔值,指示下拉列表是否应该只读:

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Mvc.Html;

public static class DropDownListForHelper
{
    public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> dropdownItems, bool disabled)
    {
        object htmlAttributes = null;

        if(disabled)
        {
            htmlAttributes = new {@disabled = "true"};
        }

        return htmlHelper.DropDownListFor<TModel, TProperty>(expression, dropdownItems, htmlAttributes);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,您还可以创建其他具有更多参数的实例.

在我的视图中,我只是为我的html帮助扩展导入了命名空间,然后将视图模型变量readonly传递给DropDownListFor Html帮助器:

<%@ Import Namespace="MvcApplication1.Helpers.HtmlHelpers" %>

<%= Html.DropDownListFor(model => model.MyDropDown, Model.MyDropDownSelectList, Model.Readonly)%>
Run Code Online (Sandbox Code Playgroud)

我对TextBoxFor,TextAreaFor和CheckBoxFor做了同样的事情,它们似乎都运行良好.希望这可以帮助.


Fen*_*ton 5

与其禁用下拉列表,不如不将其替换为选定的选项...如果您要进行大量操作,则应考虑使用只读视图和可编辑视图...

<% if (Model.IsReadOnly) { %>
    <%= Model.MyModel.MyType %>
<% } else { %>
    <%= Html.DropDownListFor(model => model.MyModel.MyType, EnumHelper.GetSelectList< MyType >(),new { @class = "someclass", someattrt = "someattrt"})%>
<% } %>
Run Code Online (Sandbox Code Playgroud)

顺便说一句,如果属性名称是保留字(例如“ class”),则只需用“ @”转义属性名称。

更新资料

好的。我确实为您提供了答案-但前提是您必须在实施之前阅读这些内容。

MVC就是要分离关注点。将逻辑中特别关注的逻辑放入控制器是对MVC的滥用。请不要这样做。视图的所有特定内容,例如HTML,属性,布局-“ controllerville”中都不应该包含任何内容。控制器不必更改,因为您想更改视图中的某些内容。

理解MVC想要实现的目标以及以下示例破坏整个模式并将视图内容完全放在应用程序中的错误位置上,这一点非常重要。

正确的解决方法是具有“读取”视图和“编辑”视图-或在视图中放置任何条件逻辑。但是,这是一种做您想要的事情的方法。:(

将此属性添加到模型。

public IDictionary<string, object> Attributes { get; set; }
Run Code Online (Sandbox Code Playgroud)

在控制器中,您可以有条件地设置属性:

model.Attributes = new Dictionary<string, object>();
model.Attributes.Add(@"class", "test");
if (isDisabled) {
    model.Attributes.Add("disabled", "true");
}
Run Code Online (Sandbox Code Playgroud)

在视图中使用属性:

<%= Html.TextBoxFor(model => model.SomeValue, Model.Attributes)%>
Run Code Online (Sandbox Code Playgroud)