[英]How to pass parameter of different type to a generic ServiceFilter or ActionFilter
我對 C# 和 ASP 不是很有經驗,我不確定我是否對這個問題采取了正確的方法。
這是它的簡要表示:
我有幾個與用戶相關但具有不同參數(例如字符串或 UserDTO)的端點,這是其中幾個:
[AllowAnonymous]
[HttpPut("{username}")]
// I want to pass [FromBody]UserUpdateDTO to the filter
[ServiceFilter(typeof(UserChangeManagerFilter<UserUpdateDTO>))]
public ActionResult<InternalStatus> UpdateUser([FromBody]UserUpdateDTO userDto)
{
...
}
[AllowAnonymous]
[HttpDelete("{username}")]
// I want to pass {username} to the filter
[ServiceFilter(typeof(UserChangeManagerFilter<string>))]
public ActionResult<InternalStatus> DeleteUser(string username)
{
...
}
現在,我需要在執行每個操作后執行一些代碼。 為此,我創建了一個通用過濾器 我的問題是過濾器需要知道用戶詳細信息,因此 PUT 端點必須將 UserDTO 元素傳遞給過濾器,而 DELETE 端點必須傳遞用戶名。 我不知道該怎么做,但經過研究,我發現使用通用服務過濾器是一種選擇。 所以我創建了這個:
namespace ActionFilters.ActionFilters
{
public class UserChangeManagerFilter<T> : IActionFilter
{
private UserInfo _user;
public UserChangeManagerFilter(UserUpdateDTO userContext)
{
_user.Username = userContext.Username;
_user.Firstname = userContext.FirstName;
...
}
public UserChangeManagerFilter(string username)
{
_user.Username = username;
_user.Firstname = "";
...
}
public void OnActionExecuting(ActionExecutingContext context)
{
}
public void OnActionExecuted(ActionExecutedContext context)
{
// Do whatever I need to do here
}
}
我在 Startup.cs 中添加服務,如下所示:
services.AddScoped<UserChangeManagerFilter<UserUpdateDTO>>();
services.AddScoped<UserChangeManagerFilter<string>>();
當我執行 PUT 端點時,我得到
System.InvalidOperationException: No constructor for type 'ActionFilters.ActionFilters.UserChangeManagerFilter`1[xxx.Services.UserUpdateDTO]' can be instantiated using services from the service container and default values.
當我執行 DELETE 端點時,我得到
System.InvalidOperationException: No constructor for type 'ActionFilters.ActionFilters.UserChangeManagerFilter`1[System.String]' can be instantiated using services from the service container and default values.
我知道這不是對您問題的直接回答,但是如何使用非通用過濾器然后使用 OnActionExecuting 來檢查正在傳遞的 model 並根據收到的 object 的類型根據需要提取數據:
public void OnActionExecuting(ActionExecutingContext context)
{
var userDto = actionContext.ActionArguments.Values.OfType<UserUpdateDTO>().Single();
if(userDto !=null)
{
_user.Username = userContext.Username;
_user.Firstname = userContext.FirstName;
...
}else
{
//look for the string value
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.