This is a migrated thread and some comments may be shown as answers.

Changing the ContentType in the http request

16 Answers 1146 Views
This is a migrated thread and some comments may be shown as answers.
Markus
Top achievements
Rank 1
Markus asked on 11 Apr 2013, 12:39 PM
Hello,

I am looking for a way to change the contenttype in the http request,  it seems you can do it in jquery but there doesn't seem to be a way to do it with the razor html helpers.  I would think it would work something like line #6.  Is this possible?

Thanks,



01..DataSource(dataSource => dataSource
02.        .Ajax()
03.        .PageSize(20)
04.        .ServerOperation(true)
05.        .Events(events => events.Error("error_handler"))y
06.        .Create(update => update.Action("Customer_Create", "Customer", ContentType="Application/Json")
07.                
08.        )
09.        .Read(read => read.Action("Customer_Read", "Customer"))
10.        .Update(update => update.Action("Customer_Update", "Customer"))
11.        .Destroy(update => update.Action("Customer_Delete", "Customer"))
12.        .
13.        
14.    )
15.)

   

16 Answers, 1 is accepted

Sort by
0
Daniel
Telerik team
answered on 15 Apr 2013, 08:59 AM
Hello Markus,

This Kendo MVC Grid does not supported setting the content type. It is designed to work with the MVC controllers and the Kendo MVC server API and so not all request options can be set. You should use the JavaScript initialization in order to be able to set all options.

Regards,
Daniel
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Markus
Top achievements
Rank 1
answered on 15 Apr 2013, 07:13 PM
Hi Daniel,  

Are you suggesting I create the grid using javascript and not razor?  Maybe I am misunderstanding?  Or are you saying I can set the content type via javascript prior to rendering the grid with razor?  Can you provide an example of the latter if so?  The issue I am trying to resolve is a null reference error trying to execute the create action against our WCF odata service.  The object is populated all the way up to the point where it is trying to write the record back to the entity at which point it is null.  The create action works in fiddler but I can duplicate the error by omitting the content-type='Application/Json' parameter in the header.  I am thinking this may be the reason...



-Markus
0
Daniel
Telerik team
answered on 17 Apr 2013, 01:14 PM
Hello Markus,

Yes, you should use the JavaScript initialization in order to be able to send the data as JSON. The MVC Grid DataSource uses form data. If you wish to use the wrappers for this scenario as well then it is possible possible to modify the options via JavaScript after the Grid has already been initialized e.g.

$(function () {
    var grid = $("#grid").data("kendoGrid");
    grid.dataSource.transport.options.update.contentType = "application/json";
    //override the parameterMap function in order to convert the data to JSON
    grid.dataSource.transport.parameterMap = function (options, type) {
        return kendo.stringify(options);
    }
});
Kind regards,
Daniel
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Markus
Top achievements
Rank 1
answered on 18 Apr 2013, 03:50 PM
I am still having no luck with this, when the odataservice calls the business logic controller to write the record it passes a null reference....the customer object is populated up until the call to the business logic CreateEntity method. The Create Entity method is never passed the customer object and always throws a null reference.  I originally thought this was because of the content type but I am having my doubts now.  Accessing the WCF service directly with fiddler successfully creates the record...


Here is the application level  Customer_Create action being called by the kendo grid,

[System.Web.Http.HttpPost]
                public ActionResult Customer_Create([DataSourceRequest] DataSourceRequest request, Application.ServiceProxy.CustomerDTO customer)
        {
 
            if (customer != null && ModelState.IsValid)
            {
                var odataService = new Container(new Uri("http://localhost:8089/odata/"));
                //odataService.r
                 odataService.AddToCustomer(customer);
                odataService.SaveChanges();
 
                return Json(ModelState.ToDataSourceResult());
 
            }
            return View("Index");
        }

Here is the CreateEntity method being called through the generated WCF data service.

