微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MVC-如何在不添加括号[0]的情况下反序列化字典?

如何解决MVC-如何在不添加括号[0]的情况下反序列化字典?

当我将“ brand”发送到api时,我反序列化Dictionary的键结果为“ brand [0]”。

我有一个这样的班级:

public class SearchRequest
{
    public bool Html { get; set; } = false;
    public Dictionary<string,HashSet<string>> Tags { get; set; }
}

// MVC Controller
[HttpPost]
public ActionResult Index(SearchRequest searchRequest)
{
    ...
}

还有这样的json请求,我将其发布到控制器:

{
  "html": true,"tags": {
    "brand": [
      "bareminerals"
    ]
  }
} 

工作的绑定接缝已创建,但searchRequest对象已创建,但结果字典中没有键“ brand ”,但插入了键“ brand [0] ” >”如何保存发送的真实值?

编辑:我需要标签才能包含多个标签以及多个选项,这是一个简单的示例。

enter image description here

解决方法

解决我的问题的一种方法是创建一个自定义模型绑定,所以这就是现在使用的方法,但是我不明白为什么需要这样做,我觉得应该有一种更简单的方法?但是无论如何我还是会喜欢这里的。

public class FromJsonBodyAttribute : CustomModelBinderAttribute
{
    public override IModelBinder GetBinder()
    {
        return new JsonModelBinder();
    }

    private class JsonModelBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext,ModelBindingContext bindingContext)
        {
            var stream = controllerContext.HttpContext.Request.InputStream;
            stream.Position = 0;
            using (var reader = new StreamReader(stream))
            {
                var checkoutOrderDataStr = reader.ReadToEnd();
                return JsonConvert.DeserializeObject(checkoutOrderDataStr,bindingContext.ModelType);
            }
        }
    }
}
,

我不确定您的设置是怎么回事。您不需要自定义活页夹。我仍然认为问题很可能与您的调用代码有关-无论您用作客户端如何。

我正在使用Asp.net Core 3.1。这是我一起进行的快速测试。

使用MVC创建的Asp.net Core Web应用程序模板。我声明了两个类-请求POCO和结果POCO。请求是您的课程:

public class SearchRequest
{
    public bool Html { get; set; } = false;
    public Dictionary<string,HashSet<string>> Tags { get; set; }
}

结果是一样的,只是添加了一个datetime字段:

public class SearchResult : SearchRequest
{
    public SearchResult(SearchRequest r)
    {
        this.Html = r.Html;
        this.Tags = r.Tags;
    }

    public DateTime RequestedAt { get; set; } = DateTime.Now;
}

我在默认的HomeController上添加了一个简单的post方法。

    [HttpPost]
    public IActionResult Index([FromBody] SearchRequest searchRequest)
    {
        return new ObjectResult(new SearchResult(searchRequest));
    }

我在解决方案中添加了一个控制台应用程序以充当客户端。我将两个类定义复制到该项目中。

我将此添加为主要方法。请注意,您可以在请求中选择骆驼套选项,也可以不使用-asp.net。

    static async Task Main(string[] _)
    {
        var tags = new[] { new { k = "brand",tags = new string[] { "bareminerals" } } }
                    .ToDictionary(x => x.k,v => new HashSet<string>(v.tags));

        var request = new SearchRequest() { Html = true,Tags = tags };

        var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };

        var json = JsonSerializer.Serialize(request,options);

        Console.WriteLine(json);

        using (var client = new HttpClient())
        {
            var content = new StringContent(json,Encoding.UTF8,"application/json");
            
            var response = await client.PostAsync("http://localhost:59276",content);

            response.EnsureSuccessStatusCode();

            var data = await response.Content.ReadAsStringAsync();

            var result = JsonSerializer.Deserialize<SearchResult>(data,options);

            Console.WriteLine(data);

            var keysSame = Enumerable.SequenceEqual(request.Tags.Keys,result.Tags.Keys);
            var valuesSame = Enumerable.SequenceEqual(request.Tags.Values.SelectMany(x => x),result.Tags.Values.SelectMany(x=>x));

            Console.WriteLine($"Keys: {keysSame} Values: {valuesSame}");
        }
    }

这将输出:

{“ html”:true,“ tags”:{“ brand”:[“ bareminerals”]}}

{“ requestedAt”:“ 2020-10-30T19:22:17.8525982-04:00”,“ html”:true,“ tags”:{“ brand”:[“ bareminerals”]}}}

键:真值:真

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。