Какой чистый / СУХОЙ способ показать доступные операции с пользовательским контентом? - PullRequest
5 голосов
/ 06 июня 2011

Работа над приложением ASP.NET MVC 3 (Razor), которое в основном касается UGC (пользовательский контент).

Я работаю в области вопросов и ответов - где пользователи могут задавать вопросы, другие могут отвечать, голосовать и т. Д.

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

Возьмите сценарий «Страницы с подробностями вопроса» (как эта страница в Переполнении стека).

Любой (прошедший проверку подлинности) пользователь может:

  • Проголосуйте за вопрос / ответ
  • Ответ

Владелец вопроса может:

  • Редактировать
  • Удалить
  • Отметить ответ

и т. Д.

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

Я создаю его с помощью AutoMapper.

Как отобразить на странице «стикеры» (например, гиперссылки) в зависимости от доступных операций?

Мое нынешнее мышление:

  • Я создаю перечисление: QuestionOperation (Ответить, Редактировать, Отключить, Голосовать, Ответить и т. Д.)
  • Я добавляю свойство типа IEnumerable<QuestionOperation> к моей ViewModel
  • Я установил это свойство в своем методе действия (HTTP GET), проверяя, прошел ли пользователь аутентификацию и роли, в которые он входит.
  • Затем я использую шаблон редактора для рендеринга каждой операции в виде гиперссылки, используя Html.ActionLink

Это считается чистым подходом - или кто-нибудь может предложить лучший?

Помня, что я снова использую это QuestionViewModel на трех страницах:

  1. Страница с подробностями вопроса
  2. Страница "Задать вопрос"
  3. Страница "Редактировать вопрос"

Так как эти операции зависят от страницы / пользователя, на самом деле это невозможно сделать с помощью AutoMapper.

1 Ответ

1 голос
/ 06 июня 2011

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

Что-то между строк:

public class UserLinksController: Controller
{
    // TODO: ctor DI of a repository, etc...

    public ActionResult Index(string questionId)
    {
        string username = User.Identity.IsAuthenticated 
            ? User.Identity.Name : string.Empty;
        var roles = _repository.GetRolesForQuestion(username, questionId);
        var model = Mapper.Map<UserRoles, RolesViewModel>(roles);
        return PartialView(model);
    }
}

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

@model RolesViewModel
@if(Model.CanEdit)
{
    @Html.ActionLink("Edit", "Edit", "Questions")    
}
@if(Model.CanDelete)
{
    @Html.ActionLink("Delete", "Delete", "Questions")    
}
...

Теперь где-нибудь в вашем основном представлении просто включите это действие, используя метод Html.Action:

@Html.Action("Index", "UserLinks", new { questionId = Model.QuestionId })
...