1

Я создаю приложение технической поддержки поддержки asp mvc 5. Приложение потребует от пользователей регистрации для подачи заявки на поддержку. Действия пользователей состоят в том, чтобы обновить билет, добавив примечания как поток.ASP MVC 5 Организация проекта, чтобы избежать дублирования кода

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

Существует администратор сайта, который может настроить сайт.

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

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

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

Или вы просто раздуваете контроллеры и представления с помощью if then else для каждого создаваемого роли пользователя любого типа?

Некоторые рекомендации относительно наилучшей практики для этого конкретного приложения будут оценены.

Единственное преимущество создания зоны для агентов - это то, что я могу кардинально изменить внешний вид портала Агента, например, иметь другой URL-адрес. mysite/agentdesk/tickets, и его было бы легче поддерживать, но за счет дублирования кода.

/* Текущий контроллер Logic и вид модели */ Как вы можете видеть, что в ViewModel предоставляет свойства статус и приоритет, который можно установить только агент.

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

public class TicketViewModel 
{ 

     public int Id { get; set; } 

     [Required] 
     public string Subject { get; set; } 

     [Required] 
     public string Description { get; set; } 

     // Only an agent can change the status 
     [Required] 
     public int Status { get; set; } 

     // Only an agent can change the priority 
     [Required] 
     public int Priority { get; set; } 


     public IEnumerable<StatusType> StatusTypes { get; set; } 
     public IEnumerable<PriorityLevel> PriorityLevels { get; set; } 

} 

public class TicketController : Controller 
{ 

    [Authorize] 
    public ActionResult Create() 
    { 
     var viewModel = new TicketViewModel 
     { 
      StatusTypes = _context.StatusTypes.ToList(), 
      PriorityLevels = _context.PriorityLevels.ToList() 

     }; 

     return View(viewModel); 
    } 


    [Authorize] 
    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Create(TicketViewModel viewModel) 
    { 
     if (!ModelState.IsValid) 
     { 
      viewModel.StatusTypes = _context.StatusTypes.ToList(), 
      viewModel.PriorityLevels = _context.PriorityLevels.ToList() 
      return View(viewModel); 
     } 

     bool agentRole = HttpContext.Current.User.IsInRole("Agent"); 

     var ticket = new Ticket 
     { 
      CreatedBy = User.Identity.GetUserId(), 
      Subject = viewModel.Subject, 
      Description = viewModel.Description, 
      StatusId = agentRole ? viewModel.Status : 1, 
      PriorityId = agentRole ? viewModel.Priority : 1 
     }; 

     _context.Tickets.Add(ticket); 
     _context.SaveChanges(); 

     return RedirectToAction("Index", "Tickets"); 
    } 
} 
+0

Я бы, скорее всего, представила зону агента со всеми контроллерами, украшенными [Role («Agent»)] и т. Д.Что касается дублированных представлений, если вы вводите общие общие поля в виде частичного представления, это сократит это. Что касается ваших контроллеров, они должны придерживаться как можно меньше бизнес-логики, поэтому создайте бизнес-класс с именем TicketCreator, например, который содержит два метода AsAgent и AsUser. Затем вы можете вызывать каждый из своих разных контроллеров, но разделять столько логика в классе, как вам нравится – uk2k05

+0

Просто чтобы добавить, ваши методы бизнес-класса также возвратят два разных типа ViewModel, чтобы вы не отправляли конфиденциальные данные пользователю – uk2k05

+0

@ uk2k05 можете ли вы показать пример своего бизнес-класса с именем Решение TicketCreator. Я пытаюсь понять, как я могу повлиять на viewmodel, чтобы разместить как клиента, так и агента. – adam78

ответ

0

Я думаю, что это был бы лучший способ пойти. Простой факт состоит в том, что сложность вашего кода будет быстро выходить из-под контроля в противном случае. Одно дело - просто показать/скрыть поля формы на основе какой-то роли, но на самом деле для обеспечения безопасности это необходимо для защиты от сквозных. Другими словами, вам также нужно будет проверить внутри вашего действия, что свойства устанавливаются только со значениями, если пользователю разрешен доступ к этим свойствам. Трудно публиковать вещи, которые вы не можете редактировать, даже если для этого не существует полей формы.

Чтобы обойти проблему дублирования кода, просто не дублируйте код. Это звучит немного банально, но вот оно. Аналогичный код в вашем действии можно разделить на базовый контроллер или только на некоторый вспомогательный класс. Аналогичный код в ваших представлениях можно разделить на частичные. В принципе, все, что было бы одинаково для обеих ситуаций, должно идти куда-то, где один и тот же код может использоваться в обеих ситуациях.

+0

Если бы я должен был настроить область, специфичную для агентов, я бы все же закончил с почти идентичными методами управления и моделью просмотра - см. Мой пример выше, как текущая логика. Как бы вы реорганизовали методы viewmodel и controller. Пример был бы полезен? – adam78

+0

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

+0

Вы даже можете использовать generics для sub в модели правого представления, сущности и т. Д. В принципе вам просто нужно использовать инструменты, которые C# уже дает вам для повторного использования кода. В модели контроллера/представления нет ничего особенного. Это просто классы, как и любые другие, и вы можете делать с ними все, что вы можете сделать с любым классом на C#. –