![](/img/trans.png)
[英]Correct way to edit and update complex viewmodel objects using asp.net-mvc2 and entity framework
[英]Is it possible to get complex Entity Framework objects from a REST api in .NET without creating ViewModel objects?
想象一组实体框架实体:
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
// GET api/product
[HttpGet]
public async Task<IActionResult> GetProduct([FromRoute] int id)
{
return Ok(await _context.Products
.Include(p => p.Markets)
.SingleAsync(m => m.ProductID == id));
}
如果实体没有附加市场,数据会毫无问题地返回,但只要我附加了一些链接项,我就会收到错误:
HTTP错误502.3 - 错误的网关
指定的CGI应用程序遇到错误,服务器终止了该进程。
我模糊地回忆起以前的应用程序,其中每个复杂的EF对象都有一个“仅基元”类型的对象来发送和接收客户端的这个对象,但我想知道是否有一种方法可以在没有中间对象的情况下进行通信?
例如:
public class ProductViewModel {
public int ProductID { get; set; }
public string Name { get; set; }
public List<MarketViewModel> Markets{ get; set; }
}
public class MarketViewModel {
public int ProductID { get; set; }
public Country Country { get; set; }
}
我担心的是从客户端来回翻译每个复杂对象的编码开销(我承认,我不确定这是不是一件坏事,也许它必须要完成)。
由于脚手架API似乎直接接收和返回实体,我发现自己想知道是否有办法直接处理对象的复杂部分
编辑#1:
Per Noel的评论如下,如果我更改导致错误的代码
[HttpGet("{id}", Name = "GetProduct")]
public async Task<IActionResult> GetProduct([FromRoute] int id)
{
Product product = await _context.Products
.Include(t => t.Markets)
.SingleAsync(m => m.ProductID == id);
throw new System.Exception("error sample");
return Ok(product);
}
正确抛出堆栈跟踪。 如果我删除了异常,则会出现500网关错误。 我同意它看起来可能是一个序列化错误,但很难说。
编辑2 - 根据奥列格的评论如下:
坏网关的解决方案是首先在project.json
文件的依赖项中显式更新更新版本的NewtonSoft.Json
:
"dependencies": {
"Newtonsoft.Json": "8.0.1-beta3",
接下来,您必须更改Startup.cs
文件
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddJsonOptions(options => {
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
使用这两个设置后,不再出现坏网关,并且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
dynamic json = new JsonObject();
json.Message = "Hello";
json.Value = 123;
return new HttpResponseMessage<JsonObject>(json);
// ExpandoObject
dynamic expando = new ExpandoObject();
expando.message = "Hello";
expando.message2 = "World";
return expando;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.