我有这样的课程
class Holder {
public int ObjType { get; set; }
public List<Base> Objects { get; set; }
}
abstract class Base {
// ... doesn't matter
}
class DerivedType1 : Base {
// ... doesn't matter
}
class DerivedType2 : Base {
// ... doesn't matter
}
Run Code Online (Sandbox Code Playgroud)
使用WebAPI我想要接收对象Holder并正确反序列化它.基于ObjType值,我需要Objects将要反序列化的属性作为List<DerivedType1>(ObjType == 1)或List<DerivedType2>(ObjType == 2).
目前我搜索了SO和互联网以获得最佳方法,但我找到的最好的是这个答案/sf/answers/562189841/.这个解决方案的问题是,它松散了父对象的上下文,所以我找不到它的值ObjType.OK,我可以创建自定义解决它JsonConverter用于Holder和remebering的ObjType价值,但我还是很affraid这行
serializer.Populate(jObject.CreateReader(), target); …Run Code Online (Sandbox Code Playgroud) 我有一个带有复合键的模型 - 行是关键:
public class Item
{
[Key, Column(Order = 0)]
public int UserId { get; set; }
[Key, Column(Order = 1)]
public DateTime? Date { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
运行下面的代码会抛出一个异常DbEntityValidationException消息The Date field is required.::
var it = new Item { Date = null, UserId = 2 };
m_Entities.Items.Add(it);
m_Entities.SaveChanges(); // throws exception
Run Code Online (Sandbox Code Playgroud)
(m_Entities通常是子DbContext项,定义为项目DbSet<Item>)Date如果可以null(声明为DateTime?),为什么需要?以及如何允许null成为有效值Date?
从这个答案我有类JsonCreationConverter<T>和具体类型的一些实现.但是这个抽象类错过了WriteJson方法的实现.
通过互联网我找到了代码:
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
//use the default serialization - it works fine
serializer.Serialize(writer, value);
}
Run Code Online (Sandbox Code Playgroud)
但是这个代码最终会出现StackOverflowException,因为它一直在调用自己(当然).其他解决方案用于具体对象实现,逐个序列化所有值.我真的想避免它,只想使用默认序列化,这对我来说没问题.只是为了避免调用我的JsonConverter进行序列化.我只需要反序列化.可能吗?怎么样?
为什么这不可能?
abstract class A
{
public abstract T f<T>();
}
class B<T> : A
{
public override T f()
{
return default (T);
}
}
Run Code Online (Sandbox Code Playgroud)
错误:
does not implement inherited abstract member 'A.f<T>()'
no suitable method found to override
Run Code Online (Sandbox Code Playgroud)
我知道签名必须是相同的,但从我的角度来看,我认为没有理由这是不允许的.另外我知道另一个解决方案是制作A通用的,而不是它的方法,但由于某些原因它不适合我.
考虑以下非常简单的代码。
var ex_to_serialize = new Exception("something wrong", new NullReferenceException("set to null"));
var serialized_ex = JsonConvert.SerializeObject(ex_to_serialize);
var deserialized_ex = JsonConvert.DeserializeObject<Exception>(serialized_ex);
Console.WriteLine($"Type of inner exception: {deserialized_ex.InnerException.GetType().Name}");
Run Code Online (Sandbox Code Playgroud)
瞧……内部异常类型Exception不是NullReferenceException. 所以我搜索了 SO 并找到了很多JsonConverter用于反序列化的自定义示例(因为序列化的 JSON 包含ClassName可用于创建特定类型的属性)。所以我写了一个(只是ReadJson为了简单起见,其余照常)。
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var json_object = Newtonsoft.Json.Linq.JObject.Load(reader);
var target_type_name = json_object.Value<string>("ClassName");
var target_type = Type.GetType(target_type_name);
var target = Activator.CreateInstance(target_type);
serializer.Populate(json_object.CreateReader(), target);
return target;
}
Run Code Online (Sandbox Code Playgroud)
并在调用 …
我对本文中的多态绑定示例进行了一些更改。
[Required]属性。CPUIndexScreenSizeLaptopSmartPhone到目前为止还可以。
现在添加新类:
public class DeviceWrapper
{
public Device Device { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
并修改AddDevice.cshtml.cs文件:
...
[BindProperty]
public DeviceWrapper Device { get; set; } // model type changed here
public IActionResult OnPost()
{
if (!ModelState.IsValid)
{
return Page();
}
switch (Device.Device) // added Device. prefix to respect new model structure
{
case Laptop laptop:
Message = $"You added a Laptop with …Run Code Online (Sandbox Code Playgroud)