I asked a question to fill in the model data on the client, into arrays.
Add items to JSON objects
Now my problem is how to post it to the controller. I have tried this:
public ActionResult ItemRequest (Model1 model)
{
////
}
but it never gets there.
I'm trying with an AJAX request to send it:
function sendRequest() {
jsonData.items = itemArray;
$.ajax({
url: '#Url.Action("ItemRequest")',
type: 'POST',
data: JSON.stringify(jsonData),
///// and so on
}
But the action result is never invoked. I can drop the 'JSON.stringify' and it makes no difference. Any ideas on how to post this object to the controller?
If I make a psuedo model in JS it works fine, but I don't want to have to make this model, I'd rather use the model passed to the page.
function itemModel () {
var self = this;
this.itemNumber = $("#itemNumberId").val();
/// etc.
self.items = [];
}
function itemsModel () {
var self = this;
this.itemNumber = $("#itemNumberId").val();
/// etc
}
then
var itemCount = 0;
function addItem() {
var newItem = new itemModel();
newItem.items[itemCount] = newItem;
/// etc
}
This works fine.
I send the array itemModel the same way with a JSON.stringify directly into the controller method
public ActionResult ItemRequest(ItemModel model)
We are using this to send Data to API controller Methods on our internal test sides:
It's probably not the prettiest solution, but it can be used on any page.
What data should be sent:
$("#btnSend").click(function () {call("controller/method", {ParamName: $("#field").val()}); });
To send the data to a controller:
$(document).ready(function () {
var call = function (method, requestData, resultHandler) {
var url = method.substring(0, 1) == "/api/" + method;
$.ajax({
url: url,
dataType: 'json',
data: JSON.stringify(requestData),
type: 'POST',
contentType: 'application/json',
success: function (data) {
var isSuccess = data.Status == "success";
$("#jsonResponse").val(FormatJSON(data));
if (isSuccess && jQuery.isFunction(resultHandler)) {
resultHandler(data);
}
}
});
};
Related
I debugged the JS and Ajax code with console.log. I can see that what I entered into the textbox, is displayed in the console. However, when these values are supposed to send to the controller, they are empty or null when I hover over the tbl_stuff List. Not sure where I am making a mistake.
Here is the JS:
$("body").on("click", "#btnSave", function () {
var table = $("table tbody");
var array= new Array();
table.find('tr').each(function (i) {
var $tds = $(this).find('td'),
Amount = $(this).find('.val').val();
valuestoupdate = { Amount: amount };
array.push(valuestoupdate);
});
$.ajax({
type: "POST",
url: "#Url.Action("StuffAction","Home")",
data: JSON.stringify(array),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (r) {
alert(r + " record(s) saved.");
}
});
Here is the controller action:
public JsonResult StuffAction(List<tbl_Stuff> stuffs)
{
int getID = (int)TempData["id"];
TempData.Keep();
var GetData = _context.tbl_Detail.Where(x => x.detId == getID).FirstOrDefault();
if (GetData != null)
{
foreach (tbl_Stuff moreThings in stuffs)
{
tbl_Stuff stuff = new tbl_Stuff();
stuff.Amount = moreThings.Amount;
_context.tbl_Stuff.Add(stuff);
}
}
int insertedRecords = _context.SaveChanges();
return Json(insertedRecords);
}
I get an error saying that moreThings.Amount is empty. But during debugging, the JS code gets the value entered into the textbox.
The .Net routing can't match the request
change the action signature to public JsonResult StuffAction(List< string > stuffs)
or in your ajax call change the array to an array of objects matching the properties of tbl_Stuff
I have a javascript function that is creating a model that includes an array of objects and sending that data to my MVC controller with an AJAX POST request. For some reason, it seems that there is a limit on the size of that array that can be passed to the controller though, which though experimentation, seems to be between 450 and 500 objects in my case. Once it's larger than that threshold, the controller will just receive a null value. Is there some configuration or workaround that can be done to remove or work around this limitation?
I've already tried several web.config based "solutions" that a lot of people have proposed on similar SO questions to no avail (I think those may be applicable only for .Net Framework's version of ASP.NET, not .NET Core).
Javascript:
var i = 0;
$("#SupplierNumber option").each(function () {
var supplierNumber = {};
supplierNumber.Value = $(this).val();
supplierNumber.text = $(this).val();
supplierNumbers.push(supplierNumber);
//Below limits max size for testing
i = i + 1;
if (i > 450) {
return false;
}
});
//Other non-array values gathered here
var model = {
"SupplierNumbers": supplierNumbers,
//... other non-array values added to model
}
$.ajax({
type: "POST",
url: "/Administration/TestPost",
data: model,
dataType: "json",
success: function (data) {
alert("Finished");
}
});
Controller:
[HttpPost]
public async Task<IActionResult> TestPost(TestViewModel model)
{
//model is null here when array is > 500 in size
return Json(new { success = true });
}
Try this before you use JSON.stringify!
I had exactly the same problem. All I needed to do was the following:
In my Startup.cs I added the following lines in ConfigureServices:
services.Configure<FormOptions>(options =>
{
options.ValueCountLimit = int.MaxValue;
options.ValueLengthLimit = int.MaxValue;
});
Here is two solutions:
First demo,use json type data,we usually use this way to pass array in ajax(pass json type data,need to use contentType: 'application/json' in ajax and use [FromBody] in action):
IndexViewModel:
public class IndexViewModel
{
public int Id { get; set; }
public string Name { get; set; }
}
Controller:
[HttpGet]
public IActionResult TestAjax() {
return View();
}
[HttpPost]
public IActionResult TestAjaxWithJsonData([FromBody]List<IndexViewModel> l) {
return Ok();
}
View:
<button onclick="postdata1()">submit(jsondata)</button>
#section scripts{
<script type="text/javascript">
function postdata1() {
var a = [];
for (var i = 0; i < 500; i++) {
var indexViewModel = {};
indexViewModel.Id = i;
indexViewModel.Name = "name" + i;
a.push(indexViewModel);
}
var data = JSON.stringify(a);
$.ajax({
type: "POST",
url: 'TestAjaxWithJsonData',
data: data,
contentType: 'application/json'
}).done(function (data) {
});
}
</script>
}
result:
Second demo,use FormData:
Controller:
[HttpPost]
public IActionResult TestAjaxWithFormdata(List<IndexViewModel> l)
{
return Ok();
}
View:
<button onclick="postdata2()">submit(formdata)</button>
#section scripts{
<script type="text/javascript">
function postdata2() {
var formdata = new FormData();
for (var i = 0; i < 500; i++) {
formdata.append("l[" + i + "].Id", i);
formdata.append("l[" + i + "].Name", "name" + i);
}
$.ajax({
type: "POST",
url: 'TestAjaxWithFormdata',
cache: false,
contentType: false,
processData: false,
data: formdata,
}).done(function (data) {
});
}
</script>
}
result:
I dont know what is the exact problem but you can try this solution. Try to pass data as a sting into action after that Deserialize tht string to object.
var model = {
"SupplierNumbers": supplierNumbers,
//... other non-array values added to model
}
$.ajax({
type: "POST",
url: "/Administration/TestPost",
data: {"data":JSON.stringify(model)},
dataType: "json",
success: function (data) {
alert("Finished");
}
});
on controller side you can Deserilize this string to model.
[HttpPost]
public async Task<IActionResult> TestPost(string data)
{
TestViewModel model=DeserializeObject<TestViewModel>(data);
return Json(new { success = true });
}
We need to set the value count limit and length.
Please Add below code in startup.cs --- It is working for me
services.AddMvc(options =>
{
options.MaxModelBindingCollectionSize = 100000;
});
services.Configure<FormOptions>(options =>
{
options.ValueCountLimit = int.MaxValue;
options.ValueLengthLimit = int.MaxValue;
options.MultipartHeadersLengthLimit = int.MaxValue;
});
After some more searching, I was able to figure out that this is a configuration issue within ASP.NET Core. By default, the max number of values in a complex model that can be bound is 1024. Adding the option below in the ConfigureServices method of the Startup class will allow you to increase this limit to whatever you need (MSDN).
services.AddMvc(options =>
{
options.MaxModelBindingCollectionSize = 100000;
})
Also, something else that I found that people might find useful when facing this problem, but with a form submit action, is the below option that goes in the same method mentioned above (source).
services.Configure<FormOptions>(options => options.ValueCountLimit = 100000);
I'm creating mvc 4 application where I call a function in controller from a js file using ajax.
When I call the function from ajax, its calling the respective function properly. But neither success nor error function is not firing . Could someone help me out to correct my mistake?
I would like to read the data from database convert it to json format and write it into a .js file and thereafter success function to be fired off. Help me to solve this. Thanks in advance.
Here is my Code.
$.ajax({
//url: '#Url.Action("getJsonData","Home")',
url: "Home/getJsonHugeData1",
//data: "{}",
type: "GET",
//contentType: 'application/json',
//dataType: "json",
success: function () {
alert();
alert('success getJsonHugeData');
loaddata(data);
},
error:function(){
alert('error');
}
});
Controller:
public JsonResult getJsonHugeData()
{
var users = GetUsersHugeData();
string json = "var dataSource=";
json += JsonConvert.SerializeObject(users.ToArray());
System.IO.File.WriteAllText(Server.MapPath("/Scripts/NewData.js"), json);
return Json(users, JsonRequestBehavior.AllowGet);
}
private List<UserModel> GetUsersHugeData()
{
var usersList = new List<UserModel>();
UserModel user;
List<dummyData> data = new List<dummyData>();
using (Database1Entities dataEntity = new Database1Entities())
{
data = dataEntity.dummyDatas.ToList();
}
for (int i = 0; i < data.Count; i++)
{
user = new UserModel
{
ID = data[i].Id,
ProductName = data[i].ProductName,
Revenue = data[i].Revenue,
InYear = data[i].InYear.Year
};
usersList.Add(user);
}
}
I believe your browser will block the file downloaded via ajax, this is because JavaScript cannot interact with disk. If you want to get this working, you will have to do so using a form post.
#using (Html.BeginForm("Action", "Controller", FormMethod.Post, new { id = "DownloadForm" }))
{
... form data would be here if you had any...
<button type="submit">Download</button>
}
You would then return a FileStreamResult with the contents of the file to be downloaded.
public ActionResult Action(FormModel model)
{
// Do work to get data for file and then return your file result to the browser.
return new FileStreamResult(new MemoryStream(fileData), "text/csv") // set the document type that is valid for your file
{
FileDownloadName = "users.csv"
};
}
I ran all of your code except for the following since you didn't provide the UserModel and dummydata classes in your question:
private List<UserModel> GetUsersHugeData()
{
var usersList = new List<UserModel>();
UserModel user;
List<dummyData> data = new List<dummyData>();
using (Database1Entities dataEntity = new Database1Entities())
{
data = dataEntity.dummyDatas.ToList();
}
for (int i = 0; i < data.Count; i++)
{
user = new UserModel
{
ID = data[i].Id,
ProductName = data[i].ProductName,
Revenue = data[i].Revenue,
InYear = data[i].InYear.Year
};
usersList.Add(user);
}
}
The end result was that you had a typo in your ajax 'url' parameter. Also, if you are going to check for errors, set your function to
function(jqxhr, status, error) {
alert(error);
}
to check the error being thrown.
I'm trying to add a search form to my page that updates the Kendo Grid. How should I send the Ajax call, so the ASP.NET MVC Model Binder be able to work?
This is my Ajax call:
var grid = $("#SearchSheetHeads").data('kendoGrid');
var data = $("#SearchSheet").serialize();
grid.dataSource.transport.options.read.url = "#Url.Action("SearchHeaderRead", "Sheet")";
grid.dataSource.transport.options.read.data = data;
grid.dataSource.transport.options.read.dataType = 'json';
grid.dataSource.transport.options.read.contentType = "application/json";
grid.dataSource.transport.options.read.type = "POST";
grid.dataSource.fetch();
I've also tried it by stringify method and removing contentType.
And this is my Action signature:
public ActionResult SearchHeaderRead([DataSourceRequest] DataSourceRequest request, SearchSheetHeaderViewModel model)
And the request looks like this:
Can't test it at the moment, but try something like this:
var grid = $("#SearchSheetHeads").data('kendoGrid');
var data = $("#SearchSheet").serialize();
$.ajax(
{
type: 'POST',
url: '#Url.Action("SearchHeaderRead", "Sheet")',
dataType: 'json',
data: { model: data },
success: function (result) {
grid.dataSource.data(result.Data);
}
});
data: { model: data } is probably the important part for you.
Can you change the second line as given below and try it out
var data = $("#SearchSheetHeads").data('kendoGrid').dataSource.data();
Hello Fellow Developers,
I have a SSN textbox that onblur calls a function which does an ajax request to a Web Method to decide if an employee has been previously hired.
The Web Method returns a TermedEmployee Object to the success callback, but I'm unsure how to parse the object.
$('#<%=FormView1.FindControl("SSNField").ClientID%>').blur(hideValue);
hideValue = function (ev) {
var $this = $(this);
$this.data('value', $this.val());
$('#<%=FormView1.FindControl("hiddenSSN").ClientID%>').val($this.val());
var data2Send = '{"SSN": ' + $this.val() + ' }';
$.ajax({
type: "POST",
url: "AuthforHire.aspx/EmployeeisRehire",
data: data2Send,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
var obj = JSON.stringify(result.d);
if (obj.IsTermed) {
$('#%=RadWindowRehire.ContentContainer.FindControl("TextBoxTermID").ClientID%>').val(arg.d);
var wndWidth = 900;
var wndHeight = 500;
var wnd = window.radopen(null, "RadWindowRehire");
}
},
error: function (xhr) {
alert('Form update failed. '); //error occurred
}
});
Below is a minified version of my webMethod, which works correctly
[System.Web.Services.WebMethod]
public static TermedEmployee EmployeeisRehire(string SSN)
{
TermedEmployee termedEmp = new TermedEmployee();
// Db call to get necessary data.
termedEmp.Name = dr["name"];
termedEmp.TermDate = Convert.ToDateTime(dr["TermDate"].ToString());
......
}
So How Can I extract Name, TermDate,StartDate, ReasonforTerm, etc from the object returned to the callback function?
Thank you in advance!
The first line in your success callback is:
var obj = JSON.stringify(result.d);
Which is trying to serialize what ASP.Net will already have serialized for you.
Change this to:
var obj = result.d;
And you will then have access to obj.Name, obj.TermDate and all the other properties by name.