C# JsonConverter和EntityData
我正在使用Azure和数据库优先EF方法。Azure web服务中我的一个实体定义如下:C# JsonConverter和EntityData,c#,json,entity-framework,azure,json.net,C#,Json,Entity Framework,Azure,Json.net,我正在使用Azure和数据库优先EF方法。Azure web服务中我的一个实体定义如下: public class Company : EntityData { public string CompanyName { get; set; } } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { // Int32 implements t
public class Company : EntityData
{
public string CompanyName { get; set; }
}
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
// Int32 implements the IConvertible interface which has a ToString() overload
// that takes an IFormatProvider specification. Pass the invariant format to guarantee
// identical serialization in all cultures.
var convertible = (IConvertible)value;
serializer.Serialize(writer, convertible.ToString(NumberFormatInfo.InvariantInfo));
}
它从EntityData继承Id属性。Id属性的类型为字符串
在客户中,我拥有以下实体:
class Company
{
[JsonConverter(typeof(IntConverter))]
public int Id { get; set; }
public string CompanyName { get; set; }
}
正如您在上面看到的,我需要将Id从string转换为int
我创建了以下JSON转换器:
class IntConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
if (reader.Value == null)
return 0;
int num;
if (Int32.TryParse(reader.Value.ToString(), out num))
return num;
else
return 0;
}
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
serializer.Serialize(writer, value.ToString());
}
}
public class RootObject
{
readonly ObservableCollection<SomeClass> _collection = new ObservableCollection<SomeClass>();
[JsonConverter(typeof(ObservableCollectionConverter<SomeClass>>)]
public ObservableCollection<SomeClass> { get { return _collection; } }
}
它工作正常,但因为这是我的第一个JSON转换器,我不确定我是否正确创建了它。我看到了转换器的示例,它们使用的是existingValue而不是reader.Value。在我的例子中,existingValue总是0
上述实现正确吗?您的代码基本正确
existingValue
是以前存在于父c#模型中的值。通过将其传递到转换器中,Json.NET允许转换器在现有模型或只读集合出现时工作。例如,如果您具有带有转换器的预分配只读属性:
class IntConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
if (reader.Value == null)
return 0;
int num;
if (Int32.TryParse(reader.Value.ToString(), out num))
return num;
else
return 0;
}
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
serializer.Serialize(writer, value.ToString());
}
}
public class RootObject
{
readonly ObservableCollection<SomeClass> _collection = new ObservableCollection<SomeClass>();
[JsonConverter(typeof(ObservableCollectionConverter<SomeClass>>)]
public ObservableCollection<SomeClass> { get { return _collection; } }
}
ReadJson()
中进行类似的修复:
ReadJson()
无法抵御意外数据。例如,如果传入的JSON实际上有一个数组或对象值(例如{“unexpectedProperty”:“unexpectedValue”}
),那么JsonReader
将不会正确地前进到输入的末尾。您应该检查并适当处理不良数据,例如:
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.Null:
return null;
case JsonToken.Integer:
// Input was already an integer. Return it
return (int)JToken.Load(reader);
case JsonToken.String:
{
int num;
if (Int32.TryParse(reader.Value.ToString(), NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out num))
return num;
else
return 0;
}
default:
throw new JsonSerializationException(string.Format("Unexpected token {0} at path {1}", reader.TokenType, reader.Path));
}
或者,如果您希望在不引发异常的情况下使用和丢弃意外数据(我不建议这样做),您可以使用:
CanConvert
返回true
将是一个问题。相反,我建议使用NotImplementedException
或正确实现该方法:
public override bool CanConvert(Type objectType)
{
return objectType == typeof(int) || objectType == typeof(int?);
}
class IntConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(int) || objectType == typeof(int?);
}
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.Null:
return null;
case JsonToken.Integer:
// Input was already an integer. Return it
return (int)JToken.Load(reader);
case JsonToken.String:
{
int num;
if (Int32.TryParse(reader.Value.ToString(), NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out num))
return num;
else
return 0;
}
default:
throw new JsonSerializationException(string.Format("Unexpected token {0} at path {1}", reader.TokenType, reader.Path));
}
}
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
// Int32 implements the IConvertible interface which has a ToString() overload
// that takes an IFormatProvider specification. Pass the invariant format to guarantee
// identical serialization in all cultures.
var convertible = (IConvertible)value;
serializer.Serialize(writer, convertible.ToString(NumberFormatInfo.InvariantInfo));
}
}
显示最终转换器的严格版本和宽容版本的示例。现有值是现有值,并且由于
Company.Id
从未直接分配给属性或从ctor分配,因此它将始终为0。我投票将此问题作为离题题结束,因为它是关于检查工作代码的。至少在结束我的问题之前,我从DBC得到了很好的见解,这是很好的:)我没有意识到它离题了。再次感谢DBC的帮助。@ata6502-问题不会被删除,它会被移动到。这是一个写得很好的问题,但对那个网站来说可能更好。