问题
How it is possible to implement such "smart" GET in WebAPI? I have 2 classes that i want to get from my service. Let's say its book store which has relation to book objects.
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; }
}
I have backend with SQL server and EntityFramework adapter in code. How should I make to return the list of books only after I need it (call for it), like with OData? As you can see I have circular dependancies, which makes my JSON serializer to show errors. I resolve it with:
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
but serialized all data and my response is HUGE, which is not good for my Windows Phone app. In some cases I need only Store object, but in other cases I need Store with all referenced books.
In controllers I user [Queryable] attribute to use OData queries. P.S. I can't create more web-methods like GetBooks, GetStore and so on. It should be one method.
How could I resolve my problem?
回答1:
How could I resolve my problem?
Do not return Entities from your API action methods.
Instead, return models.
So instead of this:
public IEnumerable<Store> GetStores()
{
using (var db = new MyDbContext())
{
return db.Stores;
}
}
Do something like this:
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,
}),
});
}
}
By doing it this way you eliminate the circular dependency graph. Book
no longer references Store
, only StoreId
.
回答2:
You need to make it hypermedia driven. Books and stores can be thought of as different resources. When a GET request is issued against a particular book, like @danlugwig has suggested, you can return a book model along with the URIs for its corresponding store. The consumer can make use of this URI to retrieve the Store details. Similarly for Store resource.
来源:https://stackoverflow.com/questions/19220825/implementing-webapi-with-circular-dependencies-and-loadable-lists