2017-10-16 147 views
0

我在阅读可用职位后发布此问题。我有一个ASP.NET web api控制器和以下方法。json字符串反序列化为自定义对象

[DataContract] 
public class CustomPerson 
{ 
    [DataMember] 
    public ulong LongId { get; set; } 
} 

[DataContract] 
public class Employee : CustomPerson 
{ 
    [DataMember] 
    public string Name { get; set; } 

    [DataMember] 
    public string Address { get; set; } 
} 
在控制器

public class CustomController : ApiController 
{ 
    [HttpPost] 
    [ActionName("AddEmployee")] 
    public bool AddEmployee(Employee empInfo) 
    { 
     bool bIsSuccess = false; 

     // Code loginc here 
     bIsSuccess = true; 

     return bIsSuccess; 
    } 

    [HttpPost] 
    [ActionName("AddEmployeeCustom")] 
    public async Task<bool> AddEmployeeCustom() 
    { 
     string rawRequest = await Request.Content.ReadAsStringAsync(); 
     bool bIsSuccess = false; 

     // Code loginc here 

     try 
     { 
      Employee emp = JsonConvert.DeserializeObject<Employee>(rawRequest); 
     } 
     catch (Exception ex) 
     { } 

     return bIsSuccess; 
    } 
} 

当我调用下面的请求经由肥皂AddEmployee

然后UI即用于LongId空值将被忽略

{ 
    "Name": "test1", 
    "Address": "Street 1", 
    "LongId": "" 
} 
无错误接收自定义对象

当我调用AddEmployeeCustom方法时,运行时会抛出异常:

Error converting value "" to type 'System.UInt64'. Path 'LongId', line 4, position 14. 

我读的一个选择是将传入的字符串转换为JObject,然后创建Employee类的对象,但我试图理解并模仿默认请求处理机制的行为,当传入的请求由控制器自动处理并反序列化员工对象

+2

改变你的'指定您的自定义转换器实例LongId'到'ulong'' – Jonesopolis

+1

'LongId'需要一个数字而不是一个空字符串 – user12345

+1

'long'值应该对应于''LongId':“”'? – Sinatr

回答

0

问题是您的JSON对您的模型无效。

在第一种方法AddEmployee中,称为模型绑定的过程发生。 MVC完成将post内容转换为对象的工作。它似乎容忍类型不匹配,并原谅你的空字符串。

在第二种情况下,您尝试自己做,并尝试在不验证输入数据的情况下运行反序列化。 Newtonsoft JSON不理解空字符串和崩溃。

如果您仍然需要接受无效JSON,你可能希望通过实现自定义转换器

public class NumberConverter : JsonConverter 
{ 
    public override bool CanWrite => false; 

    public override bool CanConvert(Type objectType) 
    { 
     return typeof(ulong) == objectType; 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var value = reader.Value.ToString(); 

     ulong result; 
     if (string.IsNullOrEmpty(value) || !ulong.TryParse(value, out result)) 
     { 
      return default(ulong); 
     } 

     return result; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

覆盖默认的反序列化过程,然后调用反序列化时

return JsonConvert.DeserializeObject<Employee>(doc.ToJson(), new NumberConverter()); 
相关问题