protected override CustomerDTO CreateEntity(CustomerDTO customerDTO)
{
     
    var customer = new customer()
    {
        matchcode = customerDTO.matchcode,
        salesOrganizationID = customerDTO.salesOrganizationID,
        statusID = customerDTO.statusID,
        serviceLevelStatusID = customerDTO.serviceLevelStatusID,
        mediaIDLogo = customerDTO.mediaIDLogo,
        systemID = customerDTO.systemID,
        customerExternalSystemID = customerDTO.customerExternalSystemID,
        internationalGroup = customerDTO.internationalGroup,
        division = customerDTO.division,
        corporateID = customerDTO.corporateID,
        inventoryManagerID = customerDTO.inventoryManagerID,
        dunsNumber = customerDTO.dunsNumber
    };
 
    entity.customer.Add(customer);
    entity.SaveChanges();
 
    return GetEntityByKey(customer.customerID);
}




0
Daniel
Telerik team
answered on 22 Apr 2013, 02:16 PM
Hello Markus,

The code looks correct. A ViewResult should not be returned from the action even if there is a ModelState error but this should not cause problems with the binding. Could you provide a runnable project so I can investigate further?

Regards,
Daniel
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Patrick
Top achievements
Rank 2
answered on 03 Nov 2013, 10:09 PM
Hi,

