Взять имя представления из реального имени действия, а не из ActionNameAttribute?
[ActionName("new-post")]
public async Task<IActionResult> NewPost()
{
return View();
}
В этом примере ASP.NET Core будет искать представление по имени "new-post", но я хочу, чтобы оно искало по реальному имени действия, которое "NewPost". В ASP.NET MVC 5 я сделал это с помощью фильтра, в котором было сохранено имя представления (filterContext.Result as ViewResultBase).ViewName. В ASP.NET Core 2.0 фильтры IAsyncActionFilter используются для асинхронных действий и контекста. Результат всегда равен нулю, поэтому я не могу изменить имя представления через него. Есть ли другие возможные способы сделать это? Конечно, я мог бы передать имя представления в return View(), но это было бы избыточным дублированием уже известного имени действия.
1 ответ
Я обнаружил, что IActionFilter может использоваться как для синхронных, так и для асинхронных действий: http://jakeydocs.readthedocs.io/en/latest/mvc/controllers/filters.html
В контексте IActionFilter.Result доступен, так что теперь я могу заставить ASP.NET Core 2.0 принимать реальное имя действия следующим образом:
public class SetActionViewNameFromActionNameAttributeFilter : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
var result = context.Result as ViewResult;
if (result != null)
{
var controllerActionDescriptor = (ControllerActionDescriptor)context.ActionDescriptor;
var actionNameAttr = controllerActionDescriptor.MethodInfo.TryGetAttribute<ActionNameAttribute>();
bool changeViewName = actionNameAttr != null && (result.ViewName == null || result.ViewName == actionNameAttr.Name);
if (changeViewName)
result.ViewName = controllerActionDescriptor.MethodInfo.Name;
}
}
public void OnActionExecuting(ActionExecutingContext context)
{
}
}
Если бы кто-то предложил более элегантный способ, я был бы признателен.