Null parameter in Json controller method while Jquery parameter has value - c#

I am creating a cascading dropdown list based on an example I found here
The query sent to the server to request the second dropdownlist values has non null parameters but when I break in the controller method, it appears empty. As you can see below.
Any help would be greatly appreciated ! Thanks !!
It's using jQuery and ASP.NET MVC 5 while my project is ASP.NET MVC Core 2
The code in the controller is the following :
public JsonResult States(string Country)
{
List<string> StatesList = new List<string>();
switch (Country)
{
case "India":
StatesList.Add("New Delhi");
StatesList.Add("Mumbai");
StatesList.Add("Kolkata");
StatesList.Add("Chennai");
break;
}
return Json(StatesList);
}
And here is the AJAX :
<script src = "/lib/jquery/dist/jquery.js" > </script>
<script>
$(document).ready(function ()
{
$("#State").prop("disabled", true);
$("#Country").change(function ()
{
if ($("#Country").val() != "Select")
{
var CountryOptions = {};
CountryOptions.url = "/Dropdown/states";
CountryOptions.type = "POST";
CountryOptions.data = JSON.stringify({ Country: $("#Country").val() });
CountryOptions.datatype = "json";
CountryOptions.contentType = "application/json";
CountryOptions.success = function (StatesList)
{
$("#State").empty();
for (var i = 0; i < StatesList.length; i++)
{
$("#State").append("<option>" + StatesList[i] + "</option>");
}
$("#State").prop("disabled", false);
};
CountryOptions.error = function ()
{
alert("Error in Getting States!!");
};
$.ajax(CountryOptions);
}
else
{
$("#State").empty();
$("#State").prop("disabled", true);
}
});
});

Since you have specified the contentType = "application/json" and are sending stringified data, then you need to add the [FromBody] attribute in the POST method to instruct the ModelBinder to use the content-type header to determine the IInputFormatter to use for reading the request (which for json is the JsonInputFormatter). Change the signature of the method to
[HttpPost]
public JsonResult States([FromBody]string Country)
However, it is not necessary send the data as json, and you can use the default contentType ('application/x-www-form-urlencoded; charset=UTF-8'). You can delete the contentType option and use
CountryOptions.data = { Country: $("#Country").val() }; // not stringified
// CountryOptions.contentType = "application/json";
For more information, refer Model binding JSON POSTs in ASP.NET Core.

Related

Not able to bind data to datatable in ASP.NET MVC

Below is my code from view from my ASP.NET MVC project. I am using datatable to create a table. I am fetching data from a Web API. Data is being returned but while binding I get the error shown here. I tried deleting a lot of code which had buttons. Now I just have code for simply binding it.
datatables warning: table id=patients - ajax error. for more information about this error, please see http://datatables.net/tn/7
jQuery code :
$(document).ready(function () {
debugger;
var table = $("#patients").DataTable({
ajax: {
url: "/api/patients",
dataSrc: ""
},
columns: [
{
data: "First_Name"
},
{
data: "phoneNumber",
render: function (data) {
debugger;
return data.toString().replace(
/(\d\d\d)(\d\d\d)(\d\d\d\d)/g, '$1-$2-$3');
}
},
{
data: "Address"
},
]
});
});
API code from controller:
public IHttpActionResult GetPatients()
{
var patientDto = getdata();
return Ok(patientDto);
}
public IEnumerable<Patient_Response> getdata()
{
IEnumerable<Patient_Response> students = null;
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer 0f6af107-6ad2-4665-ad24-f09402d50082");
client.BaseAddress = new Uri("http://localhost:6600/api/");
// HTTP GET
var responseTask = client.GetAsync("patients");
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsAsync<IList<Patient_Response>>();
readTask.Wait();
students = readTask.Result;
}
else //web api sent error response
{
// log response status here..
students = Enumerable.Empty<Patient_Response>();
ModelState.AddModelError(string.Empty, "Server error. Please contact administrator.");
}
}
return students;
}
What is wrong? I am not able to figure out.
Did you read the documentation: https://datatables.net/manual/tech-notes/7
This occurs when jQuery falls into its error callback handler (this callback built into DataTables), which will typically occur when the server responds with anything other than a 2xx HTTP status code.
That means that your call go the controller, failed to bring any data.
You can use the following code to see what went wrong:
$.fn.dataTable.ext.errMode = 'none';
$('#patients')
.on( 'error.dt', function ( e, settings, techNote, message ) {
alert( 'An error has been reported by DataTables: ', message );
} )
.DataTable();

How to get selected index changed value in controller mvc c#