I've using this example and everything works great expect when the JSON is posted back to the server the sort prop is null. I'm using the DataSourceRequest binder on the action parameter "request". If I change it back to the default form post data (so I don't change the contentType option) all works with the sort prop. However I really need to post the data as JSON. Any help would be greatly appreciated!

Patrick
0
Daniel
Telerik team
answered on 06 Nov 2013, 09:00 AM
Hello,

The DataSourceRequestAttribute does not support getting the values from the payload. If you wish to use JSON for the read request then you should implement a custom binder. If JSON should be used only for the create, update and destroy operations then you could check the type in the parameterMap function and use the "aspnetmvc-ajax" transport to serialize the values when read is performed:

$(function () {
    var grid = $("#grid").data("kendoGrid"),
        mvcTransport = new kendo.data.transports["aspnetmvc-ajax"]({});
    grid.dataSource.transport.options.update.contentType = "application/json";
 
    grid.dataSource.transport.parameterMap = function (options, type) {
        var result;
        if (type == "read") {
            result = mvcTransport.parameterMap(options, type);
        }
        else {
            result = kendo.stringify(options);
        }
        return result;
    }
});
Regards,
Daniel
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Robert
Top achievements
Rank 1
answered on 08 Apr 2014, 03:25 PM
[quote]If you wish to use JSON for the read request then you should implement a custom binder.[/quote]

I am trying to use JSON for the Read request and it is not working.  How do I implement a custom binder?

Here is what I have:

    $(function ()
    {
        var grid = $('#JobsGrid').data("kendoGrid");
        grid.dataSource.transport.options.read.contentType = "application/json; charset=utf-8";
        grid.dataSource.transport.parameterMap = function (options, operation) { return JSON.stringify(postData); }
    });
0
Daniel
Telerik team
answered on 11 Apr 2014, 07:08 AM
Hello Robert,

Could you clarify why JSON should be used for read? The easiest option if this is required is to still serialize the state parameters to string values via the default parameterMap function. The alternative is to parse the collection of objects in the format specified in the documentation(sort, filter, group) to lists of state descriptors (SortDescriptor, GroupDescriptor and FIlterDescriptor). 
On a side note, since the latest official release the contentType and parameterMap options as well as all other dataSource options can be set with the Custom builder. I attached a sample project which uses the Custom builder and the default parameterMap function to serialize the state values.

Regards,
Daniel
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Robert
Top achievements
Rank 1
answered on 14 Apr 2014, 01:47 PM
I need to use JSON because that is what MVC expects to receive in order to Deserialize the parameter.  

So this is what I want to happen, I want to Post the JSON to the server and then my method would look like this:

        [HttpPost]
        public ActionResult GetJobs([DataSourceRequest]DataSourceRequest request, FilterViewModel filters)

The filters should come in as JSON and then .Net can Deserialize them as the FilterViewModel object.

The way it works now it is not coming in as JSON and therefore I have to declare my method like this:

        [HttpPost]
        public ActionResult GetJobs([DataSourceRequest]DataSourceRequest request, string filters)

and then I have to do 
       FilterViewModel viewModel = new JavaScriptSerializer().Deserialize<FilterViewModel>(filters);
in order to Deserialize the parameter.

0
Daniel
Telerik team
answered on 16 Apr 2014, 11:31 AM
Hello again Robert,

How are you sending the FilterViewModel with the read request? The MVC modelbinder also supports form data so the model should still be bound as expected with the default content type.

Regards,
Daniel
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Robert
Top achievements
Rank 1
answered on 16 Apr 2014, 05:23 PM
I am using JSON.stringify on the form data.
0
Daniel
Telerik team
answered on 17 Apr 2014, 02:29 PM
Hello Robert,

Isn't the data bound when not using JSON.stringify? In the latest versions, the additional data is also serialized as expected by the model binder for form data.

Regards,
Daniel
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Robert
Top achievements
Rank 1
answered on 17 Apr 2014, 03:54 PM
Here is my code.  I am open to how you would do it, but this is the only way I could get it work.

The DataSource setting on my grid (MVC Razor):
        .DataSource(ds => ds
            .Ajax()
            .PageSize(50)
            .Read(read => read.Action("GetJobs", "Gremlin").Data("SendFilters").Type(HttpVerbs.Post))

JavaScript SendFilters Method:
function SendFilters()
{
    var filters = new FilterViewModel();
    return { filters: JSON.stringify(filters) };
};

function FilterViewModel()
{
    var self = this;
    self.JobName = $('#JobName').val();
    self.JobID = $('#JobID').val();
    self.Client = $("#Client").data("kendoDropDownList").value();
    self.Project = $("#Project").data("kendoDropDownList").value();
    self.Schematic = $("#Schematic").data("kendoDropDownList").value();
    self.JobNumber = $('#JobNumber').val();
    self.User = $('#User').val();
    self.Server = $('#Server').val();
    self.Source = $('#Source').val();
    self.RelativeStartTime = $('#RelativeStartTime').is(':checked');

    if (self.RelativeStartTime)
    {
        self.RelativeStartAmount = $('#RelativeStartAmount').val();
        self.RelativeStartInterval = $('#RelativeStartInterval').data("kendoDropDownList").value();
    }
    else
    {
        self.AbsoluteStartTime = $('#AbsoluteStartTime').data("kendoDateTimePicker").value();
    }

    self.RelativeEndTime = $('#RelativeEndTime').is(':checked');

    if (self.RelativeEndTime)
    {
        self.RelativeEndAmount = $('#RelativeEndAmount').val();
        self.RelativeEndInterval = $('#RelativeEndInterval').data("kendoDropDownList").value();
    }
    else
    {
        self.AbsoluteEndTime = $('#AbsoluteEndTime').data("kendoDateTimePicker").value();
    }

    self.Active = $('#Active').is(":checked");
    self.Completed = $('#Completed').is(":checked");
    self.Failed = $('#Failed').is(":checked");
    self.Paused = $('#Paused').is(":checked");
    self.Stopped = $('#Stopped').is(":checked");
    self.AWSJobs = $('#AWSJobs').is(":checked");
    self.ResubmittedOnly = $('#ResubmittedOnly').is(":checked");

    self.NA = $('#NA').is(":checked");
    self.Unchecked = $('#Unchecked').is(":checked");
    self.NeedsRevisited = $('#NeedsRevisited').is(":checked");
    self.NotAnIssue = $('#NotAnIssue').is(":checked");
    self.Fixed = $('#Fixed').is(":checked");
};
0
Daniel
Telerik team
answered on 18 Apr 2014, 06:55 AM
Hi,

Based on the code that you provided, the model should be bound as expected with the default contentType and parameterMap function when the SendFilters function is changed as in the snippet below:
function SendFilters() {
    var filters = new FilterViewModel();
    return filters;
};


Regards,
Daniel
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Robert
Top achievements
Rank 1
answered on 21 Apr 2014, 11:32 AM
That worked.

Thank you.
Tags
Grid
Asked by
Markus
Top achievements
Rank 1
Answers by
Daniel
Telerik team
Markus
Top achievements
Rank 1
Patrick
Top achievements
Rank 2
Robert
Top achievements
Rank 1
Share this question
or