Why ASP MVC model binder only accept JSON in POST? - javascript

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

Related

Get data from ajax to mvc action

I want to send array of objects from ajax call to controller action.
On back-end side I have
container classes:
public class MyContainer
{
public string Id { get; set; }
public Filter[] Filters { get; set; }
}
public class Filter
{
public string Name { get; set; }
public string[] Values { get; set; }
}
and action:
public ActionResult MyAction(MyContainer container)
{
var id = container.Id;
foreach(Filter filter in container.Filters)
{
//Do something
}
}
On front-end side I have
$(document).on('click', 'mySelector', function (event) {
//Create first object
var firstIds = {};
firstIds.Name = "Custom Name 1";
firstIds.Values = GetIds('param1'); //this return an array of strings
//Create second object
var secondIds = {};
secondIds.Name = "Custome Name 2";
secondIds.Values = GetIds('param2'); //another array
var Id = $(this).attr('id'); //id of element
//Add objects to array
var filters = [];
filters.push(firstIds);
filters.push(secondIds);
$.ajax({
method: "GET",
url: baseUrl+"/MyAction",
//traditional: true, //I tried with and without that parameter
data:
{
Id: Id,
Filters: filters
},
contentType: 'application/json',
success: function (res) {
alert('success')
}
});
});
So if I use it like in example on top, container-object in action have Id value and have array of 2 elements in Filters, however both of them have Name and Values as null.
With traditional set to True, I got container.Id set but container.Filters = null.
Any suggestion?
Thank you.
Use a POST request in combination with JSON.stringify() method.
C#
[HttpPost]
public ActionResult MyAction(MyContainer container)
{
var id = container.Id;
foreach(Filter filter in container.Filters)
{
//Do something
}
}
JQUERY
$.ajax({
method: "POST",
url: baseUrl+"/MyAction",
data:JSON.stringify(
{
Id: Id,
Filters: filters
}),
contentType: 'application/json',
success: function (res) {
alert('success')
}
});
Why do you need JSON.stringify() method ?
contentType is the type of data you're sending, so application/json; The default is application/x-www-form-urlencoded; charset=UTF-8.
If you use application/json, you have to use JSON.stringify() in order to send JSON object.
JSON.stringify() turns a javascript object to json text and stores it in a string.
You should use POST method instead of GET in ajax request. As you are posting data. and also your action should have [HttpPost] decorator.
$.ajax({
method: "POST",
url: baseUrl+"/MyAction",
data:
{
Id: Id,
Filters: filters
},
contentType: 'application/json',
success: function (res) {
alert('success')
}
});
Though its an old post, adding my bit to it. I would ask if you are returning a view from the action or not? here it seems like you are not returning a view but just wanting to update some data.
But in case you wanted to return a view, for e.g like showing some product info, then you would just pass the selected product's id to the action method, retrieve the related product information and then pass on this data as a model to the view, and then return the complete view. In this case you don't need a separate ajax call to process the data, instead just do it when you are requesting for the view itself (through the action method).
On the contrary if you already have the view rendered and are just wanting to change the data inside the current view then just resort to an ajax call to get the data without any view.
Hope it helps

ajax post request with multiple paramaters

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"
}

Web Api C# .net params POST

I'm trying to send a list of products for my web api in C# via JavaScript but my API doesn't accepts the products. How do I should pass it?
This is my model
public class ProductModels
{
public int productId { get; set; }
public string description { get; set; }
public int quantity { get; set; }
public decimal amount { get; set; }
}
and my API endpoint
[Route("api/pag_seguro/transactions/credit_card")]
public IHttpActionResult DoTransactionWithCreditCard(ProductModels[] products, string senderHash, string cardHash)
in Javascript I'm trying to send it like this
data.products = [{ "productId": 1, "description": "tupperware", "quantity": 1, "amount": 29.80 }];
$.ajax({
type: 'POST',
url: url + '/api/pag_seguro/transactions/credit_card?cardHash=' + cardHash + '&senderHash=' + senderHash,
data: data,
success: function (response) {
console.log(response);
},
dataType: 'json',
async: false
});
and still about this endpoint... how do I send the senderHash and cardHash as POST parameters so that than doesn't appears in web url?
Thank you all
You need to set the content type in the request as
contentType:"application/json"
Also, use JSON.stringify to convert the data to JSON format when you send.
Try this code:
$.ajax({
type: 'POST',
url: url + '/api/pag_seguro/transactions/credit_card?cardHash=' + cardHash + '&senderHash=' + senderHash,
data: JSON.stringify(data),
contentType: "application/json",
success: function (response) {
console.log(response);
},
dataType: 'json',
async: false
});
try this
public IHttpActionResult DoTransactionWithCreditCard([FromUri] SiteInfo, siteInfoProductModels[] products)
and your siteinfo model is
public class SiteInfo
{
public string senderHash { get; set; }
public string cardHash { get; set; }
}
finally remove your route from action header and add new route in webapiconfig.cs like this (and change js file set params liek this /param1/param1 )
config.Routes.MapHttpRoute(
name: "HashRoute",
routeTemplate: "api/{controller}/{action}/{senderHash}/{cardHash}"
);

Pass object from Javascript to MVC Controller

