gpt4 book ai didi

asp.net-mvc - 如何将 JSON.NET 作为 ASP.NET MVC Controller 的模型绑定(bind)程序?

转载 作者:行者123 更新时间:2023-12-03 02:44:46 25 4
gpt4 key购买 nike

ASP.NET Web API 团队决定使用 JSON.NET 库来进行模型绑定(bind) JSON 数据。然而,“普通”MVC Controller 仍然使用较差的 JsonDataContractSerializer。这会导致解析日期出现问题,让我很头痛。

请参阅此引用:
http://www.devcurry.com/2013/04/json-dates-are-different-in-aspnet-mvc.html

作者选择在客户端的Knockout层解决问题。但我更愿意通过在 MVC Controller 中使用与 Web API Controller 中相同的 JSON.NET 模型绑定(bind)器来解决此问题。

如何将不同的 JSON 模型绑定(bind)器替换为 ASP.NET MVC?具体来说,是 JSON.NET 库。如果可能的话,使用来自 Web API 的相同模型绑定(bind)器将是理想的选择。

最佳答案

我已经做到了这一点,并且还大量定制了 Json.NET 正在执行的序列化,方法是:

替换global.asax.cs中的默认格式化程序,Application_Start:

GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.JsonFormatter);
GlobalConfiguration.Configuration.Formatters.Add(new CustomJsonMediaTypeFormatter());

我的 CustomJsonMediaTypeFormatter 是:

public static class CustomJsonSettings
{
private static JsonSerializerSettings _settings;

public static JsonSerializerSettings Instance
{
get
{
if (_settings == null)
{
var settings = new JsonSerializerSettings();

// Must convert times coming from the client (always in UTC) to local - need both these parts:
settings.Converters.Add(new IsoDateTimeConverter { DateTimeStyles = System.Globalization.DateTimeStyles.AssumeUniversal }); // Critical part 1
settings.DateTimeZoneHandling = DateTimeZoneHandling.Local; // Critical part 2

// Skip circular references
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;

// Handle special cases in json (self-referencing loops, etc)
settings.ContractResolver = new CustomJsonResolver();

_settings = settings;
}

return _settings;
}
}
}

public class CustomJsonMediaTypeFormatter : MediaTypeFormatter
{
public JsonSerializerSettings _jsonSerializerSettings;

public CustomJsonMediaTypeFormatter()
{
_jsonSerializerSettings = CustomJsonSettings.Instance;

// Fill out the mediatype and encoding we support
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
SupportedEncodings.Add(new UTF8Encoding(false, true));
}

public override bool CanReadType(Type type)
{
return true;
}

public override bool CanWriteType(Type type)
{
return true;
}

public override Task<object> ReadFromStreamAsync(Type type, Stream stream, HttpContent content, IFormatterLogger formatterLogger)
{
// Create a serializer
JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);

// Create task reading the content
return Task.Factory.StartNew(() =>
{
using (StreamReader streamReader = new StreamReader(stream, SupportedEncodings.First()))
{
using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
{
return serializer.Deserialize(jsonTextReader, type);
}
}
});
}

public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContent content, TransportContext transportContext)
{
// Create a serializer
JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);

// Create task writing the serialized content
return Task.Factory.StartNew(() =>
{
using (StreamWriter streamWriter = new StreamWriter(stream, SupportedEncodings.First()))
{
using (JsonTextWriter jsonTextWriter = new JsonTextWriter(streamWriter))
{
serializer.Serialize(jsonTextWriter, value);
}
}
});
}
}

最后是 CustomJsonResolver:

public class CustomJsonResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, Newtonsoft.Json.MemberSerialization memberSerialization)
{
var list = base.CreateProperties(type, memberSerialization);

// Custom stuff for my app
if (type == typeof(Foo))
{
RemoveProperty(list, "Bar");
RemoveProperty(list, "Bar2");
}

return list;
}

private void RemoveProperty(IList<JsonProperty> list, string propertyName)
{
var rmc = list.FirstOrDefault(x => x.PropertyName == propertyName);

if (rmc != null)
{
list.Remove(rmc);
}
}
}

关于asp.net-mvc - 如何将 JSON.NET 作为 ASP.NET MVC Controller 的模型绑定(bind)程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20980241/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com