我创建了一个控制器,用于将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对象。
答案 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;
}