MVC Controller not parsing Ajax Request Correctly? - asp.net-mvc

I have an MVC .NET 4.5 application using an Ajax request with JSON to hit the MVC controller on server side. The function in the controller looks like this:
[HttpPost]
public void SomeFunction(int int1, List<int> listOfInts, int int2)
{
someOtherFunction(int1, listOfInts, int2);
}
and the ajax request looks like this:
actionData = {
int1: 1,
int2: 2,
listOfInts: list
}
$.ajax({
type: 'POST',
url: actionURL,
data: JSON.stringify(actionData),
traditional: true,
dataType: "json",
contentType: "application/json; charset=utf-8",
success: functionIfSuccessful() },
error: functionIfNotSuccessful() }
});
If I look at the request in Fiddler the JSON ojbect being passed has the format:
int1=1
int2=2
listOfInts=[1,2]
The problem is when the function in the MVC controller is hit, the int1 and int2 properties are set correctly from the request but the listOfInts parameter is empty. I have tried changing it to use a primitive array instead of a List object aswell but that didn't change anything.

Fixed. This issue was being caused by something outside of the code provided. The javascript that was building the list of integers should not have been adding the brackets to the ends. Removed those and it worked like a charm.

Related

Pass array of string from ajax to controller

I need to send an array of string from ajax to a controller and I need to return a file to download. I already look and everywhere says that the same solution, but I can not make it work. I have put a break on the controller, but never entered.
The controllers are in different project.
SOLUTION
PROJECT 1
Controllers
ApiControllers
RenderMvcControllers
SurfaceControllers
ExportController
PROJECT 2
function GetData() {
var stringArray = new Array();
stringArray[0] = "item1";
stringArray[1] = "item2";
stringArray[2] = "item3";
var postData = { values: stringArray };
$.ajax({
type: "POST",
url: "/umbraco/Surface/Export/HandleDownloadFile",
data: postData,
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (data) {
alert();
alert(data.Result);
},
error: function (data) {
alert("Error: " + data.responseText);
},
});
}
class ExportController : SurfaceController
{
[HttpPost]
public ActionResult HandleDownloadFile(string[] productList)
{
return CurrentUmbracoPage();
}
}
If you are sending array values via AJAX, you'll need to ensure that the traditional attribute is set to true (which allows this behavior) and that your parameter is named to match what MVC expects that it should be productList :
// This is important for passing arrays
traditional: true,
Secondly, since you are posting this to a different project, you may need to explicitly define where the project is running by using an absolute URL (as a relative one would be used by default and would likely point to your current project) :
url: "{your-other-project-url}/umbraco/Surface/Export/HandleDownloadFile",
Finally, you may want to try removing the contentType attribute as that is used to define what the server expects to receive in it's response. Since you aren't expecting JSON back (and instead are expecting a file), you could consider removing it.
$.ajax({
type: "POST",
// Consider making the URL absolute (as it will be relative by default)
url: "/umbraco/Surface/Export/HandleDownloadFile",
// This is important for passing arrays
traditional: true,
// Make sure that productList is used as it matches what your Controller expects
data: { productList: stringArray }.
dataType: "json",
success: function (data) {
alert(data.Result);
},
error: function (data) {
alert("Error: " + data.responseText);
},
});

Ajax Request issue with ASP.NET MVC 4 Area

