На сайте asp.net-mvc есть ли хороший шаблон для работы как с редактируемыми представлениями, так и с представлениями только для чтения?

У меня есть веб-сайт asp.net-mvc, на котором до сих пор не было никаких прав, поскольку он был открыт для всех. Многие страницы представляют собой подробные формы с текстовыми полями, раскрывающимися списками выбора и т. д.

Теперь мне нужно изменить это, чтобы сделать многие из существующих страниц «имеющими право», чтобы только определенные люди имели возможность редактирования, а все остальные видели страницу только для чтения. Я пытаюсь понять, должен ли я

  1. Создайте отдельное представление для каждого из моих существующих представлений с формами, которые только для чтения html на странице и перенаправляют на основе прав на стороне сервера, что-то вроде

    public ActionResult OrderView()
    {
         var isEntitled = Model.IsEntitled()
         if (isEntitled)
         { 
              return("OrderEditableView", GetViewModel()); 
         }
         else 
         {
             return("OrderReadOnlyView", GetViewModel());  
         }
    

    }

or

  1. Повторно используйте тот же вид и просто отключите или скройте кнопку «Сохранить» на экране.

на мой взгляд есть

     <% if (Model.IsEntitled) { %>
           <button id="saveButton">Save Changes</button>
     <% } %>

Второй вариант был бы намного быстрее в реализации, но был бы немного странным, потому что это выглядело бы так, как будто вы можете редактировать все поля, но просто не видите (или видите неактивную) кнопку «Сохранить» в форме.

Первый вариант кажется чище, но мне пришлось бы создать новое представление для каждого из моих экранов, и это кажется большой работой (в настоящее время более 100 представлений).

Это кажется распространенной ситуацией, поэтому я хотел посмотреть, есть ли передовой опыт решения этой ситуации. Очевидно, я ищу решение, учитывая текущую ситуацию, в которой я нахожусь, но мне также было бы интересно, есть ли шаблоны или решения, которые можно было бы считать передовой практикой или рекомендовать, если я начинаю с нуля.


person leora    schedule 04.05.2014    source источник
comment
Похоже, вам нужно создать класс сеанса сервера, в котором вы можете размещать такие вещи, как MyWeb.Session.isEntitled.   -  person Ross Bush    schedule 04.05.2014
comment
@Irb - у меня нет проблем с расчетом и определением того, имеет ли кто-то право. Что касается моего вопроса, я больше сосредоточен на том, как я управляю представлениями   -  person leora    schedule 04.05.2014
comment
Вы можете создать представление как частичное на основе редактируемых требований.   -  person Ross Bush    schedule 04.05.2014
comment
@Irb - разве это не первый вариант, который я перечислил выше?   -  person leora    schedule 04.05.2014
comment
Есть много шаблонов, чтобы делать то, что вы хотите. Но: используете ли вы помощники EditorFor для рендеринга всех элементов управления вводом, которые вы хотите преобразовать в пассивные элементы управления? Можно ли пользователям без прав администратора видеть деактивированные входы (или вам нужно, чтобы они видели простой текст)? Не слишком ли сложно вносить изменения или использовать пользовательские помощники, поведение которых вы хотите изменить? Согласны ли вы добавить некоторые функции из библиотеки JS, такой как Angular?   -  person Dave Alperovich    schedule 14.05.2014


Ответы (4)


Я бы пошел на создание отдельных частичных/полных представлений для обоих.

Причины:
легко изменять и поддерживать
проверочный код только в редактируемой части
четкое разделение задач
более чистый код
может быть, мы сможем повторно использовать часть кода путем абстрагирования/отделения аналогичного кода для повторного использования частичных представлений
легкий контроль над доступом

Кроме того, в реальном мире мы балансируем между бюджетом, временем и усилиями. поэтому, учитывая, что я могу использовать их сочетание в зависимости от ситуации.

person aamir sajjad    schedule 10.05.2014

Я бы выбрал второй вариант с одним представлением как для форм, доступных для записи, так и для форм только для чтения.

