ASP.NET WebApi JSON响应和具有外键的实体

5 c# serialization json foreign-keys asp.net-web-api2

我正在开发WebApi项目,我的域名中有2个实体:
Street

public class Street
{
  public int ID { get; set; }
  public string Name { get; set; }
  public int StreetTypeID { get; set; }
  public virtual StreetType StreetType { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

和街道类型:

public class StreetType
{
  public int ID { get; set; }
  public string Name { get; set; }
  public virtual ICollection<Street> Streets { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我使用FluenApi来映射这些实体:

public class StreetTypeMap : EntityTypeConfiguration<StreetType>
{
  public StreetTypeMap()
  {
     HasKey(t => t.ID);
     Property(t => t.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
     Property(t => t.Name).IsRequired().HasMaxLength(50);
     HasMany(a => a.Streets).WithRequired(p => p.StreetType).HasForeignKey(p => p.StreetTypeID);
     ToTable("StreetType");
   }
 }
Run Code Online (Sandbox Code Playgroud)

和街道实体类似.
现在我得到JSON:

{
  "id":1,
  "name":"Street1",
  "streettypeid":3
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能获得JSON:

{
  "id":1,
  "name":"Street1",
  "streettypeid":
   {
    "id":3,
    "name":"Type3"
   }
}
Run Code Online (Sandbox Code Playgroud)

或者一些类似的结构.我怎样才能在.NET中实现这一目标?

我的控制器:

StreetController : BaseApiController<Street>
Run Code Online (Sandbox Code Playgroud)

    public class BaseApiController<T> : ApiController where T : BaseEntity
    {
        protected UnitOfWork unitOfWork = new UnitOfWork();

        protected IRepository<T> repository;

        public BaseApiController()
        {
            repository = unitOfWork.EFRepository<T>();
        }
        public virtual IQueryable<T> Get()
        {
          var entity = repository.Table;

          if (entity == null)
          {
              throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NoContent));
          }
          return entity;
      }
Run Code Online (Sandbox Code Playgroud)

}

Rom*_*syk 2

要保留 JSON 中的对象引用,请将以下代码添加到 Global.asax 文件中的 Application_Start 方法中:

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = 
    Newtonsoft.Json.PreserveReferencesHandling.All;
Run Code Online (Sandbox Code Playgroud)

欲了解更多数据,请阅读这篇文章。

另一种方法是尝试在 webapi 中使用OData 。您必须安装 OData 包:

Install-Package Microsoft.AspNet.Odata
Run Code Online (Sandbox Code Playgroud)

然后您就可以使用$expand它使相关实体内联包含在响应中。
您可以保留所有内容,但我认为添加是正确的IgnoreDataMember(不要忘记添加using System.Runtime.Serialization;)

public class StreetType
{
  public int ID { get; set; }
  public string Name { get; set; }
  [IgnoreDataMember]
  public virtual ICollection<Street> Streets { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

还需要向您的Get方法添加属性:

[EnableQuery]
public virtual IQueryable<T> Get()
Run Code Online (Sandbox Code Playgroud)

之后你可以创建 http 请求,如下所示:

http://blablabla/Street?$expand=StreetType
Run Code Online (Sandbox Code Playgroud)

并用Streets他们的一切StreetType