ajax post request with multiple paramaters - javascript

My controller:
[HttpPost]
public IActionResult UserRoleChanged(string roleName,string userName)
{
var a = roleName;
var b = userName;
return RedirectToAction("UserManager");
}
Script in view:
if (window.confirm('Are you sure that you want to change role?')) {
jQuery.ajax({
type: "POST",
url: "#Url.Action("UserRoleChanged", "DashBoard")",
dataType: 'json',
data: { 'roleName': this.text, 'userName': 'SomeName'},
cache: false,
success: function (data){
window.location.href = data;
},
failure: function (data) {
}
})};
When I run script above UserRoleChanged action does not invoke. If I try to remove userName variable from data in ajax then UserRoleChanged action method invokes without any problem. How can i pass multiple data to my controller? What is wrong with my code?

Remove the dataType: 'json' from the ajax, and try again. As you are trying to get the values on server side as normal variable, so dataType: 'json' is not required here.

You can create a model with same properties and pass it as a parameter. Its a good practice.
Looks like this.
public class User
{
public string RoleName { get; set; }
public string UserName { get; set; }
}
And the json looks like this example
{
"RoleName" : "somename",
"UserName" : "somename"
}

Related

How to use returned JSON.stringify array in C#

I have JavaScript function where I have an array and when I send that array to my C# controller, it should be in such way way that my controller should understand.
JavaScript function
function Check(obj) {
var eArray = $('..').map(function () {
return this.getAttribute("value");
}).get();
$.ajax({
url: "/Order/Check",
data: { GUID: JSON.stringify(eArray) },
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
});
My Controller
public ActionResult Check()
{
string guid = HttpContext.Request["GUID"];
var result = //send the result
return Json(result, JsonRequestBehavior.AllowGet);
}
I would like to get an array in my controller.
I'm not really sure what you are trying to achieve. From what I saw in your comments, you are sending an array of GUIDs to your controller, but that results in it being send as a string, and you want an array.
I tested your code and modified it a bit:
$.ajax({
type: "POST",
url: /your url/,
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
data: JSON.stringify({GUID: eArray}),
});
Where eArray is let eArray = ['D5FAF478-CF43-40E1-BE79-BB90147A3194', '2E79B23E-D264-4901-A065-7E0B7032A5D8']
Then, in my controller, I receive it as a model:
public class Dto
{
public string[] GUID { get; set; }
}
Then, you can use it like this:
[HttpPost]
public IActionResult Post([FromBody] Dto dto)
{
var listOfGuids = dto.GUID.Select(guid => Guid.Parse(guid)).ToList();
var result = Services.CheckRecords(listOfGuids);
...
}
It seems that unfortunately the standard JavaScriptSerializer.Deserialize doesn't handle Guid type.
Therefore, I would go with something like
public ActionResult Check()
{
string guidsStr = HttpContext.Request["GUID"];
var guids = new List<Guid>();
foreach (var guid in Regex.Replace(guidsStr, "[\\[\\\"\\]]", "").Split(",")) {
Guid newGuid;
if (Guid.TryParse(guid, out newGuid)) {
guids.Add(newGuid);
} else {
// handle invalid guide value
}
}
// guids list now contains parsed Guid objects
// do here what you need to do with the list of guids
return Json(result, JsonRequestBehavior.AllowGet);
}
Please let me know if this helps.

Why does my MVC Action not see my ajax passed object

Ajax call works but the passed object is empty.
Its a simple setup of passing a cart object to a controller action.
The call happens but man is empty when it hits the Action.
The paylod being sent(in chrome) is:
{"man":"testtext2"}
The response is:
{"man":null}
.net cartitem:
public class Cartitem
{
public string man { get; set; }
}
Javascript cartitem:
class cartitem {
constructor( _man, ) {
this.man = _man;
}
}
Controller Action:
[HttpPost]
public ActionResult AddToCart(Cartitem myCartitem)
{
//ERROR: cartitem values are coming in empty
return Json(myCartitem);
}
Javascript
$(".AddLink").click(function () {
var json = JSON.stringify(c);
var cartitem = JSON.stringify({
'man': 'testtext2',
});
$.ajax({
type: "POST",
url: '#Url.Action("AddToCart", "ShoppingCart")',
contentType: "application/json; charset=utf-8",
dataType: "json",
data: cartitem,
success: function (data) {
alert("Data Back: " + data.man);
}
});
});
Edit
To remove a a lot of red hearings, I've simplified the code so its one single string(man).
The result is the same, MyCartitem is coming in empty.
Add [FromBody] to the Action method e.g
public ActionResult AddToCart([FromBody] Cartitem myCartitem)
{
}
2 days lost!

Why ASP MVC model binder only accept JSON in POST?

Whenever I send 'GET' with JSON.stringify() using AJAX, model value is always accept null;
Why it can only bind 'POST'?
If it is possible, can I use 'GET' and still bind data to model?
Edit: adding Code Example
JS:
$.ajax({
var modelsend = {
itemname: 'shoe',
itemcolor: 'red',
itemsize: '31',
itemvariety: 'SR-31',
}
type: "POST",
url: "#Url.Action("ShowData", "Controller")",
data: JSON.stringify(modelsend),
dataType: "json",
contentType: "application/json",
success: function (data) {
//do something with data
},
error: function (jqXHR, textStatus, errorThrown) {
//show error
}
});
Model:
public class shoemodel
{
public string itemname { get; set; }
public string itemcolor { get; set; }
public string itemsize { get; set; }
public string itemvariety { get; set; }
}
Controller:
public ActionResult ShowData(shoemodel get)
{
List<DataGrid> fetch = func.getdata(get);
return Json(fetch);
}
Perhaps you are forgetting that GET is used for viewing something, without changing it, while POST is used for changing something. And Get can be used to change something only when you use Querystring. Post on the other hand sends form data directly.
HTTP 'GET' method doesn't support a body in the request. The way to send parameters via 'GET' is using the application/x-www-form-urlencoded format appending them in the URL like this.
http://example.com/?key1=value1&key2=value2

Convert JQuery ajax GET to POST

I have this jquery ajax get method on an Index razor in my application:
$.ajax({
url: "#Url.Action("SubmitProjectForPreapproval", "api/Project")",
type: "GET",
cache: false,
data: { projectId: "#ViewContext.RouteData.Values["ProjectId"]" }
}).done(function (data) {
var count = 0;
$.each(data, function (index, value) {
$("#ulMessages").append("<li>" + value + "</li>");
count++;
});
// Assume validation errors if more than 1 message
if (count > 1) {
$("#btnSubmit").removeAttr("disabled");
}
}).fail(function () {
$("#ulMessages").append("<li>An error occurred. Please try again later</li>");
$("#btnSubmit").removeAttr("disabled");
}).always(function () {
$("#imgAjaxLoader").hide();
});
This calls a method within the api/project controller that returns a list of strings:
[HttpGet]
public List<string> SubmitProjectForPreapproval(int projectId)
{ ... }
What I want to do is convert this to an ajax post method. I've been struggling to do just that for the better part of the day. My question is, what is everything that needs to change in order for this to happen? e.g. - change attribute of the method to [HttpPost], and how do I send it the route value? (int pojectId)
Edit: If I do this it works for some reason:
public List<string> SubmitProjectForPreapproval(/*int projectId*/)
{
int projectId = 3308;
...
}
Not sure why it doesn't find my method if I have the parameter there.
I'm not sure how the #Url stuff formats with your system - but just changing it to something like:
$.ajax({
url: "#Url.Action("SubmitProjectForPreapproval", "api/Project")",
type: "POST",
cache: false,
data: { projectId: "#ViewContext.RouteData.Values["ProjectId"]" }
}).done(function (data) {
If you're bit:
#Url.Action("SubmitProjectForPreapproval
..actually has any ?xxx values in it, you also need to add them into the data: { ... }
The problem was indeed the way I was sending the data to the controller action. I fixed it by doing the following:
Alter the ajax method (make use of JSON.stringify):
var projectIdObject = {
ProjectId: "#ViewContext.RouteData.Values["ProjectId"]",
}
$.ajax({
url: "#Url.Action("SubmitProjectForPreapproval", "api/Project")",
type: "POST",
cache: false,
data: JSON.stringify(projectIdObject),
contentType: 'application/json',
}).done(function (data) { ... }
Add a class to take this stringified value:
public class ProjectIdObject
{
public string ProjectId { get; set; }
}
Alter the controller action method to receive this new object and extract the value I want:
[HttpPost]
public List<string> SubmitProjectForPreapproval(ProjectIdObject projectIdObject)
{
int projectId = int.Parse(projectIdObject.ProjectId);
...
}

Why ModelBinding don't work with FormData but works with RequestPayload?

I have been working with Web API and found an interesting observation that I am not able to understand.
controller:
public class UserController: ApiController
{
public void Post(MyViewModel data)
{
//data is null here if pass in FormData but available if its sent through Request Payload
}
}
viewModel
public class MyViewModel{
public long SenderId { get; set; }
public string MessageText { get; set; }
public long[] Receivers { get; set; }
}
JS that is not working
var usr = {};
usr.SenderId = "10";
usr.MessageText = "test message";
usr.Receivers = new Array();
usr.Receivers.push("4");
usr.Receivers.push("5");
usr.Receivers.push("6");
$.ajax(
{
url: '/api/User',
type: 'POST',
data: JSON.stringify(usr),
success: function(response) { debugger; },
error: function(error) {debugger;}
});
JS that is working
var usr = {};
usr.SenderId = "10";
usr.MessageText = "test message";
usr.Receivers = new Array();
usr.Receivers.push("4");
usr.Receivers.push("5");
usr.Receivers.push("6");
$.post( "/api/User", usr)
.done(function( data ) {
debugger;
});
So, if I pass on $.ajax with lots of other configuration like type, contentType, accept etc, it still don't bind model correctly but in case of $.post it works.
Can anybody explain WHY?
Try looking at what gets POSTed when you try it with $.ajax (e.g. with Fiddler of F12 tools of your choice). It can very well be that jQuery passes the data as URL-encoded string rather that as JSON literal.
To fix the issue try specifying dataType together with contentType parameter. Also, I don't think you need JSON.stringify, just pass the JSON literal you're creating:
$.ajax({
data: usr,
dataType: 'json',
contentType: 'application/json',
/* The rest of your configuration. */
});
Here's the TypeScript method that we use in one of our projects (ko.toJSON returns a string representing a JSON literal passed as a method parameter):
public static callApi(url: string, type?: string, data?: any): RSVP.Promise {
return new RSVP.Promise((resolve, reject) => {
$.ajax('/api/' + url, {
type: type || 'get',
data: data != null ? ko.toJSON(data) : null,
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: () => {
resolve.apply(this, arguments);
},
error: () => {
reject.apply(this, arguments);
}
});
});
}
Hope this helps.

Categories