json字符串反序列化到自定义对象

时间:2017-10-16 14:49:22

标签: c# json

我在阅读可用的帖子后发布了这个问题。我有一个带有以下方法的ASP.NET web api控制器。

[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;
    }
}

当我通过soap ui向AddEmployee调用以下请求时,收到的自定义对象没有错误,但忽略了LongId的空值

{
    "Name": "test1",
    "Address": "Street 1",
    "LongId": ""
}

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

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

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

1 个答案:

答案 0 :(得分:0)

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

在第一个方法AddEmployee中,发生了名为Model Binding的过程。 MVC负责将帖子内容转换为对象。它似乎容忍类型不匹配并原谅你空字符串。

在第二种情况下,您尝试自己完成,并尝试在不验证输入数据的情况下运行反序列化。 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();
    }
}

然后在调用deserialize

时指定自定义转换器实例
return JsonConvert.DeserializeObject<Employee>(doc.ToJson(), new NumberConverter());
相关问题