簡體   English   中英

如何將不同類型的參數傳遞給通用 ServiceFilter 或 ActionFilter

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM