WebAPI响应导致"System.OutOfMemoryException". [英] WebAPI response causes "System.OutOfMemoryException"

查看:339
本文介绍了WebAPI响应导致"System.OutOfMemoryException".的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发了一个WebAPI服务,该服务在响应中返回一组复杂的自定义对象. 他们的某些领域具有多对多关系.例如:

I developed a WebAPI service which returns in its response an array of complex custom objects. Some of their fields have many-to-many relations. For example:

[Table("OEReferences", Schema = "public")]
public class OEReference
{

    [NotMapped]
    public IList<IAReference> IAReferences{ get; set; }

}

[Table("IAReferences", Schema = "public")]
public class IAReference
{

    [NotMapped]
    public IList<OEReference> OEReferences{ get; set; }

}

每个OEReference对象都有一个IAReferences列表,与此同时,每个IAReference对象都有一个OEReference列表(包括第一个)及其相应的IAReferences列表,等等.并且永远不会停止.

Each OEReference object has a list of IAReferences, which at the same time each IAReference object has a list of OEReference (including the first one) with its corresponding list of IAReferences, etc. And it never stops.

有时我遇到内存不足的异常.这是原因吗?我该如何预防?

Sometimes I'm getting an out of memory exception. Is this the reason? How can I prevent it?

只有约50个OEReference包含了每个IAReferences,这才打破了局面.其余字段非常简单. 我在.Net 4.7.1中使用HttpClient类.

It's breaking with just ~50 OEReference containing each of them a couple of IAReferences. The rest of the fields are quite simple. I use HttpClient class in .Net 4.7.1.

推荐答案

似乎您是直接从Web API(通过其内置的JSON序列化器)返回Entity Framework对象.一般规则是永远不要这样做,因为JSON序列化程序将尝试序列化它可以找到的所有内容.但是对于具有诸如您这样的关系的EF对象,它将不知道从何处停止,从而导致引用循环错误甚至内存不足错误.

It looks like you are returning Entity Framework objects directly from the Web API (through its built-in JSON Serializer). The general rule is to NEVER do that, because the JSON Serializer will try to serialize everything it can find. But with EF Objects that have relations such as yours, it won't know where to stop, leading to Reference Loop errors or even Out of Memory errors.

相反,您需要从EF对象中准确获取您需要的东西,或更确切地说,是API调用者需要的东西.

Instead you need to take exactly from the EF objects what you need, or more precisely: what your API caller needs.

解决方案是创建对象/视图模型,以复制调用方需要的EF对象的部分,填充EF对象中的部分,然后将其返回.

The solution is to create Objects/ViewModels that copy the parts of the EF Objects that the caller needs, fill those from the EF Objects, and then return them.

一种快捷方法是使用匿名对象,例如:

A quick-and-dirty way is to use anonymous objects, for example:

// Instead of "return EF_Item":
return new
{
    Item = new
    {
        Id = EF_Item.Id,
        Description = EF_Item.Description,
        Things = MapThings(EF_Item.Things) // helper function that you need to provide
    }
};

一个好的经验法则是只将EF对象中的简单属性(数字,布尔值,字符串,日期时间)分配给ViewModel项.一旦遇到另一个EF对象(或EF对象集合)的EF对象属性,则需要将这些对象也转换为未链接到EF的简单"对象.

A good rule-of-thumb is to only assign simple properties (number, bool, string, datetime) from the EF Objects to the ViewModel items. As soon as you encounter an EF Object property that is yet another EF Object (or a collection of EF Objects), then you need to translate those as well to 'simple' objects that are not linked to EF.

一种更加结构化的方法是使用ViewModel类,并且可以使用诸如AutoMapper之类的工具(一旦配置)将其结构化,从而使结构更加结构化.

A more structured approach is by using ViewModel classes, and you can make that even more structured by using a tool such as AutoMapper that (once configured) will do the mapping for you whenever and wherever you need it.

这篇关于WebAPI响应导致"System.OutOfMemoryException".的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