C# · 12月 21, 2021

c# – 带有外键的ASP.NET WebApi JSON响应和实体

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

public class Street{ public int ID { get; set; } public string Name { get; set; } public int StreetTypeID { get; set; } public virtual StreetType StreetType { get; set; }}

和街道类型:

public class StreetType{ public int ID { get; set; } public string Name { get; set; } public virtual ICollection<Street> Streets { get; set; }}

我使用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"); } }

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

{ “id”:1,”name”:”Street1″,”streettypeid”:3}

我怎样才能获得JSON:

{ “id”:1,”streettypeid”: { “id”:3,”name”:”Type3″ }}

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

我的控制器:

StreetController : BaseApiController<Street>

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

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

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;

欲了解更多数据,请阅读this文章.

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

Install-Package Microsoft.AspNet.Odata

然后你就可以使用$expand来导致相关实体被包含在响应内联中.
您可以按原样保留所有内容,但我认为可以正确添加IgnoreDataMember(不要忘记使用System.Runtime.Serialization添加;)

public class StreetType{ public int ID { get; set; } public string Name { get; set; } [IgnoreDataMember] public virtual ICollection<Street> Streets { get; set; }}

还需要为你添加属性Get方法:

[EnableQuery]public virtual IQueryable<T> Get()

之后,您可以创建http请求,如:

http://blablabla/Street?$expand=StreetType

并使用他们的StreetType获取所有Streets