Today i discovered something weird, i have regular asp.net mvc 4 project with no such ajax (just post, get). so today i need ajax request, i did an ajax action with jquery in controller and it didn't work out. Here is my code
Areas/Admin/Controllers/BannersController
public JsonResult SaveOrder(string model)
{
bool result = false;
if (!string.IsNullOrEmpty(model))
{
var list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<int>>(model);
result = repository.SaveOrder(list);
}
return Json(result, JsonRequestBehavior.AllowGet);
}
View side (Its in area too)
$(document).ready(function () {
$("#saveOrder").click(function () {
var data = JSON.stringify($("#list_banners").nestable('serialize'));
$.ajax({
url: '#Url.Action("SaveOrder", "Banners", new { area = "Admin" })',
data: { model: data },
success: function (result) {
if (result) {
toastr.success('Kaydedildi.');
}
else {
toastr.error('kaydedilemedi.');
}
},
error: function (e) {
console.log(e);
}
});
});
});
i've already tried everything i know, which is $.post, $.get, ajax options, trying request from out of area etc.. just request can't reach action
and here is the errors ,
http://prntscr.com/297nye
error object
http://prntscr.com/297o3x
Try by specifying the data format (json) you wand to post to server like and Also change the way you pass data object in JSON like this :
var data = $("#list_banners").nestable('serialize');
$.ajax({
url: '#Url.Action("SaveOrder", "Banners", new { area = "Admin" })',
data: JSON.stringify({ model: data }),
dataType: 'json',
contentType: "application/json",
...
I had same issue, but after spending too much time, got solution for that. If your request is going to your specified controller, then check your response. There must be some problem in your response. In my case, response was not properly converted to JSON, then i tried with passing some values of response object from controller using select function, and got what i needed.

what is Request.InputStream and when to use it?

Question is really simple. What is Request.InputStream and when to use it. Is it always used to read entire html body sent in the post request or only some parameters sent in it? Why should i not send data as a parameter to my server side code by passing it in the Ajax request?
In the example i can either pass the parameter in the data: or i can read the parameter in the Request.InputStream. When should i use which one?
Example:
In controller:
public ActionResult GetSomeData(string someData)
{
Request.InputStream.Position = 0;
System.IO.StreamReader str = new System.IO.StreamReader(Request.InputStream);
string sBuf = str.ReadToEnd();
return Json("something");
}
Ajax Request:
$.ajax({
type: "POST",
url: "Home/GetSomeData",
data: "{someData:'Hello'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
alert(msg);
// Insert the returned HTML into the <div>.
$('#dvResult').html(msg);
}
});
Request.InputStream allows you to access the raw request data. If this data is formatted using some standard format such as application/x-www-form-urlencoded or multipart/form-data or some other format that the default model binder understands you do not need to use Request.InputStream. ASP.NET will parse the request values and you will be able to access them directly using Request[...]. Of course in ASP.NET MVC you don't even need to use Request[...] because you can define a view model which your controller action will take as parameter and leave the model binder assign its properties from the request.
There are cases though when you might want to access the raw request stream. For example you have invented some custom protocol and the client sends some custom formatted data in the request stream. Those cases are very rare since inventing custom protocols is not very common.
Now back to your question. In your case you could define a view model:
public class MyViewModel
{
public string SomeData { get; set; }
}
which your controller action will take as argument:
public ActionResult GetSomeData(MyViewModel model)
{
// model.SomeData will contain the Hello string that the client sent
return Json("something");
}
and on the client I would recommend you using the JSON.stringify method which is natively built into modern browsers to JSON serialize the request javascript literal into a JSON string instead of manually writing the JSON as you did:
$.ajax({
type: 'POST',
url: 'Home/GetSomeData',
data: JSON.stringify({ someData: 'Hello' }),
contentType: 'application/json; charset=utf-8',
success: function (msg) {
alert(msg);
// Insert the returned HTML into the <div>.
$('#dvResult').html(msg);
}
});

asp.net mvc 3 json values not recieving at controller

the problem is that i am not able to recieve any value in the controller . what could be wrong? the code is here.
$('#save').click(function () {
var UserLoginViewModel = { UserName: $('vcr_UserName').val(),
Password: $('vcr_Password').val()
};
$.ajax({
url: "/User/Login",
data: JSON.stringify(UserLoginViewModel),
contenttype: "application/json; charset=utf-8",
success: function (mydata) {
$("#message").html("Login");
},
error: function () {
$("#message").html("error");
},
type: "POST",
datatype: "json"
});
return false;
});
});
[HttpPost]
public ActionResult Login(UserLoginViewModel UserLoginViewModel)
{
}
As you're using MVC3 - you should be able to take advantage of the built in JSON model binding.
Your code example has a couple of typos: contentType and dataType are lowercase...(they should have an uppercase "T")
jQuery ajax docs
After you POST up the correct contentType/dataType, MVC should automatically bind your object to the posted JSON.
You're going to need an action filter or similar to intercept the json from the post body.
Here's a starter
Provider Factory
but here is the article that sorted this for me On Haacked
It is good if you know the type you are deserialising into up front, but if you need polymorphism you'll end up using these ideas in an action filter.

