如何在没有子代的情况下在C#中序列化JSON

时间:2018-04-07 14:03:18

标签: c# json asp.net-mvc json.net

我创建了一个控制器,用于将JSON返回给移动应用程序。鉴于此行动:

public JsonResult GetFirm(int id)
{
    Firm firm = new Firm();
    firm = dbContext.Firms.FirstOrDefault(s => s.id == id);
    string firmString = JsonConvert.SerializeObject(firm);
    return Json(firmString, JsonRequestBehavior.AllowGet);
}

这个方法(上面的方法)抛出自引用循环错误,我写道:

Firm firm = new Firm();
firm = dbContext.Firms.FirstOrDefault(s => s.id == id);
string firmString = JsonConvert.SerializeObject(firm, Formatting.None,
    new JsonSerializerSettings()
    {
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore
    });
return Json(firmString, JsonRequestBehavior.AllowGet);

但是这个方法发送带有所有子和集合的对象,json包括" \"在所有属性之前。

我想发送没有子项或集合的json对象。

2 个答案:

答案 0 :(得分:3)

分析和问题

您的问题显然在您的模型中的某个地方,您有一个循环引用。我非常有信心,因为您正在尝试直接反序列化数据库模型(一种猜测的EF模型)。不建议这样做。

数据库模型通常包含对其他类的引用,这些类本身由于表示数据库结构而引用回第一个类。所以你可能有类似的东西:

public class ParentItemDataModel
{
    [Key]
    public Guid Id { get; set; }

    public string SomeInfo { get; set; }

    public List<ChildItemDataModel> Children { get; set; }
}

public class ChildItemDataModel
{
    public ParentItemDataModel Parent { get; set; }

    public string SomeInfo { get; set; }
}

正如您所看到的,如果反序列化,则需要一个明确的参考循环。

建议

通过创建一个仅包含所需信息的新的简单类,将返回到客户端的API模型与底层数据库模型分开:

public class ParentItemApiModel
{
    public Guid Id { get; set; }

    public string SomeInfo { get; set; }
}

然后你可以用老式的方式将这些信息传递到模型中:

var parentApiModel = new ParentItemApiModel
{
    Id = dataModel.Id,
    SomeInfo = dataModel.SomeInfo
};

或者您可以在数据模型中使用扩展方法(因此通常较低的核心Api模型没有引用备份到数据库层):

public static class DataModelExtensions
{
    public static ParentItemApiModel ToApiModel(this ParentItemDataModel dataModel)
    {
        return new ParentItemApiModel
        {
            Id = dataModel.Id,
            SomeInfo = dataModel.SomeInfo
        };
    }
}

现在你可以这样做了:

var apiModel = dataModel.ToApiModel();

或者在你的例子中,那就是:

string firmString = JsonConvert.SerializeObject(firm.ToApiModel());

或者你喜欢的任何其他方式。

直接修复

如果您不想按照建议进行修复,最快捷,最简单的方法是使用[JsonIgnore]标记您在JSON模型中不需要的数据模型Firm属性

答案 1 :(得分:-2)

尝试修改字符串而不是JsonResult

public string GetFirm(int id)
{

    Firm firm = new Firm();
    firm = dbContext.Firms.FirstOrDefault(s => s.id == id);
    string firmString = JsonConvert.SerializeObject(firm, Formatting.None,
                new JsonSerializerSettings()
                {
                    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
                });
    return firmString;
}