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?
EditOperation
method's implementation of theget
EditOperation
, and I pass it to the program change methods only for the filter - Bald