I migrated to the WebAPI 2.2 RC (Microsoft.AspNet.WebApi -Version 5.2.0-rc) and I since them I get only 406 (Not Acceptable) as status response on all my queries, for example:
http://localhost:7923/api/Quotes(1)
OData Service Configuration
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.EnableSystemDiagnosticsTracing();
config.MapODataServiceRoute("api", "api", CreateEdmModel());
}
private static IEdmModel CreateEdmModel()
{
var odataModelBuilder = new ODataConventionModelBuilder();
odataModelBuilder.EntitySet<Tag>("Tags");
odataModelBuilder.EntitySet<Author>("Authors");
EntitySetConfiguration<Quote> quoteEntitySetConfiguration = odataModelBuilder.EntitySet<Quote>("Quotes");
FunctionConfiguration getQuotesRandomFunction = quoteEntitySetConfiguration.EntityType.Collection.Function("Random");
getQuotesRandomFunction.Parameter<int>("count");
getQuotesRandomFunction.ReturnsCollectionFromEntitySet<Quote>("Quotes");
return odataModelBuilder.GetEdmModel();
}
}
QuotesController
public class QuotesController : ODataController
{
private WhatAQuoteDb db = new WhatAQuoteDb();
[ODataRoute("Default.Random(count={count})")]
[EnableQuery]
public IHttpActionResult GetQuotesRandom(int count)
{
return Ok(db.Quotes.OrderBy(quote => Guid.NewGuid()).Take(count));
}
// GET: odata/Quotes
[EnableQuery]
public IQueryable<Quote> GetQuotes()
{
return db.Quotes;
}
// GET: odata/Quotes(5)
[EnableQuery]
public SingleResult<Quote> GetQuote([FromODataUri] int key)
{
return SingleResult.Create(db.Quotes.Where(quote => quote.Id == key));
}
// PUT: odata/Quotes(5)
public async Task<IHttpActionResult> Put([FromODataUri] int key, Quote quote)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (key != quote.Id)
{
return BadRequest();
}
db.Entry(quote).State = EntityState.Modified;
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!QuoteExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(quote);
}
// POST: odata/Quotes
public async Task<IHttpActionResult> Post(Quote quote)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.Quotes.Add(quote);
await db.SaveChangesAsync();
return Created(quote);
}
// PATCH: odata/Quotes(5)
[AcceptVerbs("PATCH", "MERGE")]
public async Task<IHttpActionResult> Patch([FromODataUri] int key, Delta<Quote> patch)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
Quote quote = await db.Quotes.FindAsync(key);
if (quote == null)
{
return NotFound();
}
patch.Patch(quote);
try
{
await db.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!QuoteExists(key))
{
return NotFound();
}
else
{
throw;
}
}
return Updated(quote);
}
// DELETE: odata/Quotes(5)
public async Task<IHttpActionResult> Delete([FromODataUri] int key)
{
Quote quote = await db.Quotes.FindAsync(key);
if (quote == null)
{
return NotFound();
}
db.Quotes.Remove(quote);
await db.SaveChangesAsync();
return StatusCode(HttpStatusCode.NoContent);
}
// GET: odata/Quotes(5)/Author
[EnableQuery]
public SingleResult<Author> GetAuthor([FromODataUri] int key)
{
return SingleResult.Create(db.Quotes.Where(m => m.Id == key).Select(m => m.Author));
}
// GET: odata/Quotes(5)/Tags
[EnableQuery]
public IQueryable<Tag> GetTags([FromODataUri] int key)
{
return db.Quotes.Where(m => m.Id == key).SelectMany(m => m.Tags);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
private bool QuoteExists(int key)
{
return db.Quotes.Count(e => e.Id == key) > 0;
}
}
I checked your solution and found that you used service reference.
However adding service reference doesn't support OData V4 and the version in your generated code is V3.
You can try OData T4 code generator to generate client code.
Check the blog below:
http://blogs.msdn.com/b/odatateam/archive/2014/03/11/how-to-use-odata-client-code-generator-to-generate-client-side-proxy-class.aspx
Update:
I checked your solution again and found the problem:
The ODataController you used is V3!
If you want the V4 version, you need to change the using namespace in your controller cs file
From
using System.Web.Http.OData;
To
using System.Web.OData;
What is more, there is other problem that the following template is invalid when I start up the project.
[ODataRoute("Default.Random(count={count})")]
I guest that the random function you defined is a function import and you should define like this:
FunctionConfiguration getQuotesRandomFunction = odataModelBuilder.Function("Random");
And the function import should not add namespace and the template should be:
[ODataRoute("Random(count={count})")]
Let me know if you have other problems.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With