Reputation:
I'm working on WebApi project and I have 2 entities in my domain:
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; }
}
and StreetType:
public class StreetType
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Street> Streets { get; set; }
}
I use FluenApi to map these entities:
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");
}
}
and the similar for Street entity.
Now I get JSON:
{
"id":1,
"name":"Street1",
"streettypeid":3
}
How can I get the JSON like:
{
"id":1,
"name":"Street1",
"streettypeid":
{
"id":3,
"name":"Type3"
}
}
Or some similar structure. How can I accomplish this in .NET?
My Controller:
StreetController : BaseApiController<Street>
and
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;
}
}
Upvotes: 5
Views: 7765
Reputation: 24589
To preserve object references in JSON, add the following code to Application_Start method in the Global.asax file:
var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling =
Newtonsoft.Json.PreserveReferencesHandling.All;
For more datail please read this article.
Another way is try to use OData in your webapi. You have to install the OData Packages:
Install-Package Microsoft.AspNet.Odata
Then you'll able yo use $expand
that causes related entities to be included inline in the response.
You can leave all as is, but I think it will properly to add IgnoreDataMember
(do not forget add 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; }
}
Also need to add attribute to you Get
method:
[EnableQuery]
public virtual IQueryable<T> Get()
After that you can create http-request like:
http://blablabla/Street?$expand=StreetType
and get all Streets
with their StreetType
Upvotes: 2
Reputation: 2602
You need to create a view model to return that has the included entity.
Edit: here's a complete api controller method including proposed route.
[HttpGet, Route("/api/streets/{id:int:min(1)}")]
public IHttpActionResult GetYourJsonData(int id)
{
try
{
//from your unit of work class
return uow.GetEntities<Street>(x => x.ID == id)
.FirstOrDefault()
.Select(viewModel => new {
ID = viewModel.ID,
Name = viewModel.Name,
StreetTypeID = viewModel.StreetType //consider renaming this to streeytype and not street type id
});
}
catch(Exception)
{
return InternalServerError();
}
}
//Edit: in your repo class
public IEnumerable<T> GetEntities<T>(Func<T, bool> predicate) where T : class
{
return yourContext.Set<T>().Where(predicate);
}
Upvotes: 1