簡體   English   中英

MVC - 如何在不將括號 [0] 添加到鍵的情況下反序列化字典?

[英]MVC - How to deserialize a Dictionary without having brackets [0] added to the key?

當我將“brand”發送到 api 時,我反序列化字典的關鍵結果為“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] ”如何保留我發送的真實值?

編輯:我需要標簽能夠包含多個標簽,有多個選項,這是一個簡單的例子。

在此處輸入圖片說明

我的問題的一個解決方案是創建一個自定義模型綁定,所以這就是現在正在使用的,但我不明白為什么我需要這樣做,我覺得應該有一種更簡單的方法? 但無論如何我都會把它放在這里。

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; }
}

結果是同樣的事情,添加一個日期時間字段只是為了它:

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":["baremeralals"]}}

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

鍵:真值:真

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM