Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net core 一种在绑定asp.net core后设置一个属性值的方法_Asp.net Core_Middleware_Model Binding - Fatal编程技术网

Asp.net core 一种在绑定asp.net core后设置一个属性值的方法

Asp.net core 一种在绑定asp.net core后设置一个属性值的方法,asp.net-core,middleware,model-binding,Asp.net Core,Middleware,Model Binding,我正在创建一个asp.net core 2.2 api。我有几个模型类,其中大多数包含字符串属性CreatorId: public class ModelOne { public string CreatorId { get; set; } //other boring properties } 我的控制器的操作接受具有[FromBody]属性的这些模型 [HttpPost] public IActionResult Create([FromBody] ModelOne mod

我正在创建一个asp.net core 2.2 api。我有几个模型类,其中大多数包含字符串属性CreatorId:

public class ModelOne
{
    public string CreatorId { get; set; }
    //other boring properties
}
我的控制器的操作接受具有[FromBody]属性的这些模型

[HttpPost]
public IActionResult Create([FromBody] ModelOne model) { }
我不希望我的web客户端设置CreatorId属性。此CreatorId字段出现在数十个类中,我不想在Controllers操作中手动设置它,如下所示:

model.CreatorId = User.Claims.First(claim => claim.Type == "id").Value;
我不能用任何自定义模型绑定相关属性污染模型类。我不想用任何模型绑定属性污染控制器或操作


现在,问题是:在模型绑定检查(可能使用反射)模型类是否包含CreatorId字段并更新该值后,是否有方法添加一些自定义逻辑。如果无法从ControllerBase用户属性执行,则可以查看jwt令牌。该过程对开发人员来说应该是透明的,没有属性-可能是一些在应用程序级别注册的自定义模型绑定器,或者是一些透明工作的中间件。

好的,我发明了自己的基于操作过滤器的解决方案。看起来效果不错。我已经创建了一个自定义操作筛选器:

public class CreatorIdActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ActionArguments.ContainsKey("request")) return;

        var request = context.ActionArguments["request"];
        var creatorIdProperty = request?.GetType().GetProperties().FirstOrDefault(x => x.Name == "CreatorId");

        if (creatorIdProperty == null) return;

        var user = ((ControllerBase)context.Controller).User;
        creatorIdProperty.SetValue(request, user.Claims.First(claim => claim.Type == "id").Value);
    }

    public void OnActionExecuted(ActionExecutedContext context) { }
}
刚刚在ConfigureServices中注册的

services.AddMvc(options => { options.Filters.Add(typeof(CreatorIdActionFilter)); })
不需要其他样板代码。参数名总是“request”,这就是为什么我从ActionArguments中获取这个名称,但如果需要,当然可以用更通用的方式实现

解决方案是有效的。我只想问一些专家一个问题——我们能称之为优雅而高效的解决方案吗?也许我用了一些坏习惯?如能就此发表任何意见,我将不胜感激