JsonConvert.DeserializeObject C#对象类型没有默认构造函数

时间:2015-03-11 20:51:32

标签: c# json asp.net-web-api json.net

我在使用JsonConvert反序列化自己的自定义类时遇到异常。

这是我用来从Web Api返回任何数据和错误的自定义类。注意数据类型为object。

public class ResponseModel
{
    public bool IsSuccess { get; private set; }
    public string Message { get; private set; }
    public object Data { get; private set; }

    public ResponseModel(bool isSuccess, string message, object data)
    {
        this.IsSuccess = isSuccess;
        this.Message = message;
        this.Data = data;
    }
}

这是我的Web Api控制器方法。

public class CatalogApiController : ApiController
    {
        public ResponseModel GetAllCatalogs(string search, int pageIndex, int pageSize)
        {
            try
            {
                using(var unitOfWork = new UnitOfWork<XXXX>())
                {
                    using (var catalogManager = new CatalogManager(unitOfWork))
                    {
                        var totalCount = 0;
                        var allProducts = catalogManager.GetAllSpecies(search, pageIndex, pageSize, out totalCount);
                        var paginatedList = new PaginatedList<Product>(allProducts, pageIndex, pageSize, totalCount);
                        return new ResponseModel(true, "", paginatedList);
                    }
                }
            }
            catch(Exception ex)
            {
                //TODO Handle Exception
                return new ResponseModel(false, "", null);
            }
        }
}

PaginatedList类没有默认构造函数。

public class PaginatedList<T> : List<T>
{
    public int PageIndex { get; private set; }
    public int PageSize { get; private set; }
    public int TotalCount { get; private set; }

    public PaginatedList(IEnumerable<T> source, int pageIndex, int pageSize, int totalCount)
    {
        if (source == null)
        {
            throw new ArgumentNullException("Source cannot be null.");
        }

        AddRange(source);

        PageIndex = pageIndex;
        PageSize = pageSize;
        TotalCount = totalCount;
    }
}

这就是我将Json结果转换回ResponseModel的方式。

            var allProductJson = //somehow get json result
            var allProduct = JsonConvert.DeserializeObject<ResponseModel>(allProductJson);
            if(allProduct.IsSuccess)
            {
                var productData = JsonConvert.DeserializeObject<PaginatedList<Product>>(allProduct.Data.ToString());//I am getting exception on this line.

            }

只有在使用PaginatedList<Product>时才会出现异常。如果我从Web Api返回IList<Product>,我就不会例外。

异常消息:

  

无法找到用于类型的构造函数   XXXX.Business.Domain.PaginatedList`1 [XXXX.Business.Domain.Product]。   路径&#39;&#39;,第1行,第1位。

内部例外:

  

JsonSerializationException:无法找到要用于的构造函数   类型   XXXX.Business.Domain.PaginatedList 1[XXXX.Business.Domain.Product]. Path '', line 1, position 1.]
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewList(JsonReader reader, JsonArrayContract contract, Boolean& createdFromNonDefaultCreator) +670
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id) +198
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) +238
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) +749
Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) +354
Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType) +47
Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings) +199
Newtonsoft.Json.JsonConvert.DeserializeObject(String value, JsonSerializerSettings settings) +118
Newtonsoft.Json.JsonConvert.DeserializeObject(String value) +81
XXXX.Web.Controllers.HomeController.HomePage(String search, Nullable
1   在XXXX.Web \ Controllers \ HomeController.cs:50中   lambda_method(Closure,ControllerBase,Object [])+225

奖金问题:

  1. 如何使ResponseModel数据对象强类型化。我想通过将其作为ResponseeModel<T>使用它作为通用,但我必须做出太多改变的地方。是否有任何方法可以使用JsonConvert获取强类型数据表单对象而无需再次解析它(我在之前的代码中执行此操作)。
  2. 提前谢谢。

1 个答案:

答案 0 :(得分:0)

由于错误表明您需要默认构造函数,因此我建议您添加默认构造函数。反序列化器需要创建一个以标准化方式重新水化的类的实例,因此总是需要一个默认的构造函数。创建实例后,它将尝试通过设置公共属性来设置其状态。您已经定义了“私有集”属性,因此我无法确定它是否会设置它们。

然后你遇到的问题是你试图序列化/反序列化从List派生的类,我不相信List知道如何这样做。因此,您需要将自定义序列化添加到PaginatedList类。