Передайте объект из ActionFilter.OnActionExecuting() в ApiController
Я хочу создать объект для каждого запроса HTTP в ActionFilter и передать этот объект контроллеру. До сих пор я пробовал Request.Properties [] следующим образом
public class DbReadonlyAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
actionContext.Request.Properties["CustomObjectKey"] = new MyClass();
И я также попытался назначить новый объект непосредственно классу ControllerBase.
public class DbReadonlyAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var controller = (MyControllerBase) actionContext.ControllerContext.Controller;
controller.StorageContextFactory = new MyClass();
Проблема заключается в том, что ни один из методов не предоставляет экземпляр MyClass для контроллера, потому что новое свойство ["CustomObjectKey"] теряется в конвейере Webapi к моменту вызова метода контроллера.
Контроллер повторно создается конвейером webapi после фильтра вызова OnActionExecuting().
Точки перехвата подтверждают, что конвейер Webapi рассылает следующий поток событий во время одного HTTP-запроса.
- конструктор MyControllerBase()
- MyAuthenticationFilter
- Фильтр OnActionExecuting()
- конструктор MyControllerBase()
- MyController.MethodA()
Двойная инстанция MyControler нечетна, но прямо сейчас я ищу любую технику передачи вновь созданного объекта из фильтра действий в контроллер.
Edit-1: MyAuthorizationFilter, упомянутый в v1 этого вопроса, фактически является фильтром аутентификации. Все еще расследует.
Решение: ошибка была в другом фильтре. После того как я удалил свой фильтр проверки подлинности, проблема, о которой сообщалось в этом вопросе, ушла.
Ответы
Ответ 1
Вы должны будете использовать .add
метод Request.Properties
коллекции.
public class DbReadonlyAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
actionContext.Request.Properties.Add(new KeyValuePair<string, object>("CustomObjectKey", new MyClass()));
Вы можете получить это значение из своего контроллера api.
object _customObject= null;
if (Request.Properties.TryGetValue("CustomObjectKey", out _customObjectKey))
{
MyClass myObject = (MyClass)_customObject;
}
Ответ 2
Другой способ передать переменную из ActionFilter.OnActionExecuting() в ApiController:
public class CustomFilterAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext actionContext)
{
actionContext.ControllerContext.RequestContext.RouteData.Values["CustomValue"] = "CustomValue";
}
}
Обратите внимание на использование ActionFilterAttribute для веб-API:
System.Web.Http.Filters.ActionFilterAttribute
Не для классики MVC:
System.Web.Mvc.ActionFilterAttribute
С помощью:
[CustomFilter]
public class SomeController : ApiController
{
string customValue = RequestContext.RouteData.Values.ToDictionary(x => x.Key, y => y.Value)["user_id"].ToString();
//...
}