I am building an asp mvc 5 support ticket helpdesk application. The application will require users to signup to submit a support ticket. Users actions would be to update the ticket by adding notes like a thread.
Agents will manage the ticket and have additional permissions to edit the ticket and create internal as well as public notes and be able to view all tickets.
There is a site admin who can configure the site.
The issue is if I have a controller say called ticket controller, the main actions on the create or edit ticket are similar for both an agent and a user. The differences are that when a user creates a ticket they can only complete certain fields on the form where as an agent can update additional fields.
So what I'm ending up with is a lot of if then else statements in my controllers and views to check user roles inorder to restrict what form fields and actions are displayed to the different types of users. Also my viewmodels are exposing properties to a customer that they shouldn't have permissions to.
So my question is how do you organize this type of set up. Do you create a separate area for Agents and duplicate all the controllers and viewmodels to cater for this type of user.
Or would you just bloat the controllers and views with if then else statements for every different type of user role that is created?
Some advise on what would be best practice for this particular application would be appreciated.
The only benefit of creating an Area for agents is that I could drastically change the look and feel of the Agent portal, have a different url eg. mysite/agentdesk/tickets and it would be easier to maintain but at the expense of duplicating code.
/* Current Controller Logic and view model */ As you can see the in viewmodel exposes the status and priority properties which only an agent can set.
In the create method of the controller, you can see the teneray operator being used to determing if the user has the correct role to set the above properties.
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");
}
}