Для визуальной стороны я бы реализовал несколько вещей в дополнение к скрытию кнопки Сохранить:

  • Установите поля ввода только для чтения. Вы можете легко сделать это с помощью Javascript на стороне клиента.

  • Измените цвета (и, возможно, другие атрибуты) полей ввода, чтобы подчеркнуть, что они доступны только для чтения (например, удалите границы). Этого легко добиться с помощью таблицы стилей и одного дополнительного имени класса в теге формы.

Авторизация на стороне сервера также проста. Просто аннотируйте действие соответствующим образом.

Это может выглядеть так (упрощенно, с использованием Razor и jQuery):

Просмотр:

@using (Html.BeginForm("AddressController", "SaveChanges", FormMethod.Post,
        new { @class = Model.IsEntitled ? "regular" : "readonly"}))
{
   <p>
     @Html.TextboxFor(model => model.Name)
   </p>
   <p>
     @Html.TextboxFor(model => model.Address)
   </p>
   @if (Model.IsEntitled) {
     <p>
       <button id="saveButton">Save Changes</button>
     </p>
   }
}

<script type="text/javascript">
  $( document ).ready(function() {
     $('form.readonly input').attr("readonly", true);
  });
</script>

Контроллер:

public class AddressController : Controller {

    [Authorize(Roles = "xyz")]
    [HttpPost]
    public ActionResult SaveChanges(Address address) {
        ...
    }
}

CSS:

.readonly input {
    border: none;
}
person Torino    schedule 10.05.2014
comment
Я думаю, что это отличное решение. Использование javascript на стороне клиента таким образом, возможно, не идеально, но это отличный компромисс, поскольку он позволяет избежать необходимости вручную вносить изменения для каждого элемента ввода. - person Ben Aaronson; 15.05.2014

вариант - сделать переключатель в представлении.

<% if (Model.IsEntitled) 
{ 
    Html.Partial("OrderEditablePartialView", Model)
}
else 
{
    Html.Partial("OrderReadOnlyPartialView", Model)
}
%>

другим вариантом может быть создание пользовательских помощников Html для отображения элементов как редактируемых или только для чтения, что даст вам некоторую гибкость в отношении того, как вы обрабатываете каждый элемент.

грубый пример:

public static MvcHtmlString FormTextBox(this HtmlHelper helper, string name, string text, bool editable)
        {
            return
                new MvcHtmlString(
                    String.Format(
                        editable
                            ? "<input type='text' id='{0}' name='{0}' value='{1}'>"
                            : "<label for='{0}'>{1}</label>",
                            name, text));
        }
person Mark Redman    schedule 10.05.2014
comment
Перемещение предложения OP из контроллера в представление на самом деле не сильно меняет, и OP говорит , но мне придется пойти и создать новое представление для каждого из моих экранов, и это кажется большой работой (более 100 просмотров). в настоящее время) который это не решает. - person CodeCaster; 10.05.2014
comment
+1 за метод расширения. Таким образом, вы пишете представление один раз, и оно знает свою индивидуальность. Однако я бы использовал встроенные шаблоны EditorFor и DisplayFor: public static MvcHtmlString EditOrDisplayFor<TModel, TValue>( this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, bool isEditable) { return (isEditable) ? html.EditorFor(expression):html.DisplayFor(expression); } - person Colby Cavin; 15.05.2014

Самым быстрым решением был бы какой-нибудь javascript, отключающий все элементы ввода на страницах, на которые пользователь не имеет права. Как это реализовать, решать вам, это зависит от того, как структурированы ваши представления и модели.

Таким образом, вы можете повторно использовать представления редактирования, даже не редактируя их, но в зависимости от типа вашего пользователя вы можете ожидать вызовы «сайт не работает», когда ваши формы кажутся отключенными.

шаблоны или решения, которые считались бы передовой практикой или рекомендовались, если бы я начинал с нуля.

Правильный путь: DisplayTemplates и EditorTemplates с правильными моделями просмотра, но из вашего комментария "создайте новый вид для каждого из моих экранов, и это кажется большой работой", я понимаю, что вас это не интересует.

Так что я бы пошел с первым. Убедитесь, что вы проверили разрешения в [HttpPost] методах действий, так как злоумышленники могут легко повторно включить форму и опубликовать ее в любом случае.

person CodeCaster    schedule 10.05.2014