C# 在ASP.NET Web API 2中,如何跨JSON序列化保留对象引用?
我使用ASP.NET Web API 2和Entity Framework 6创建了一个REST API。我想序列化/反序列化对象并保留对其他对象的引用 我在ASP.NET中定义了一个标记模型类,它还有一个通过脚手架生成的普通控制器类:C# 在ASP.NET Web API 2中,如何跨JSON序列化保留对象引用?,c#,asp.net,python-2.7,asp.net-web-api2,C#,Asp.net,Python 2.7,Asp.net Web Api2,我使用ASP.NET Web API 2和Entity Framework 6创建了一个REST API。我想序列化/反序列化对象并保留对其他对象的引用 我在ASP.NET中定义了一个标记模型类,它还有一个通过脚手架生成的普通控制器类: // C# // Tag.cs public class Tag { public int ID { get; set; } public string Value { get; set; } public Tag Parent { ge
// C#
// Tag.cs
public class Tag
{
public int ID { get; set; }
public string Value { get; set; }
public Tag Parent { get; set; } // I know this can't be circular
}
...
// Context.cs
...
public DbSet<Tag> Tag { get; set; }
...
modelBuilder.Entity<Tag>().HasOptional(_ => _.Parent);
以下Python代码可以正确地在Tags表中创建标记条目:
newTag = Tag()
newTag.Value = "Parent"
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
r = requests.post("http://server/api/Tags", data=jsonpickle.encode(newTag), headers=headers)
# ID | Value | Parent_ID
# 1 | Parent | -
但是,当我将父标记指定给设置了正确ID的标记对象时,将创建2个新标记条目,而不是使用父ID引用:
# Get Tag
rg = requests.get("http://server/api/Tags/1")
parentTag = Tag(rg.text)
# Create new Tag with Parent reference
newTag = Tag()
newTag.Value = "Child"
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
r = requests.post("http://server/api/Tags", data=jsonpickle.encode(newTag), headers=headers)
# ID | Value | Parent_ID
# 1 | Parent | -
# 2 | Parent | - << This should net be created
# 3 | Child | 2 << This should be 1
#获取标签
rg=请求。获取(“http://server/api/Tags/1")
parentTag=Tag(rg.text)
#创建具有父引用的新标记
newTag=Tag()
newTag.Value=“Child”
headers={'Content-type':'application/json','Accept':'text/plain'}
r=请求。post(“http://server/api/Tags,data=jsonpickle.encode(newTag),headers=headers)
#ID |值|父项| ID
#1 |家长|-
#2 | Parent |-对ASP.NET的每个请求都应该获得一个新的DbContext。这意味着每次需要更新数据库时,都应该在SaveChanges
之前检索要更新的记录,然后对其进行更新
如果您只是反序列化一个对象并保存更改,它将(如您所见)在数据库中创建一个新记录
我建议您实现一个标准的三层机制,在API/Controller中使用视图模型,在业务层使用DTO,在数据库层使用实体(您当前拥有的实体)
简单的(但我建议是错误的)修复方法是在控制器中执行以下操作:
public void MyAPI(ApiViewModel vm)
{
var entity = _dbContext.Find(tag.Id);
entity.Value = vm.Value;
_dbContext.SaveChanges();
return Ok();
}
public void MyAPI(ApiViewModel vm)
{
var entity = _dbContext.Find(tag.Id);
entity.Value = vm.Value;
_dbContext.SaveChanges();
return Ok();
}