从.Net核心API返回复杂对象 [英] Return complex object from .Net core API

查看:45
本文介绍了从.Net核心API返回复杂对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将.Net核心后端与Entity Framework一起使用,以将对象检索到我的angular2前端.只要我从后端返回平面对象,我就不会有问题.但是,当我使用Linq Include 时,会出现 net :: ERR_CONNECTION_RESET 错误.该错误似乎是在调用从后端返回后立即发生的,但是它从未进入结果处理程序.

I'm using a .Net core backend with Entity Framework to retrieve objects to my angular2 frontend. As long as I return flat objects from the backend I have not problems. But when I use an Linq Include I get an net::ERR_CONNECTION_RESET error. The error seems to occur as soon as the call returns from backend, but it never enters the result handler.

如何返回对象内部包含列表的复杂对象?

How can I return a complex object with lists inside the objects?

DocumentsController.cs:

[Produces("application/json")]
[Route("api/[controller]")]
public class DocumentsController : Controller
{
    private readonly DatabaseContext _context;

    public DocumentsController(DatabaseContext context)
    {
        _context = context;
    }

    // GET: api/Documents
    [HttpGet]
    public IEnumerable<Document> GetDocuments()
    {
        var documents = _context.Documents
            .Include(x => x.Pages);

        return documents;
    }
}

Document.cs:

public class Document : IEntity
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string AlternativeTitle { get; set; }
    public ICollection<Page> Pages { get; set; }
}

Page.cs:

public class Page : IEntity
{
    public Document Document { get; set; }
    public int DocumentId { get; set; }
    public int Id { get; set; }
    public string OriginalText { get; set; }
    public int Sorting { get; set; }
}

documents.components.ts:

import { Component, Inject } from '@angular/core';
import { Http } from '@angular/http';

@Component({
    selector: 'documents',
    templateUrl: './documents.component.html'
})
export class DocumentsComponent {
    public documents: Document[];

    constructor(http: Http, @Inject('BASE_URL') baseUrl: string) {
        http.get(baseUrl + 'api/Documents').subscribe(result => {
            this.documents = result.json() as Document[];
        }, error => console.error(error));
    }
}

interface Document {
    title: string;
    alternativeTitle: string;
    pageCount: number;
    pages: Array<Page>;
}
interface Page {
    originalText: string;
    sorting: number;
}

推荐答案

连接重置错误是由于您的Action方法抛出未处理的异常,将500返回给客户端.发生这种情况的原因是,当序列化程序启动时,无限循环 Document => Page => Document .
解决此问题而不破坏关系的一种简单方法(即使使用DTO时也可能需要它们)是更改默认的序列化过程:

The connection reset error is due to your Action method throwing an unhandled exception, returning a 500 to the client. This happens because of the infinite loop Document => Page => Document when the serializer kicks in.
An easy way to solve this problem without breaking the relationship (you might need them even when using DTOs) is to change the default serialization process:

public IActionResult GetDocuments()
{
    var documents = ...;

    var options = new JsonSerializerSettings 
    {
        ReferenceLoopHandling = ReferenceLoopHandling.Ignore
    };

    return Json(documents, options);
}

话虽如此,您应该始终返回 IActionResult async Task< IActionResult> 而不是直接返回类型(例如 IEnumerable< Document> >).
另外,如果您发现自己必须连续使用上述代码,则可能需要在应用程序级别的启动"中更改默认选项

With that said, you should always return either IActionResult or async Task<IActionResult> instead of the type directly (like IEnumerable<Document>).
Also, if you find yourself having to use the above code continuously, you might want to change the default options at the application level in Startup

这篇关于从.Net核心API返回复杂对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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