Search code examples
asp.net-web-apikendo-uikendo-gridodata

Kendo & Web API using OData: ODataActionParameters is null


Using OData v3, trying to bind Kendo Grid to OData Actions.

Problem

ODataActionParameters is always null...

Here are my actions:

[EnableQuery]
[HttpPost]
public virtual IQueryable<ComparitiveLocalizableString> GetComparitiveTable(ODataActionParameters parameters)
{
    string cultureCode = (string)parameters["cultureCode"];

    var query = Repository.Table
            .Where(x => x.CultureCode == null || x.CultureCode == cultureCode)
            .GroupBy(x => x.TextKey)
            .Select(grp => new ComparitiveLocalizableString
            {
                Key = grp.Key,
                InvariantValue = grp.FirstOrDefault(x => x.CultureCode == null).TextValue,
                LocalizedValue = grp.FirstOrDefault(x => x.CultureCode == cultureCode) == null ? "" : grp.FirstOrDefault(x => x.CultureCode == cultureCode).TextValue
            });

    return query;
}

[HttpPost]
public virtual IHttpActionResult PutComparitive(ODataActionParameters parameters)
{
    string cultureCode = (string)parameters["cultureCode"];
    string key = (string)parameters["key"];
    var entity = (ComparitiveLocalizableString)parameters["entity"];

    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    if (!key.Equals(entity.Key))
    {
        return BadRequest();
    }

    var existing = Repository.Table.FirstOrDefault(x => x.CultureCode == cultureCode && x.TextKey == key);

    if (existing == null)
    {
        return NotFound();
    }

    existing.TextValue = entity.LocalizedValue;

    Repository.Update(existing);

    return Updated(entity);
}

[HttpPost]
public virtual IHttpActionResult DeleteComparitive(ODataActionParameters parameters)
{
    string cultureCode = (string)parameters["cultureCode"];
    string key = (string)parameters["key"];

    var entity = Repository.Table.FirstOrDefault(x => x.CultureCode == cultureCode && x.TextKey == key);
    if (entity == null)
    {
        return NotFound();
    }

    Repository.Delete(entity);

    return StatusCode(HttpStatusCode.NoContent);
}

My OData route configuration:

var getComparitiveTableAction = builder.Entity<LocalizableString>().Collection.Action("GetComparitiveTable");
getComparitiveTableAction.Parameter<string>("cultureCode");
getComparitiveTableAction.Returns<IQueryable<ComparitiveLocalizableString>>();

var putComparitiveAction = builder.Entity<LocalizableString>().Collection.Action("PutComparitive");
putComparitiveAction.Parameter<string>("cultureCode");
putComparitiveAction.Parameter<string>("key");
putComparitiveAction.Parameter<ComparitiveLocalizableString>("entity");
putComparitiveAction.Returns<IHttpActionResult>();

var deleteComparitiveAction = builder.Entity<LocalizableString>().Collection.Action("DeleteComparitive");
deleteComparitiveAction.Parameter<string>("cultureCode");
deleteComparitiveAction.Parameter<string>("key");
deleteComparitiveAction.Returns<IHttpActionResult>();

and the config for my Kendo Grid:

var odataBaseUrl = "/odata/cms/LocalizableStrings/";

$(document).ready(function () {
    $("#Grid").kendoGrid({
        data: null,
        dataSource: {
            type: "odata",
            transport: {
                read: {
                    url: odataBaseUrl + "GetComparitiveTable",
                    dataType: "json",
                    type: "POST"
                },
                update: {
                    url: odataBaseUrl + "PutComparitive",
                    dataType: "json",
                    type: "POST"
                },
                destroy: {
                    url: odataBaseUrl + "DeleteComparitive",
                    dataType: "json",
                    type: "POST"
                },
                parameterMap: function (options, operation) {
                    if (operation === "read") {
                        alert(cultureCode);
                        return JSON.stringify({
                            cultureCode: cultureCode
                        });
                    }
                    else if (operation === "update") {
                        var model = models[0];
                        return {
                            cultureCode: cultureCode,
                            key: model.Key,
                            entity: model
                        };
                    }
                    else if (operation === "destroy") {
                        var model = models[0];
                        return {
                            cultureCode: cultureCode,
                            key: model.Key
                        };
                    }
                }
            },
            schema: {
                data: function (data) {
                    return data.value;
                },
                total: function (data) {
                    return data["odata.count"];
                },
                model: {
                    fields: {
                        Key: { type: "string", editable: false },
                        InvariantValue: { type: "string", editable: false },
                        LocalizedValue: { type: "string" }
                    }
                }
            },
            batch: true,
            //etc......

Where am I going wrong? How can I fix this?


Solution

  • It seems I just needed to add, contentType: "application/json" as per the following:

    read: {
                        url: odataBaseUrl + "GetComparitiveTable",
                        dataType: "json",
                        contentType: "application/json",
                        type: "POST"
                    },
                    update: {
                        url: odataBaseUrl + "PutComparitive",
                        dataType: "json",
                        contentType: "application/json",
                        type: "POST"
                    },
                    destroy: {
                        url: odataBaseUrl + "DeleteComparitive",
                        dataType: "json",
                        contentType: "application/json",
                        type: "POST"
                    }