Skip to content

Instantly share code, notes, and snippets.

@BryanWilhite
Last active October 11, 2015 04:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BryanWilhite/25046e8d35341ea88e23 to your computer and use it in GitHub Desktop.
Save BryanWilhite/25046e8d35341ea88e23 to your computer and use it in GitHub Desktop.
ASP.NET Web API ODataController and OWIN [OData 4.0]
void Main()
{
var baseAddress = "http://localhost:9000/";
var client = new HttpClient();
try
{
using (WebApp.Start<Startup>(url: baseAddress))
{
HttpResponseMessage response;
Action<string> callOwin = path =>
{
response = client.GetAsync(baseAddress + path).Result;
response.Dump();
response.Content.ReadAsStringAsync().Result.Dump();
};
callOwin("api/$metadata");
callOwin("api/Product?$count=true");
callOwin("api/Product(2)");
callOwin("api/Product?$filter=Category+eq+'Bakery'+and+indexof(Name,'Tortillas')+ne+-1");
}
}
finally
{
client.Dispose();
}
}
public interface IProduct
{
int Id { get; set; }
string Name { get; set; }
decimal Price { get; set; }
string Category { get; set; }
}
public class Product : IProduct
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
}
public class ProductRepository
{
public IQueryable<IProduct> LoadProducts()
{
var data = new []
{
new Product{ Id = 1, Category = "Bakery", Name = "Spinach/Rice Tortillas", Price = 6.99M },
new Product{ Id = 2, Category = "Bakery", Name = "Organic Corn Tortillas", Price = 1.99M },
new Product{ Id = 3, Category = "Bakery", Name = "Flower Flour Thins", Price = 5.99M },
new Product{ Id = 4, Category = "Canned", Name = "Ranchero Beans", Price = 1.69M },
new Product{ Id = 5, Category = "Canned", Name = "Wild Caught Sardines in Water", Price = 3.99M },
new Product{ Id = 6, Category = "Canned", Name = "Wild Caught Salmon in Water", Price = 6.99M },
new Product{ Id = 7, Category = "Grocery", Name = "Organic Swiss Chard", Price = 2.89M },
new Product{ Id = 8, Category = "Grocery", Name = "Organic Kale", Price = 2.99M },
new Product{ Id = 9, Category = "Grocery", Name = "Organic Red Potatoes", Price = 2.49M },
};
return data.AsQueryable();
}
}
public class ProductController : ODataController
{
public ProductController()
{
this._repository = new ProductRepository();
this._repository.Dump("controller and repository loaded");
}
[EnableQuery(PageSize = 3, AllowedQueryOptions = AllowedQueryOptions.All)]
public IQueryable<IProduct> Get()
{
return this._repository.LoadProducts();
}
[EnableQuery]
public SingleResult<IProduct> Get([FromODataUri] int key)
{
IQueryable<IProduct> result = this._repository.LoadProducts().Where(p => p.Id == key);
return SingleResult.Create(result);
}
ProductRepository _repository;
}
public class ControllerResolver : DefaultHttpControllerTypeResolver
{
public override ICollection<Type> GetControllerTypes(IAssembliesResolver assembliesResolver)
{
var types = Assembly.GetExecutingAssembly().GetExportedTypes();
var controllerType = typeof(System.Web.Http.Controllers.IHttpController);
var list = types.Where(i => controllerType.IsAssignableFrom(i)).ToList();
list.Add(typeof(MetadataController));
list.Dump(this.GetType().Name);
return list;
}
}
public class Startup
{
public void Configuration(IAppBuilder appBuilder)
{
var config = new HttpConfiguration();
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
config.Services.Replace(typeof(IHttpControllerTypeResolver), new ControllerResolver());
var builder = new ODataConventionModelBuilder();
builder
.EntitySet<Product>("Product")
.EntityType.DerivesFrom<IProduct>();
var model = builder.GetEdmModel();
config.MapODataServiceRoute("odata", "api", model);
appBuilder.UseWebApi(config);
config.EnsureInitialized();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment