ViewModel 객체를 만들지 않고 .NET의 REST API에서 복잡한 Entity Framework 객체를 가져올 수 있습니까?

asp.net-core asp.net-mvc c# entity-framework entity-framework-core

문제

Entity Framework 엔터티 집합을 상상해보십시오.

public class Country {
    public string CountryCode { get; set; }
    public string Name { get; set; }
    public string Flag { get; set; }
}

public class Market {
    public string CountryCode { get; set; }
    public virtual Country Country { get; set; }
    public int ProductID { get; set; }      
    public virtual Product Product { get; set; }
}

public class Product {
    public int ProductID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Market> Markets{ get; set; }
}

상상해도 닷넷 5 api GET

public class Country {
    public string CountryCode { get; set; }
    public string Name { get; set; }
    public string Flag { get; set; }
}

public class Market {
    public string CountryCode { get; set; }
    public virtual Country Country { get; set; }
    public int ProductID { get; set; }      
    public virtual Product Product { get; set; }
}

public class Product {
    public int ProductID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Market> Markets{ get; set; }
}

엔티티에 연결된 시장이 없으면 데이터가 문제없이 반환되지만 링크 된 항목이 몇 개 첨부 되 자마자 오류가 발생합니다.

HTTP 오류 502.3 - 잘못된 게이트웨이
지정한 CGI 응용 프로그램에 오류가 발생하여 서버가 프로세스를 종료했습니다.

나는 모든 복합 EF 객체가 "primitives only"타입 객체를 가지고 클라이언트와주고받는이 객체를 모호하게 기억하지만, 중간 객체없이 통신 할 수있는 방법이 있는지 궁금합니다.

예 :

public class Country {
    public string CountryCode { get; set; }
    public string Name { get; set; }
    public string Flag { get; set; }
}

public class Market {
    public string CountryCode { get; set; }
    public virtual Country Country { get; set; }
    public int ProductID { get; set; }      
    public virtual Product Product { get; set; }
}

public class Product {
    public int ProductID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Market> Markets{ get; set; }
}

내 관심사는 모든 복잡한 객체를 클라이언트에서 앞뒤로 번역하는 코딩 오버 헤드입니다. (필자도 틀림없이, 어쨌든 끝내야 할지도 모릅니다.)

스캐 폴딩 된 API는 엔티티를 직접 가져 와서 반환하는 것처럼 보이기 때문에 객체의 복잡한 부분을 직접 처리하는 방법이 있는지 궁금해합니다.

# 1 편집 :

아래 Noel의 의견에 따르면 오류의 원인이되는 코드를

public class Country {
    public string CountryCode { get; set; }
    public string Name { get; set; }
    public string Flag { get; set; }
}

public class Market {
    public string CountryCode { get; set; }
    public virtual Country Country { get; set; }
    public int ProductID { get; set; }      
    public virtual Product Product { get; set; }
}

public class Product {
    public int ProductID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Market> Markets{ get; set; }
}

스택 추적이 올바르게 throw됩니다. 예외를 제거하면 500 게이트웨이 오류가 나타납니다. 아마 직렬화 오류 일 것 같아서 동의하지만, 말하기는 어렵습니다.

편집 2 - Oleg의 의견에 따라 아래 :

나쁜 게이트웨이에 대한 해결책은 먼저 project.json 파일의 종속성에서 NewtonSoft.Json 최신 버전을 명시 적으로 업데이트하는 것입니다.

public class Country {
    public string CountryCode { get; set; }
    public string Name { get; set; }
    public string Flag { get; set; }
}

public class Market {
    public string CountryCode { get; set; }
    public virtual Country Country { get; set; }
    public int ProductID { get; set; }      
    public virtual Product Product { get; set; }
}

public class Product {
    public int ProductID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Market> Markets{ get; set; }
}

다음 Startup.cs 파일을 변경해야합니다.

public class Country {
    public string CountryCode { get; set; }
    public string Name { get; set; }
    public string Flag { get; set; }
}

public class Market {
    public string CountryCode { get; set; }
    public virtual Country Country { get; set; }
    public int ProductID { get; set; }      
    public virtual Product Product { get; set; }
}

public class Product {
    public int ProductID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Market> Markets{ get; set; }
}

이 두 설정을 적용하면 잘못된 게이트웨이가 더 이상 나타나지 않고 API 호출이 복잡한 객체를 예상대로 성공적으로 반환합니다.

수락 된 답변

SingleAsync 호출에서 await SingleAsync . 사용하려고 시도하십시오.

[HttpGet]
public async Task<IActionResult> GetProduct([FromRoute] int id)
{
    return Ok(await _context.Products
        .Include(p => p.Markets)
        .SingleAsync(m => m.ProductID == id));
}

업데이트 : 문제를 발견 했습니다 . 검토 할 것을 권장합니다 package.lock.json 을 검사하여 종속성의 자동 해결로 어떤 버전이로드되는지 확인할 수 있습니다. 그런 다음 프로젝트의 종속성에 최신 버전 8.0.1- Newtonsoft.Json명시 적으로 추가하는 것이 좋습니다. 또한 Newtonsoft.Json.ReferenceLoopHandling.Ignore 의 설정을 SerializerSettings.ReferenceLoopHandling 의 구성에 추가해야합니다. 자세한 내용 은 문제 를 참조하십시오.


인기 답변

익명 객체를 반환하거나 ExpandoObject / JsonObject를 사용할 수 있습니다.

public HttpResponseMessage Get()
{
    return this.Request.CreateResponse(
        HttpStatusCode.OK,
        new { Message = "Hello", Value = 123 });
}

// JsonObject

public HttpResponseMessage Get()
{
    return this.Request.CreateResponse(
        HttpStatusCode.OK,
        new { Message = "Hello", Value = 123 });
}

// ExpandoObject

public HttpResponseMessage Get()
{
    return this.Request.CreateResponse(
        HttpStatusCode.OK,
        new { Message = "Hello", Value = 123 });
}



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.