如何在WebAPI中实现这种“智能”GET?我有2个课程,我想从我的服务中获得。让我们说它的书店与书籍对象有关。
public class Book
{
Guid Id { get; set; }
string Title { get; set; }
Store Store { get; set; }
}
public class Store
{
Guid Id { get; set; }
string Title { get; set; }
string Owner { get; set; }
IEnumerable<Book> Books { get; set; }
}
我在代码中有SQL Server和EntityFramework适配器的后端。我应该如何在我需要它之后返回书籍列表(请求它),就像OData一样? 正如您所看到的,我有循环依赖,这使我的JSON序列化程序显示错误。我解决它:
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
但序列化了所有数据,我的回复是巨大的,这对我的Windows Phone应用程序来说并不好。在某些情况下,我只需要Store对象,但在其他情况下,我需要Store以及所有引用的书籍。
在控制器中,我使用[Queryable]属性来使用OData查询。 附:我无法创建更多的Web方法,如GetBooks,GetStore等。它应该是一种方法。
我怎样才能解决我的问题?
答案 0 :(得分:1)
我怎样才能解决我的问题?
不要从API操作方法中返回实体。
相反,返回模型。
所以不要这样:
public IEnumerable<Store> GetStores()
{
using (var db = new MyDbContext())
{
return db.Stores;
}
}
做这样的事情:
public IEnumerable<StoreModel> GetStores()
{
using (var db = new MyDbContext())
{
var entities = db.Stores;
return entities.Select(x => new StoreModel
{
Id = x.Id,
Title = x.Title,
Owner = x.Owner,
Books = x.Books.Select(y => new BookModel
{
Id = y.Id,
Title = y.Title,
StoreId = x.Id,
}),
});
}
}
通过这种方式,您可以消除循环依赖图。 Book
不再引用Store
,仅引用StoreId
。
答案 1 :(得分:0)
你需要让它成为超媒体驱动的。书籍和商店可以被认为是不同的资源。当针对特定书籍发出GET请求时,如@danlugwig建议的那样,您可以返回书籍模型以及相应商店的URI。消费者可以使用此URI来检索商店详细信息。同样适用于商店资源。