I am getting value in a dropdown list and I wanted to get the selected value in controller when user select any value from the dropdown list. My view is -
#using (Html.BeginForm("ApReport", "Sales", FormMethod.Post))
{
#Html.DropDownList("Ddl", null, "All", new { #class = "control-label"})
#Html.Hidden("rddl")
}
controller -
[HttpPost]
public ActionResult ApReport(ApReport Ddl)
{
string Ddlvalue = string.Empty;
if (Request.Form["rddl"] != null)
{
Ddlvalue = Request.Form["rddl"].ToString();
}
}
but I am not getting any value. Also, I donot want to use any submit button.
Thanks in advance
The use of Ajax allows you as the developer to update the main view without reloading the entire page, as well as send data to the server in the background.
This is how I would have accomplished this task.
Firstly, I would have created an action in my controller which returns a JsonResult. This will return a JSON object to your calling jquery code, that you can use to get values back into your views. Here is an example of the action method.
[HttpGet]
public JsonResult YourActionName(string selectedValue) //Assuming key in your dropdown is string
{
var result = DoYourCalculation(selectedValue);
return Json(new { myResult = result }, JsonRequestBehavior.AllowGet);
}
Now, you need to add your jquery code. I would recommend you place this in a seperate javascript file referenced by your view.
Here is the JQuery code, with the ajax call to the Action in your controller. The Ajax call to the server is initiated by the 'change' event of your DropDown, handled in JQuery, as can be seen below.
$(function () {
$(document)
.on('change', '#Ddl', function(){
var valueofDropDown = $(this).val();
var url = '/YourControllerName/YourActionName';
var dataToSend = { selectedValue: valueofDropDown }
$.ajax({
url: url,
data: dataToSend,
type: 'GET',
success: function (dataReceived) {
//update control on View
var receivedValue = dataReceived.myResult ;
$('YourControlIDToUpdate').val(receivedValue);
}
})
});
};

Why DatasourceRequest is not passed on toolbar's custom command in Kendo Grid

I try to create a custom command button on toolbar in Kendo Grid. The code is like
Html.Kendo().Grid...
.ToolBar(commands => commands.Custom().Text("Export").Action("ExportAthletePageToExcel", "ExportExcelButton", new { selectedSportId = Model.CurrentSport, yearId = Model.CurrentYear }))
...
Controller is like,
public ActionResult ExportAthletePageToExcel(DataSourceRequest request, string selectedSportId, string yearId)
...
It works for parameters like selectedSportId and yearId, except request does not have right info for grid (filter, sort, page and etc). I'd like to know what is the problem.
Thanks.
I indirectly stumbled across a solution to this that I like. Telerik has a demo posted for exporting a grid's contents to Excel. They use a custom command, and set the DataSourceRequest parameters in javascript on the client side using the OnDataBound event of the grid. I've put together the relevant bits here for you...
Include the four DataSourceRequest parameters in the Action's routevalues, but with placeholder tildes which will be replaced in step 2:
.ToolBar(commands => commands.Custom().Text("Export").Action("ExportAthletePageToExcel", "ExportExcelButton", new { page = "~", pageSize = "~", filter = "~", sort = "~", selectedSportId = Model.CurrentSport, yearId = Model.CurrentYear }))
Include a call to a javascript function in the DataBound event:
.Events(ev => ev.DataBound("onDataBound"))
then add the following script to the page:
function onDataBound(e) {
var grid = this;
// ask the parameterMap to create the request object for you
var requestObject = (new kendo.data.transports["aspnetmvc-server"]({ prefix: "" }))
.options.parameterMap({
page: grid.dataSource.page(),
sort: grid.dataSource.sort(),
filter: grid.dataSource.filter()
});
// Get the export link as jQuery object
var $exportLink = grid.element.find('.export');
// Get its 'href' attribute - the URL where it would navigate to
var href = $exportLink.attr('href');
// Update the 'page' parameter with the grid's current page
href = href.replace(/page=([^&]*)/, 'page=' + requestObject.page || '~');
// Update the 'sort' parameter with the grid's current sort descriptor
href = href.replace(/sort=([^&]*)/, 'sort=' + requestObject.sort || '~');
// Update the 'pageSize' parameter with the grid's current pageSize
href = href.replace(/pageSize=([^&]*)/, 'pageSize=' + grid.dataSource._pageSize);
//update filter descriptor with the filters applied
href = href.replace(/filter=([^&]*)/, 'filter=' + (requestObject.filter || '~'));
// Update the 'href' attribute
$exportLink.attr('href', href);
}
Now in your controller method you'll have access to the DataSourceRequest with all the relevant parameters populated with the current state. Also note that you're missing the attribute [DataSourceRequest] in your method's request parameter so it should look like this:
public ActionResult ExportAthletePageToExcel([DataSourceRequest]DataSourceRequest request, string selectedSportId, string yearId)
I don't think a custom Toolbar is supposed to send the datasourcerequest, you can try doing it with javascript though.
For example:
function exportAthletePageToExcel(){
var dataSource = $('#YourGrid').data('kendoGrid').dataSource;
var dataSourceRequest = dataSource.transport.parameterMap({
filter: dataSource.filter(),
page: dataSource.page(),
pageSize: dataSource.pageSize(),
sort: dataSource.sort()
});
var data = "";
for (var key in dataSourceRequest) {
if (dataSourceRequest[key] !== undefined) {
data += key + "=" + dataSourceRequest[key] + "&";
}
}
$.ajax({
type: "POST",
contentType: "application/x-www-form-urlencoded; charset=UTF",
url: '#Html.Action("ExportAthletePageToExcel", "ExportExcelButton", new { selectedSportId = Model.CurrentSport, yearId = Model.CurrentYear })',
data: data,
success: function(){
dataSource.read();
}
});
}

How to bind the response data from my post method controller in MVC

Given the Controller View and JS how do you bind the JSON data returned from a post action controller.Is this possible.
Controller
[HttpPost]
public ActionResult PBHEP(string PC,string FC)
{
/some data calculations
Output output = new Output() { CIR = CIR_, Recharge = Recharge_, GW_Withdrawal= GW_Withdrawal_ };
return Json(output);
}
JS
self.submit_conditions = function () {
var PC_data = ko.toJSON(self.present_conditions());
var FC_data = ko.toJSON(self.future_conditions());
$.post("/Home/PBHEP", { "PC": PC_data, "FC": FC_data }, function (data) { alert((data));},'json');
}
After this when the controller returns the Json data "output" I see that in my dev tools I have Response from the POST in my network as {"CIR":8.31779,"Recharge":4.28381,"GW_Withdrawal":32.27184}
How Do I het this in my JS and later use it to bind as text on my UI.
Thank you in Advance!
Say your model has these output elements defined some where...
function vm(){
var self = this;
self.CIR = ko.observable();
self.Recharge = ko.observable();
self.GW_Withdrawl = ko.observable();
//remaining stuff
self.submit_conditions = function(){
//usual stuff
$.post(svcUrl, data, function(data){
self.CIR(data.CIR);
self.Recharge(data.Recharge);
self.GW_Withdrawl(data.GW_Withdrawl);
});
};
}
ko.applyBindings(new vm());
Now bind this as you would normally, for e.g.
<label>Recharge:</label><label data-bind="text: Recharge"></label>
i guess if you are using ViewModels, you can create the same viewmodel on knockout and asp.net mvc, and make bind of the data normally.
On your controller:
var model = new YourViewModel();
// fill data to return
return Json(model);
On return to javascript you can use knockout mapping plugin

How do I use AJAX to upload files to ASP.NET?

I am trying to upload files using AJAX to ASP.NET. I have this Javascript:
var xhr = new XMLHttpRequest();
for (var i = 0; i < files.length; i++) {
xhr.open('post', '/File/Upload', true);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
var formData = new FormData();
formData.append("_file", files[i]);
xhr.send(files[i]);
}
files is an Array()
Then I try to access the post file in C# code, but the value is always null. How can I resolve this issue?
// Method 1, Result: file = null
HttpPostedFileBase file = Request.Files["_file"];
// Method 2, Result: postedFile.Count = 0
HttpFileCollectionBase postedFile = Request.Files;
Assuming you have the following form containing the file input field:
<form action="/home/index" method="post" enctype="multipart/form-data" onsubmit="return handleSubmit(this);">
<input type="file" id="_file" name="_file" multiple="multiple" />
<button type="submit">OK</button>
</form>
you could try the following function:
function handleSubmit(form) {
if (!FormData) {
alert('Sorry, your browser doesn\'t support the File API => falling back to normal form submit');
return true;
}
var fd = new FormData();
var file = document.getElementById('_file');
for (var i = 0; i < file.files.length; i++) {
fd.append('_file', file.files[i]);
}
var xhr = new XMLHttpRequest();
xhr.open(form.method, form.action, true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
};
xhr.send(fd);
return false;
}
Now on the server you should be able to retrieve the file using Request.Files.
You can also use jQuery
you have 2 functions
Ajax : http://api.jquery.com/jQuery.ajax/
Load(shortcut, calls ajax) : http://api.jquery.com/load/
Examples : http://www.w3schools.com/jquery/jquery_ajax.asp
Edited : 2012-10-04 16:31
Reason : Got the following Comment :
Hm unless I don't understand, I don't want to load informations of the server, I want to get the informations I have in my JS code on my server. I already have the informations to send in the files Array(). – Elfayer
What you do is you make a AJAX call to the server like to an webservice.
Here is an example
var value = 1;
var handlerUrl = [YOUR WEBSERVICE URL];
//Do the Ajax Call
jQuery.ajax({
url: handlerUrl,
data: { "params[]": [value] },
type: 'POST',
success: function (data)
{
alert("succes");
},
error: function (jxhr, msg, err)
{
alert("error");
}
});
in the data parameter you give your data.
I send it here in the form of an array but you can send it also like 1 parameter.
How do you access it in well in my case a generic handler.
//Split the parameters and set in Array of Strings
var param = context.Request.Form[0].Split(',');
var value = param[0];
Like I said I give it in the form of an array so I only have one parameter
and then I split it. But if you would give it like single properties then you
could get it like :
context.Request.Form[0]
context.Request.Form[1]
context.Request.Form[2]
context.Request.Form[3]
context.Request.Form[4]

Categories

Resources