是否可以從.NET中的REST API獲取複雜的Entity Framework對象而無需創建ViewModel對象?

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

想像一組實體框架實體:

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; }
}

想像一下DOTNET 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對像都有一個“僅基元”類型的對象來發送和接收客戶端的這個對象,但我想知道是否有一種方法可以在沒有中間對象的情況下進行通信?

例如:

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:

Per 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; }
}

正確拋出堆棧跟踪。如果我刪除了異常,則會出現500網關錯誤。我同意它看起來可能是序列化錯誤,但很難說。

編輯2 - 根據奧列格的評論如下:

壞網關的解決方案是首先在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調用成功返回複雜對象。

一般承認的答案

在我看來,你只是錯過了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-beta3中的Newtonsoft.Json 顯式添加到項目的依賴項中。另外,您應該在SerializerSettings.ReferenceLoopHandling的配置中將設置添加到Newtonsoft.Json.ReferenceLoopHandling.Ignore 。有關更多詳細信息,請參閱問題


熱門答案

您可以返回匿名對像或使用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合法嗎? 是的,了解原因