In the asp.net-mvc project, I use action filters to test the availability of a method in gui, an example of such a filter is below:
public class DisallowChangingTheApprovedOperationsAttribute : ActionFilterAttribute { public IOperationService _operationService { get; set; } public override void OnActionExecuting(ActionExecutingContext filterContext) { var valueResult = filterContext.Controller.ValueProvider.GetValue("operationId"); if (valueResult == null || string.IsNullOrWhiteSpace(valueResult.AttemptedValue)) { throw new InvalidOperationException("OperationId is not be null"); } int operationId = int.Parse(valueResult.AttemptedValue); var result = _operationService.IsPublished(operationId); if (result) { if (string.Equals(filterContext.HttpContext.Request.RequestType, "Get", System.StringComparison.InvariantCultureIgnoreCase)) { filterContext.Result = new RedirectResult(filterContext.HttpContext.Request.UrlReferrer.PathAndQuery); } else { filterContext.Result = new RedirectToRouteResult(filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, new RouteValueDictionary { { "operationId", operationId } }); } } } } its purpose is to prevent a change in the approved Operation ; the method for the passed parameter operationId checks the state var result = _operationService.IsPublished(operationId); and if the result is true then the action is canceled.
I apply this filter to the methods I need: EditOperation , DeleteOperation , etc., an example of a method for editing below:
[DisallowChangingTheApprovedOperations] public ActionResult EditOperation(int operationId) { ViewBag.Products = new SelectList(_productService.GetProductList(), "Id", "Name"); ViewBag.Equipments = new SelectList(_equipmentService.GetEquipmentList(), "Id", "SelectListName"); ViewBag.Units = new SelectList(_unitService.GetAll(), "Id", "FullName"); var model = _operationService.GetOperation(operationId); return View("EditOperation", model); } [HttpPost] [DisallowChangingTheApprovedOperations] public Actionresult EditOperation(int operationId, EditedOperation model) { } In order for this method to work, I have to drag the operationId into each of the methods, which seems to me to be not convenient / not correct, but this is not all.
I also have a Program entity that relates to Operation in the ratio 1 operation, many programs, for working with Program I have methods: AddProgram , EditProgram , etc. I need to prohibit changes to an operation based on its state ( _operationService.isPublished(int operationId) ) - I cannot add, modify existing programs, for these purposes I pass the operationId parameter to the editing, modification, removal of the program and apply the same DisallowChangingTheApprovedOperations filter to the method
An example of a method for editing a program:
[DisallowChangingTheApprovedOperations] //здесь прочие методы public ActionResult EditProgram(int operationId, programId) {} those. here, in addition to the program id , I have to pass on the operation id as well, as an option you can implement a method from the ActionFilterAttribute inherited from which, based on the programId will receive the status of the operation and, according to some logic, cancel or allow the action, i.e. something like
public class DisallowChangingTheApprovedOperationsForTheProgrammAttribute : ActionFilterAttribute { //получаем programId из контекста var result = _operationService.GetOperationStateForTheProgramm(programId); //отменяем действия в соответствии с логикой } Tell me how to do better / correctly implement the possibility of restricting some user actions in accordance with certain logic?
EditOperationmethod's implementation of thegetEditOperation, and I pass it to the program change methods only for the filter - Bald