【发布时间】:2017-04-14 14:19:19
【问题描述】:
Json.Net not 将它接收到的对象反序列化为我的 Control 类的正确派生类。 (请参阅以下问题说明。另外请注意,我认为这是解释问题所需的最少代码量。提前感谢您查看此问题。)
我正在尝试将以下类序列化/反序列化为 JSON。
public class Page {
public Guid Id { get; set; }
public Guid CustomerId { get; set; }
public IList<Control> Controls { get; set; }
}
这里是控制类:
public class Control : ControlBase
{
public override Enums.CsControlType CsControlType { get { return Enums.CsControlType.Base; } }
}
这里是 ControlBase 抽象类:
public abstract class ControlBase
{
public Guid Id { get; set; }
public virtual Enums.CsControlType CsControlType { get; }
public Enums.ControlType Type { get; set; }
public string PropertyName { get; set; }
public IList<int> Width { get; set; }
public string FriendlyName { get; set; }
public string Description { get; set; }
}
这是从 Control 派生的 OptionsControl:
public class OptionsControl : Control
{
public override Enums.CsControlType CsControlType { get { return Enums.CsControlType.OptionsControl; } }
public IDictionary<string, string> Options;
}
当 OptionsControl 被序列化时,JSON 如下所示。请注意,Json.Net 添加了 $type 属性,以便(假设)它可以将控件反序列化回 OptionsControl。
{
"options":{
"TN":"TN"
},
"csControlType":4,
"id":"00000000-0000-0000-0000-000000000000",
"type":4,
"propertyName":"addresses[0].state",
"width":[
2,
2,
6
],
"friendlyName":"State",
"description":null,
"$type":"MyApp.Infrastructure.Core.Models.UI.Controls.OptionsControl, MyApp.Infrastructure.Core"
}
但是,当我尝试反序列化页面(包含基本控件和选项控件)时,所有控件都被反序列化为基本控件,并且 options 属性(包括上面的状态列表)被忽略。
这就是我尝试反序列化(和更新)我通过 WebAPI 服务收到的 Page 对象的方式:
[HttpPut]
[ActionName("UpdatePage")]
public async Task<CommandResult> UpdatePageAsync([FromBody]Object page)
{
try
{
// Deserialize the page into the correct object
// When I Debug.WriteLine the page.ToString(), the page still has the $type property at this point (before it is deserialized).
var dsPage = return JsonConvert.DeserializeObject<Page>(page.ToString(), new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
});
// The dsPage passed in here does not have any OptionsControls.
// At this point, they have all been deserialized into the base Control, unfortunately.
return await _uiCommandFacade.UpdatePageAsync(dsPage, msg);
}
catch (Exception ex)
{
return new CommandResult()
{
ErrorType = ErrorType.ControllerError,
DeveloperMessage = $"Unable to update page",
Exception = ex
};
}
}
如您所见,我正在使用 TypeNameHandling.All(如文档中所述,并在 SO 中多次提及)进行反序列化(就像我在序列化期间一样,这就是在JSON)。但是,当我反序列化 Page 对象时,Page 对象中的任何 OptionsControls 都会被反序列化为常规基础 Controls,因此 Options 属性将被忽略(因此我的状态列表不会更新/丢弃) .
如何让 Json.Net 正确反序列化我的控件及其派生类?
【问题讨论】:
标签: c# json serialization asp.net-web-api json.net