Ответ 1
Я мог бы предложить вам использовать mvccontrib.FluentHtml.
Вы можете сделать что-то вроде этого
<%=this.TextBox(m=>m.FirstNam ).Disabled(Page.User.IsInRole("administrator"))%>
При использовании помощника HTML лучший способ установить атрибут на основе условия. Например
<%if (Page.User.IsInRole("administrator")) {%>
<%=Html.TextBoxFor(m => m.FirstName, new {@class='contactDetails'}%>
<%} else {%>
<%=Html.TextBoxFor(m => m.FirstName, new {@class='contactDetails', disabled = true}%>
<%}%>
Должен быть лучший способ программно добавить только один дополнительный KeyPair к анонимному типу? Невозможно использовать
new { .... disabled = Page.User.IsInRole("administrator") ... }
поскольку браузер принимает любое значение отключенного атрибута, чтобы отключить ввод
Я мог бы предложить вам использовать mvccontrib.FluentHtml.
Вы можете сделать что-то вроде этого
<%=this.TextBox(m=>m.FirstNam ).Disabled(Page.User.IsInRole("administrator"))%>
Он работает и для меня...
<%: Html.DropDownList("SportID", (SelectList)ViewData["SportsSelectList"], "-- Select --", new { @disabled = "disabled", @readonly = "readonly" })%>
<%= Html.CheckBoxFor(model => model.IsActive, new { @disabled = "disabled", @readonly = "readonly" })%>
Page.User.IsInRole( "администратор" )? null: new {disabled = "disabled" }
Используя предложение @SLaks использовать метод расширения и используя Пример Джереми Кларка Метод расширения Я написал метод расширения, чтобы я мог теперь do
Html.TextBoxFor(m => m.FirstName,new{class='contactDetails', ...},Page.User.IsInRole("administrator"));
Не уверен, есть ли лучший способ, хотя
public static class InputExtensions
{
public static IDictionary<string, object> TurnObjectIntoDictionary(object data)
{
var attr = BindingFlags.Public | BindingFlags.Instance;
var dict = new Dictionary<string, object>();
if (data == null)
return dict;
foreach (var property in data.GetType().GetProperties(attr))
{
if (property.CanRead)
{
dict.Add(property.Name, property.GetValue(data, null));
}
}
return dict;
}
public static MvcHtmlString TextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes, bool disabled)
{
IDictionary<string, object> values = TurnObjectIntoDictionary(htmlAttributes);
if (disabled)
values.Add("disabled","true");
return htmlHelper.TextBoxFor(expression, values);
}
public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes, bool disabled)
{
IDictionary<string, object> values = TurnObjectIntoDictionary(htmlAttributes);
if (disabled)
values.Add("disabled", "true");
return htmlHelper.TextAreaFor(expression, values);
}
public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool>> expression, object htmlAttributes, bool disabled)
{
IDictionary<string, object> values = TurnObjectIntoDictionary(htmlAttributes);
if (disabled)
values.Add("disabled", "true");
return htmlHelper.CheckBoxFor(expression, values);
}
}
Вам нужно передать Dictionary<string, object>
и добавить ключ disabled
внутри оператора if
.
Я рекомендую сделать перегрузку метода расширения, который принимает параметр bool disabled
и добавляет его в RouteValueDictionary
, созданный из атрибут, если он true
. (Вы также можете удалить запись disabled
из RouteValueDictionary
, если она false
, и не принимать другой параметр)
Возможно, вам захочется написать собственный класс расширения HtmlHelper с новым методом TextBox:
public static class HtmlHelperExtensions
{
public static MvcHtmlString TextBoxFor(this HtmlHelper htmlHelper, Expression<Func<TModel, TProperty>> expression, string cssClass, bool disabled)
{
return disabled
? Html.TextBoxFor(expression, new {@class=cssClass, disabled="disabled"})
: Html.TextBoxFor(expression, new {@class=cssClass})
}
}
теперь (если этот новый класс находится в одном и том же пространстве имен или вы импортировали новое пространство имен в заголовок страницы или в раздел страниц в файле web.config), вы можете сделать это на своей странице aspx:
<%=Html.TextBoxFor(m => m.FirstName, "contactDetails", Page.User.IsInRole("administrator")) %>
Создан метод расширения для объекта, который создаст копию входного объекта, исключая любые свойства, которые являются нулевыми, и возвращает все это как словарь, который упрощает его использование в MVC HtmlHelpers:
public static Dictionary<string, object> StripAnonymousNulls(this object attributes)
{
var ret = new Dictionary<string, object>();
foreach (var prop in attributes.GetType().GetProperties())
{
var val = prop.GetValue(attributes, null);
if (val != null)
ret.Add(prop.Name, val);
}
return ret;
}
Не уверен о последствиях производительности для отражения через свойства дважды и не нравится имя метода расширения, но, похоже, хорошо выполняет работу...
new {
@class = "contactDetails",
disabled = Page.User.IsInRole("administrator") ? "true" : null
}.StripAnonymousNulls()
Вы также можете определить этот параметр таким образом:
Page.User.IsInRole("administrator")
? (object)new { @class='contactDetails'}
: (object)new { @class='contactDetails', disabled = true}