2012-06-07 3 views
1

Я пытаюсь реализовать требование, которое позволит мне изменить состояние элемента управления html на основе роли пользователя или другой бизнес-логики. Например, некоторые пользователи не должны иметь возможность редактировать определенное свойство модели, или в некоторых случаях я даже не хочу, чтобы элемент управления отображал html DOM.Могу ли я модифицировать метаданные модели внутри фильтра действий?

В HTML-хелперах метаданные могут сообщать помощнику, нужно ли отображать элемент управления, или он может сделать его доступным только для чтения/отключенным. Вместо того, чтобы повторно изобретать колесо здесь, я просто хочу использовать то, что уже на месте, изменив метаданные внутри фильтра действий на основе логики во время выполнения. Мне не нужна эта логика в моем представлении, и я не хочу создавать пользовательские помощники для каждого элемента управления html, если мне не нужно.

Что я пытался сделать, это создать фильтр действий для обработки оценивая логические правила на моем бизнес-уровне, а затем внося изменения в метаданные для данного model.property.

Проблема в том, что мои модификации в метаданных, похоже, не делают это для представления. Мне кажется, что мои изменения в метаданных внутри фильтра действий не по ссылке, поэтому я не изменяю тот же экземпляр, который используется для представления?

public override void OnResultExecuting(ResultExecutingContext filterContext) 
    { 
    var trans = filterContext.Controller.ViewData.ModelMetadata.Properties.Where(e => e.PropertyName == "Transaction").FirstOrDefault(); 
    trans.DisplayName = "Show FOO!"; 
} 

Что я делаю неправильно?

ответ

1

Вы не можете изменить ModelMetadata.Properties значения в фильтре на самом деле вы не можете изменить их вообще.

Проблемы находится внутри встроенного DataAnnotationsModelMetadataProvider (чтобы быть точным AssociatedMetadataProvider «ы GetMetadataForProperties метода) namelly ModelMetadata.Properties получает регенерированный из атрибутов каждый раз, когда вы итерацию над ним.

Таким образом, элементы внутри коллекции ModelMetadata.Properties неизменяемы.

Вы можете проверить его с отладкой:

public override void OnResultExecuting(ResultExecutingContext filterContext) 
{ 
    var properties = filterContext.Controller.ViewData.ModelMetadata.Properties 
    var trans1 = properties.Where(e => e.PropertyName == "Transaction").First(); 
    trans1.DisplayName = "Show FOO!"; 
    var trans2 = properties.Where(e => e.PropertyName == "Transaction").First(); 
} 

trans1 и trans2 будут разные случаи (вы можете проверить их хэш-код), так trans2 отображаемое_имя будет оригинальным отображаемое_имя не «Показать FOO!».

Для того, чтобы достичь своей цели, вам необходимо расширить/написать новый MetadataProvider.

+0

Спасибо, я понял это после некоторых проб и ошибок. В результате я создал пользовательский поставщик метаданных, который позволяет мне изменять свойства по мере необходимости. – JBeckton

0

Вы можете проверить роль пользователя в представлении и внести соответствующие корректировки. Роль оценивается на стороне сервера до рендеринга HTML-

@if(HttpContext.Current.User.IsInRole("MyRole")) { 
    <input type='text' id='txtSomeInput' /> 
} 
+0

Это именно то, что я стараюсь не делать. Не столько для аспекта роли пользователя, но и у нас есть другая логика, которая определяет, будут ли доступны определенные данные для редактирования в этом году по сравнению с прошлым годом. Предыдущие разработчики делали инструкции по всему месту, чтобы справиться с этим. Теперь, когда новый год катится вокруг кода, необходимо обновить примерно в 50 местах, чтобы логика рассмотрела новый год. С одного года на другое наши заявки на стипендию могут запрашивать различную информацию, представление и модель по-прежнему должны поддерживать просмотр/редактирование данных приложения за предыдущий год. – JBeckton

+0

Теперь я вижу ... как насчет частичного просмотра каждого нового года? Ваша стипендиальная модель остается прежней, но у вас есть словарь . Затем для _partial2012 вы передаете стипендию словаря [2012]. У меня возникли проблемы с мыслью о том, как вы это делаете с помощью одного представления, которое может включать или удалять различные поля каждый год без всех операторов if. –

+0

Я не возражаю против операторов if, пока они не видны. Я хочу централизовать эту логику для обслуживания. Вот почему я хотел манипулировать метаданными, чтобы помощники html могли просто делать то, что они уже делают, и мне не нужно ничего менять. Я смотрю на пользовательский поставщик метаданных, чтобы узнать, не имеет значения. – JBeckton

Смежные вопросы