代码之家  ›  专栏  ›  技术社区  ›  michasaucer

在ASP.NET中向请求体写入数据。NET核心

  •  0
  • michasaucer  · 技术社区  · 5 年前

    我有 base 类为我的应用程序中的每个请求:

    public abstract class BaseDto
    {
       public string Uid { get; set; }
    }
    
    public class RequestDto : BaseDto
    {
        public string SomeData { get; set; }
    }
    

    我用我的 ReuqestDto 类在我的控制器操作中:

    [HttpGet]
    public IEnumerable<string> Get(RequestDto req)
    {
        // some logic on request
        if (req.Uid != null)
        {
            // perform action
        }
    
    }
    

    用户仅通过 SomeData 属性给我。在我的JWT令牌中,我保存了一些关于 Uid 对于 BaseDto .将数据写入的最佳方式是什么 Uid 使用中间件/过滤器将该信息保存在我的 Get() 方法?我试着连载 HttpContext.Request.Body 但没有成功,因为我找不到,如何正确地去做。或者,这个问题可能有更好的解决方案?如何将数据写入应用程序中的传入对象?

    0 回复  |  直到 5 年前
        1
  •  1
  •   Dharman vijay    5 年前

    这可能是你想要的。

    你应该为这样的模型创建自己的界面

    public interface IMyRequestType { }
    

    您的模型应该实现它,以便在FilterAttribute中查找模型

    public class MyModel : IMyRequestType
    {
        public string ID { get; set; }
    }
    

    并使用创建您的过滤器属性 OnActionExecuting 实施

    public class MyFilterAttribute : TypeFilterAttribute
    {
        public MyFilterAttribute() : base(typeof(MyFilterImpl)) { }
    
        private class MyFilterImpl : IActionFilter
        {
            private readonly ILogger _logger;
    
            public MyFilterAttributeImpl(ILoggerFactory loggerFactory)
            {
                // get something from DI
                _logger = loggerFactory.CreateLogger<MyFilterAttributeImpl>();
            }
    
            public void OnActionExecuting(ActionExecutingContext context)
            {
                // get your request model
                var model = context.ActionArguments.Values.OfType<IMyRequestType>().Single();
    
                // get your key
                //context.HttpContext.User or whatever
    
                // do something with model
            }
    
            public void OnActionExecuted(ActionExecutedContext context)
            {
                // perform some logic work
            }
        }
    }
    
        2
  •  1
  •   KarateJB    5 年前

    我经常创建一个过滤器来实现 Attribute 和 IAsyncActionFilter 在进入控制器的操作之前获取信息。

    这里是一个例子,

    using System.IdentityModel.Tokens.Jwt;
    
     public class UserProfileFilter : Attribute, IAsyncActionFilter
     {
            public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
            {
                string uid = string.Empty;
                StringValues authHeaderVal = default(StringValues);
    
                // Get UID from JWT
                if (context.HttpContext.Request.Headers.TryGetValue("Authorization", out authHeaderVal))
                {
                    string bearerTokenPrefix = "Bearer";
                    string accessToken = string.Empty;
                    string authHeaderStr = authHeaderVal.ToString();
                    if (!string.IsNullOrEmpty(authHeaderStr) && authHeaderStr.StartsWith(bearerTokenPrefix, StringComparison.OrdinalIgnoreCase))
                    {
                        accessToken = authHeaderStr.Replace(bearerTokenPrefix, string.Empty, StringComparison.OrdinalIgnoreCase).Trim();
                    }
    
                    var handler = new JwtSecurityTokenHandler();
                    var token = handler.ReadJwtToken(accessToken);
                    uid = token.Claims.FirstOrDefault(c => c.Type.Equals("sub", StringComparison.OrdinalIgnoreCase))?.Value;
                }
    
                // Or Get UID from ActionExecutingContext
                var user = context.HttpContext.User;
                if (user.Identity.IsAuthenticated)
                {
                    uid = user.Claims.FirstOrDefault(c => c.Type.Equals("sub", StringComparison.OrdinalIgnoreCase))?.Value;
                }
    
                // Get payload
                RequestDto payload = (RequestDto)context.ActionArguments?.Values.FirstOrDefault(v => v is RequestDto);
                payload.Uid = uid;
    
                await next();
            }
    }
    

    然后,您可以对任何操作进行筛选。

    [HttpPost]
    [Authorize]
    [TypeFilter(typeof(UserProfileFilter))]
    public ActionResult<IActionResult> AdminGet(RequestDto request)
    {           
       Debug.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(request));
       return this.Ok();
    }
    
    

    上述过滤器将使用 sub claim的值覆盖传入有效负载的值。

    例如,如果我按如下方式发布有效载荷,

    {
        "uid" : "",
        "someData": "Test"
    }
    

    该动作最终将输出 {"Uid":"MyID","SomeData":"Test"} .