I have tried many different solutions from other people but have had no luck with either, and I can't seem to be able to debug javascript.
These are some of the variables just so you can see the types. All variables contain data
My view is as follows:
var startTime = new Date();
var images = #Html.Raw(Json.Encode(ViewBag.Images));
var sound = #Html.Raw(Json.Encode(ViewBag.Tones));
var gamePlayed = #Html.Raw(Json.Encode(ViewBag.GamePlayedId));
function SaveGameData()
{
$.ajax({
type: 'POST',
url: '#Url.Action("Play", "Game")',
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: {
GamePlayedId: gamePlayed,
Level: level,
ExpectedImageName: expectedImageArray,
ExpectedToneName: expectedToneArray,
SelectedImageName: selectedImageArray,
SelectedToneName:selectedToneArray,
StartTime: startTimeArray,
EndTime: endTimeArray
},
success: function () {
alert('suc');
},
error: function (args) {
alert('error');
}
});
}
My controller is as follows:
[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Play(SaveGameViewModel model)
{
// Do something
return Json(new { success = true , message ="successful"});
}
My viewmodel is as follows:
public class SaveGameViewModel
{
public int GamePlayedId { get; set; }
public int Level { get; set; }
public List<string> ExpectedImageName { get; set; }
public List<string> ExpectedToneName { get; set; }
public List<string> SelectedImageName { get; set; }
public List<string> SelectedToneName { get; set; }
public List<DateTime> StartTime { get; set; }
public List<DateTime?> EndTime { get; set; }
}
I keep getting the error message from the ajax alert. I have tried many different things and nothing seems to work. I appreciate any help that you can give. Thanks a lot!
There are at least 2 issues with the code your have shown.
First your method is marked with the [ValidateAntiForgeryToken] attribute but you do not pass the token so the method will never be run. Either remove the attribute, or include it using (this assumes your form includes #Html.AntiForgeryToken())
data: {
__RequestVerificationToken: $('[name=__RequestVerificationToken]').val(),
.... // your other properties
},
Second, your posting a javascript object so you need to remove the contentType: "application/json; charset=utf-8", option (or alternatively you need to stringify the data using JSON.stringify()
Side note: Its unclear from you code why you are manually constructing an object to send to the controller. If your form controls are based on SaveGameViewModel and are correctly generated using the strongly typed html helpers, then you can post it all back using
$.ajax({
data: $('form').serialize(),
....
});

MVC5 controller action not called from JSON AJAX Post

I am sending data from from a javascript app to a MVC5 controller, however when data is submitted to the Submit controller action, it is never called. I have some very simple mappers which create the following JSON object:
function mapContactDto(vm)
{
var contactDto = {};
contactDto.firstName = vm.firstName();
contactDto.lastName = vm.lastName();
contactDto.companyName = vm.companyName();
contactDto.emailAddress = vm.emailAddress();
contactDto.phonePrimary = vm.phonePrimary();
contactDto.phoneSecondary = vm.phoneSecondary();
contactDto.address1 = vm.address1();
contactDto.address2 = vm.address2();
contactDto.city = vm.city();
contactDto.postalCode = vm.postalCode();
contactDto.country = vm.country();
return contactDto;
}
function mapCartItems(vm)
{
var cartItemsDto = new Array();
$.each(vm.selectedOptions(), function (index, step, array) {
var sku = step.selection().sku;
if (sku !== "0") {
cartItemsDto.push(sku);
}
});
return cartItemsDto;
}
/* if i dump the object that is sent to the server with `console.log(JSON.stringify(item))` I get:
{
"skus": ["1001","8GB","201"],
"contact": {
"firstName":"Jon",
"lastName":"Doe",
"companyName":"Yup my company",
"emailAddress":"contact#me.com",
"phonePrimary":"012111 231",
"phoneSecondary":"",
"address1":"1 Billing Way",
"address2":"Navigation House",
"city":"London",
"postalCode":"112211",
"country":"GB"
}
}
*/
I then send the data with the following code:
var contactDto = mapContactDto(self.billingVm());
var cartItemsDto = mapCartItems(self.configurationVm());
var req = new XMLHttpRequest();
req.open('HEAD', document.location, false);
req.send(null);
var item = {
skus: mapCartItems(cartItemsVm()),
contact: mapContactDto(billingVm())
};
var url = '/Knockout/Submit';
$.ajax({
cache: false,
url: url,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: item,
type: 'POST',
success: function (data, textStatus, jqXHR) {
},
error: function (data, textStatus, jqXHR) {
}
});
My controller code is below:
public JsonResult Submit(string[] Skus, ContactDto Contact)
{
return Json(new { success = true, message = "Some message" });
}
/* and MVC models are: */
public class ContactDto
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string CompanyName { get; set; }
public string EmailAddress { get; set; }
public string PhonePrimary { get; set; }
public string PhoneSecondary { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
}
I have the following questions please:
Submit is never called however, if I comment out the controller parameters so it becomes Submit() then it is called, why is this?
From the above, it seems like the controller framework cannot match up the parameters - any idea what I am doing wrong please?
How to enable debugging on the MVC controller so I can see what's going on?
Four things you must check using ajax calls,
1. If using javascript object you must stringify the object before passing.
2. The Action verb for the action method should be same as the type of your ajax call if POST then the action method should be decorated by action verb [HttpPost].
3. Always use the relative path for url's in ajax as #Url.Action("action", "controller").
4. The input parameters of your action method method should match the json object parameters (exactly i.e. case sensitive).
For debugging you may use firebug addon in your browser so that you can see what is sent over the network or press F12 for debugging tool in that check in network tab.
You will have to make two changes:
Stringify your Json as below:
$.ajax({
cache: false,
url: url,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify(item),
type: 'POST',
success: function (data, textStatus, jqXHR) {
},
error: function (data, textStatus, jqXHR) {
}
});
Second, Just Annotate your Method with [HttpPost] as below:
[HttpPost]
public JsonResult Submit(string[] Skus, ContactDto Contact)
{
return Json(new { success = true, message = "Some message" });
}

Categories