【问题标题】:How to bind remaining query parameters to a dictionary in ASP.NET Core如何将剩余的查询参数绑定到 ASP.NET Core 中的字典
【发布时间】:2020-07-28 22:38:08
【问题描述】:

我正在为 ASP.NET Core 应用程序使用模型绑定,它配置了几个已知属性,然后是一个字典,我希望在其中添加任何其他 URL 属性。我希望我的查询字符串如下所示:

/foobar?Id=5&Status=pending&SpecialKey=test

让它在我的模型中填充属性Id = 5, Status = Pending,并拥有一个名为ExtraParams 的字典,其中包含一个项目,“SpecialKey”的键和“test”的值。

这是我现在的模型:

using Microsoft.AspNetCore.Http;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text.Json.Serialization;

namespace MyProject.Models
{
    public class MyCustomModel
    {
        public string? Id { get; set; }
        public string? Status { get; set; }
        public string? SerialNumber { get; set; }
        public string? Nickname { get; set; }
        public string? DisplayName { get; set; }

        [JsonExtensionData]
        public Dictionary<string, object> ExtraParams { get; set; } = new Dictionary<string, JToken>();
    }
}

就目前而言,只有 Id/Status 被填充。我可以在ExtraParams 中获取任何内容的唯一方法是使用我不想要的ExtraParams[key]=test 的查询字符串表示法。

【问题讨论】:

  • 为什么不用一个简单的字符串参数,它的值是base 64编码器编码的jason字符串呢?您可以轻松获取编码值,然后在后端解码并转换为主 json。之后反序列化为您想要的字典。
  • 我正在替换现有的 API,所以我无法更改请求的格式
  • 你的意思是你只能在后端进行更改?如果您无法更改请求,请说明数据是如何从客户端传递的!

标签: c# asp.net-core


【解决方案1】:

我有一个类似的用例。以下是我使用的步骤

  • 向控制器操作方法添加可选参数
public async Task<IActionResult> GetAllItemsAsync(string searchString, int? pageNo = 1, int? pageSize = 10, Dictionary<string, object> filters = null)
{
   <My-Controller-Logic>
}
  • 创建了一个 ActionFilterAttribute 覆盖
    public class QueryStringActionFilter : ActionFilterAttribute
    {
        private const string _additionalParamsFieldName = "filters";

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            var filters = new Dictionary<string, object>();
            foreach (var kvp in context.HttpContext.Request.Query)
            {
                if (!context.ActionArguments.ContainsKey(kvp.Key))
                {
                    filters.Add(kvp.Key, kvp.Value);
                }
            }
            context.ActionArguments[_additionalParamsFieldName] = filters;
            base.OnActionExecuting(context);
        }
    }
  • 在我的控制器操作方法中添加了操作过滤器属性
[QueryStringActionFilter]
public async Task<IActionResult> GetAllItemsAsync(string searchString, int? pageNo = 1, int? pageSize = 10, Dictionary<string, object> filters = null)
{
   <My-Controller-Logic>
}

这样,除了 searchString、pageNo 和 pageSize 之外,我的所有查询参数都会填充到过滤器中。

【讨论】:

    【解决方案2】:

    一种方法是使用此示例代码将所有参数填充到后端的字典中:

    Dictionary<string, string> parameters = HttpContext.Current.Request.QueryString.Keys.Cast<string>()
                .ToDictionary(k => k, v => HttpContext.Current.Request.QueryString[v]);
    

    甚至this 可能会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-12
      相关资源
      最近更新 更多