如何将自定义对象从异步操作过滤器传递到 ASP.net 核心中的控制器?

时间:2021-07-26 16:33:58

标签: c# asp.net asp.net-mvc asp.net-core asp.net-web-api

我一直无法找到这个问题的好答案,或者它是否可能。我想让我的 filter 使用 object 添加 parameter 作为 context.ActionArguments["personService"] = personService. 我可以使用 string type 进行论证,但是当我尝试使用自定义对象时,我一直使用 415 error 获得 postman

我知道我可以使用 context.HttpContext.Items.Add("personService",personService) 传递一个对象,但这不是我正在做的事情的优雅解决方案。我有一个课程如下:

public class PersonService
    {
        private readonly string _name;
        private readonly int _age;
        private readonly string _location;
        public Person(string name, int age, string location)
        {
            _name = name;
            _age = age;
            _location = location;
        }

        public string printPerson(){
            return "name: {0} age: {1} location {2}", _name, _age, _location";
        }
    }

然后我的过滤器如下所示:

public class PersonFilterAttribute: Attribute, IAsyncActionFilter
    {
        public PersonFilterAttribute()
        {
        }

        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
           context.ActionArguments["personService"] = new PersonService("Thomas", 29,"Miami");

          
          await next();
        }
    }
 [HttpGet("personService")]
 [ServiceFilter(typeof(PersonFilterAttribute))]
 public async Task<string> passTheObject(Person person)
    {
          return person.printPerson();
    }

1 个答案:

答案 0 :(得分:0)

您必须进行一些更改才能工作。首先,更改 API 以添加属性 [FromQuery] 以指定 complex type 参数的来源(默认情况下,路由数据和查询字符串值仅用于简单类型)。

[HttpGet("personService")]
[ServiceFilter(typeof(PersonFilterAttribute))]
public async Task<string> passTheObject([FromQuery] Person person)
{
    return person.printPerson();
}

接下来您必须向模型 Person 添加无参数构造函数:

public class Person {
    private readonly string _name;
    private readonly int _age;
    private readonly string _location;

    public Person() {
    }

    public Person(string name, int age, string location) {
        _name = name;
        _age = age;
        _location = location;
    }

    public string printPerson() {
        return string.Format("name: {0} age: {1} location {2}", _name, _age, _location);
    }
}

由于在执行 OnActionExecution Action 过滤器之前,模型绑定已经完成并且需要默认构造函数来创建模型的实例。