2015-07-28 7 views
5

я работаю над проектом WebAPI и у меня есть 2 объектов в моем домене:
StreetASP.NET WebAPI JSON ответ и Сущности с внешним ключом

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

и StreetType:

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

и аналогичные f или Улица.
Теперь я получаю JSON:

{ 
    "id":1, 
    "name":"Street1", 
    "streettypeid":3 
} 

Как я могу получить JSON как:

{ 
    "id":1, 
    "name":"Street1", 
    "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; 
     } 

}

ответ

2

Чтобы сохранить ссылки на объект в JSON, добавьте следующий код в метод Application_Start в файле Global.asax:

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

Для получения дополнительной datail пожалуйста, прочитайте статью this.

Другой способ - использовать OData в вашем webapi. Вы должны установить пакеты OData:

Install-Package Microsoft.AspNet.Odata 

Тогда вы будете в состоянии использовать йо $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; } 
} 

необходимо также добавить атрибут к вам Get метод:

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

После этого вы можете создать HTTP-запрос, как:

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

и получить все Streets с их StreetType

+0

Спасибо. Whili Я пытаюсь, я получил ошибку: 'Не удалось найти свойство с именем 'StreetTypes' в типе 'Domain.Entities. Улица '. "' –

+0

Какой http-запрос вы используете? – Marusyk

+0

'http: // mysite/Street? $ Expand = StreetTypes' –

1

Вы должны создать модель представления для возврата, который имеет включенный объект.

Редактировать: здесь приведен полный метод контроллера api, включая предлагаемый маршрут.

[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); 
} 
+0

Спасибо, но я не могу использовать dbContext в моем контроллере, потому что реализован шаблон UnitOfWork, и у меня нет dbContext –

+1

Можете ли вы обновить свой вопрос, чтобы показать, что вы используете для получения данных? В конечном итоге это будет то же самое, часть контекста данных будет просто перемещаться внутри вашего репозитория, который будет открыт вашей рабочей единицей. –

+0

Я только что обновил вопрос. –

Смежные вопросы