问题描述
当我将“ 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] ” >”如何保存发送的真实值?
编辑:我需要标签才能包含多个标签以及多个选项,这是一个简单的示例。
解决方法
解决我的问题的一种方法是创建一个自定义模型绑定,所以这就是现在使用的方法,但是我不明白为什么需要这样做,我觉得应该有一种更简单的方法?但是无论如何我还是会喜欢这里的。
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”]}}}
键:真值:真