0

I'm implementing an ODataController. It's OData V3 for compatibility reasons with Breeze.js:

using System.Web.Http.OData;
public class OffersController : ODataMetadataController
{
    ...

Somwhere in the middle I want to implement merge/patch as seen in examples:

[AcceptVerbs("PATCH", "MERGE")]
public IHttpActionResult Patch([FromODataUri] int key, Delta<BOOffer> delta)
{
    ...

For some reason I'm getting the following error:

No MediaTypeFormatter is available to read an object of type 'Delta`1' from content with media type 'application/json'.;

Ok. Delta<> is OData related, I would need an OData formatter for that.

Iterating through the formatters (as on this page), it does not seem to be an OData formatter there:

JsonMediaTypeFormatter
    CanReadType: True
    CanWriteType: True
    Base: BaseJsonMediaTypeFormatter
    Media Types: application/json, text/json
XmlMediaTypeFormatter
    CanReadType: True
    CanWriteType: True
    Base: MediaTypeFormatter
    Media Types: application/xml, text/xml
FormUrlEncodedMediaTypeFormatter
    CanReadType: False
    CanWriteType: False
    Base: MediaTypeFormatter
    Media Types: application/x-www-form-urlencoded
JQueryMvcFormUrlEncodedFormatter
    CanReadType: True
    CanWriteType: False
    Base: FormUrlEncodedMediaTypeFormatter
    Media Types: application/x-www-form-urlencoded

Should I register this formatter? Shouldn't it be automatic? If I need to register it manually, how?

If I change the input parameter form Delta<BOOffer> to BOOffer the method gets called, but since only the changed properties are sent, this is not something I can use.

I configure my controller in app_start like this:

System.Web.Http.OData.Builder.ODataConventionModelBuilder builderV3 = new System.Web.Http.OData.Builder.ODataConventionModelBuilder();
var entitySetConfigV3 = builderV3.EntitySet<BOOffer>("Offers");
entitySetConfigV3.EntityType.HasKey(o => o.ID);

config.Routes.MapODataServiceRoute(
    routeName: "odata/v3", 
    routePrefix: "odata/v3",
    model: builderV3.GetEdmModel(),
    batchHandler: new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
vinczemarton
  • 7,756
  • 6
  • 54
  • 86

1 Answers1

1

The reason for this was referencing both System.Web.Http.OData (odatav3) and System.Web.OData (odatav4) in the project and mixing up references.

the System.Web.Http.OData.Formatter.ODataMediaTypeFormatter is not configured to be able to serialize into System.Web.OData.Delta<T>.

Using to System.Web.Http.OData.Delta<T> worked as intended.

Be careful about referencing different OData versions in one projects.

vinczemarton
  • 7,756
  • 6
  • 54
  • 86