How would you pass objects with MVC and jQuery AJAX?

I am finally experimenting and trying to learn MVC after years of asp.net.
I am used to using asp.net AJAX PageMethods where you can pass an object that automagically gets parsed to whatever type the parameter is in that method.
Javascript:
PageMethods.AddPerson({First:"John",Last:"Doe"});
Code-Behind:
[WebMethod]
public static Result AddPerson(Person objPerson)
{
return Person.Save();
}
How would do this using MVC and jQuery?
Did just have to send strings and parse the json to object?
That depends on how complex your form data is going to be. Let's use a jQuery example:
$.ajax({
url: '\Persons\AddPerson', // PersonsController, AddPerson Action
data: { First: "John", Last: "Doe" },
type: 'POST',
success: function(data, status)
{
alert('Method called successfully!');
}
});
So we post two pieces of data. If the Person class has two properties called 'First' and 'Last', then the default ASP.NET MVC Model Binder should have no problems putting this form data into those properties (everything else will be defaulted).
Of course, you could always make a custom model binder for the Person type, and then you can take whatever form values you want and put them into any property at all, or call some other kind of logic.
I have a post that covers AJAX calls to ASP.NET MVC action methods. It covers the following combinations:
HTTP GET, POST
jQuery methods $.get, $.getJSON, $.post
Sending parameters to the action methods
Returning parameters (strings and JSON) from the action methods
Posting form data
Loading a MVC partial view via AJAX
AJAX calls to ASP.NET MVC action methods using jQuery
When you POST a form via ajax to an action method on your controller, the ModelBinder architecture kicks in to parse the posted form values into business objects for you. You can leverage modelbinding in a few different ways.
public ActionResult MyAction(MyObject obj)
{
}
In the above example, the modelbinder implicitly tries to create a MyObject from the information it received in the request.
public ActionResult MyAction(FormCollection stuff)
{
MyObject obj = new MyObject();
TryUpdateModel(obj);
}
Here we are explicitly trying to bind the posted form data to an object that we created. The ModelBinder will try to match the posted values to the properties of the object.
In either of these cases, you can query the ModelState object to see if there were any errors that occurred during translation of the posted values to the object.
For an introduction to model binding, see here.
For advanced modelbinding to lists and dictionaries, see Phil Haack's post.
You could do something like this:
var person = {};
person["First"] = $("#FirstName").val();
person["Last"] = $("#LastName").val();
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/Admin/AddPerson",
data: JSON.stringify(person),
dataType: "json",
success: function(result) {
},
error: function(result) {
}
});
and then on your admin controller:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddRelease(Person p)
{
// Code to add person
}
The JSON.stringify method is available from here. You could also use a model rather than the Person object as a parameter that way you could handle all of your validation.
I guess I am a cheater and do the following:
$("#ProgressDialog").dialog({
autoOpen: false,
draggable: false,
modal: true,
resizable: false,
title: "Loading",
closeOnEscape: false//,
// open: function () { $(".ui-dialog-titlebar-close").hide(); } // Hide close button
});
$("form").live("submit", function (event) {
event.preventDefault();
var form = $(this);
$("#ProgressDialog").dialog("open");
$.ajax({
url: form.attr('action'),
type: "POST",
data: form.serialize(),//USE THIS to autoserialize!
success: function (data) {
$("#dialog").dialog({height:0});
},
error: function (jqXhr, textStatus, errorThrown) {
alert("Error '" + jqXhr.status + "' (textStatus: '" + textStatus + "', errorThrown: '" + errorThrown + "')");
},
complete: function () {
$("#ProgressDialog").dialog("close");
}
});
});
});
<div id="ProgressDialog" style="text-align: center; padding: 50px;">
<img src="#Url.Content("~/Content/ajax-loader.gif")" width="128" height="15" alt="Loading" />
</div>

Resources