Мне нужно написать собственный JsonConverter в моем проекте ASP.NET MVC Core 2 для десериализации данных JSON в теле jQuery POST, поскольку это привязка модели по умолчанию. Сложная часть здесь заключается в том, что мне нужен TypeNameHandling для входящего объекта, который содержит массив базового типа или массив полиморфных типов. Я мог бы аннотировать объект с помощью
[JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto)]
но проблемы безопасности, связанные с этим, не приемлемы для моего проекта. Я написал собственный конвертер JSON и пометил свой объект взамен ниже, но, похоже, он не использует мой собственный конвертер (точка останова не достигнута).
[JsonConverter(typeof(ApplicationLoggingConverter))]
Полный соответствующий код ниже. Мое приложение LoggingModel:
public class ApplicationLoggingModel
{
public Guid ApplicationId { get; set; }
[JsonConverter(typeof(ApplicationLoggingConverter))]
public ModelActionBase[] Changes { get; set; }
}
Действие контроллера:
[HttpPost("Save/{id}")]
public async Task<ActionResult> Save(Guid id, [FromBody]ApplicationLoggingModel model)
{
model.ApplicationId = id;
//nothing yet implemented
return Ok();
}
Пользовательский конвертер:
public class ApplicationLoggingConverter : JsonConverter
{
private readonly Type[] _types;
public ApplicationLoggingConverter(params Type[] types)
{
_types = types;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.StartArray)
{
return serializer.Deserialize<ApplicationLoggingModel[]>(reader);
}
else
{
var myObject = serializer.Deserialize<ApplicationLoggingModel>(reader);
return new ApplicationLoggingModel[] { myObject };
}
}
public override bool CanConvert(Type objectType)
{
return _types.Any(t => t == objectType);
}
}
При запуске:
services.AddMvc().AddJsonOptions(options => { options.SerializerSettings.Converters.Add(new ApplicationLoggingConverter()); });
... и данные JSON, которые я пытаюсь опубликовать:
"$type": "Project.Web.Areas.Admin.Models.ApplicationLoggingModel, Project.Web",
"Changes": [{
"$type": "Project.Generation.Common.Actions.EntityAction, Project.Services.Generation.Common",
"Action": 0,
"ItemName": "Entity",
"PropertyName": "Name",
"OldValue": "",
"NewValue": "newEntity",
"Scope": {
}
}]
Я довольно новичок в пользовательской десериализации для связывания моделей ASP Core 2, и документации по ней довольно мало (если я не гуглю / не исследую не то, что нужно), но кажется, что моя точка останова в "публичном объекте переопределения ReadJson" должна по крайней мере, ударил. Я изменил имена проектов в JSON по соображениям безопасности, и когда я устанавливаю TypeNameHandling. Авто работает, что я делаю не так? Дайте мне знать, если вам нужна дополнительная информация / код.