I have an Action that takes a simple string parameter I send data to it using Ajax like this:
[HttpPost]
public async Task<IActionResult> Add(string data)
$.ajax({
type: "POST",
url: "/Items/Add",
data: {
data: item
}
})
This works fine, but after reading about model binding simple types in ASP.NET Core I learned you can use the [FromBody] attribute and prefix the value with '=' as well, so I rewrote it following examples like this:
[HttpPost]
public async Task<IActionResult> Add([FromBody] string data)
$.ajax({
type: "POST",
url: "/Items/Add",
data: "=" + item,
contentType: "text/plain"
})
However after doing this my action is no longer hit and the ajax request comes back with a 404. This happens with or without setting the contentType: "text/plain", though I notice my Request payload is empty when not setting the contentType in the second example.
Update: I've gotten the [FromBody] attribute to work by rewriting the Ajax request like this:
$.ajax({
type: "POST",
url: "/Items/Add",
data: JSON.stringify(item),
contentType: "application/json"
})
Adding application/json fixed the 404, but then the data was null. I had to update it to "'=" + item + "'" in order for the value to come through in the action, but then the "=" was still part of the data, so I don't get what the = prefix is all about in the documentation.
I'm not sure about the text/plain content-type here, but your issue can be solved by doing 2 things:
Change the [FromBody] to [FromForm] - [FromBody] only works for json data (I believe) which would explain why your your updated example worked... sort of. But because the model binder is now looking for JSON explicitly, you had to add the quotes and end up with the wrong answer.
Change the content-type to application/x-www-form-urlencoded.
So it looks like this:
[HttpPost]
public async Task<IActionResult> Add([FromForm] string data)
$.ajax({
type: "POST",
url: "/Items/Add",
data: "=" + item,
contentType: "application/x-www-form-urlencoded"
})
Now the route will match, and the model binder will treat data as a form, easily defaulting =item to your action parameter.
Side note: I suspect you were getting a 415 media unsupported, not a 404.
First of all you need to format POST request body data.It should looks like something like this:
var dataObject = {
data: '=' + item,
}
$.ajax({
type: 'POST',
url: '/Items/Add',
dataType: 'json',
contentType: dataType,
data: dataObject,
success: function(result) {
console.log(result);
}
});
In your action:
[HttpPost]
public async Task<IActionResult> Add([FromBody] string data)
{
}
Related
I am trying to send a value from jQuery using ajax call and fetch the value in the controller. Below is what I am trying, but the value of A is always null. Can someone help me where I am going wrong.
$.ajax({
type: "POST", //The type of Method being used (GET, SET, POST, etc.)
url: '/Controller1/Index',
contentType: 'application/json; charset=utf-8',
data: { A: "true" }, //Your data to pass to your Controller action
dataType: "json",
success: function (result) {
alert(response.responseText);
alert("Done!");
}
});
C# code
[HttpPost]
[ActionName("Index")]
public ActionResult IndexPost(FilterRule queryBuilder, BootstrapTableQueryType bootstrapTable, string A)
{
string B = A;
}
I'm calling an ASP.NET MVC 4 control method from Javascript (in a cshtml file) using $.ajax() as shown below
$.ajax({
url: '#Url.Action("MyAction", "MyController")',
type: 'GET',
data: { 'id': "123"},
contentType: "application/json; charset=utf-8",
dataType: 'json',
success: function (data) {
}
});
The controller action method is
public JsonResult MyAction(string id)
{
// Do stuff
return new JsonResult();
}
which is getting called ok but is causing a GET 500 (Internal Server Error).
I don't really care about the returned data I just want to call the controller method to update a model.
Can anyone let me know why I'm getting the 500 or an alternative way of doing this that would be great.
For security reasons you cannot use the GET method in ajax requests (See JSON Hijacking).
You just have to do it like this:
return Json(data, JsonRequestBehavior.AllowGet)
or better off, change the method to post
type: 'POST',
I want to send this POST request by amplifyjs
amplify.request.define('createItem', 'ajax', {
url: baseApiUrl + '/create/?folderid={folderid}',
dataType: 'json',
type: 'POST',
contentType: 'application/json; charset=utf-8'
});
after that, the execution will be something like this:
createItem = function (callbacks, folderid, itemdata) {
return amplify.request({
resourceId: 'createItem',
data : {
folderid: folderid,
data: itemdata
},
success: callbacks.success,
error: callbacks.error
});
};
"itemData" is already a JSON string. I keep getting the Bad Request status code.
If I change the API URL to:
baseApiUrl + '/create
And after that pass:
return amplify.request({
resourceId: 'createItem',
data :data,
success: callbacks.success,
error: callbacks.error
});
It works just fine, but I need to pass the Id as well. Maybe, I'm missing something here.
You need to combine folderid and itemdata into a single data object. When Amplify reads your data object it will extract the folderid property and place it in the URL of the request. Then it will POST the remaining properties of the data object.
in postback requests when i need posted values i do like this
[HttpPost]
public ActionResult Index()
{
//i need to get values in here not in action method argument
//i know this works but not like this --> ActionResult Index(string Name)
string Name = Request.Form["Name"];
}
but in ajax requests this does not work,,and i cant find where mvc store ajax posted values
Any Suggestions?
I'm a little late to the party, but I will offer an alternative that will allow you to access Request.Form with an Ajax post/form. This was tested in MVC 4 and jQuery 1.9.1.
If the controller's Request.Form is not populating for your Ajax post, it is likely because you are manually serializing and sending the data to the controller with a contentType of application/json (a common scenario).
Here is an jQuery.ajax example that will NOT populate Request.Form on the controller.
// JSON serialized form data.
var data = {"id" : "1234", "name" : "Dave"};
$.ajax({
type: "POST",
url: serviceUrl,
contentType: "application/json",
dataType: "json",
data: JSON.stringify(data || {}),
success: function () { }
});
Changing the contentType will cause the controller to process the post like a form submission.
// Form encoded data. See jQuery.serialize().
var data = "id=1234&name=Dave";
$.ajax({
type: "POST",
url: serviceUrl,
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
dataType: "json",
data: data,
success: function () { }
});
You can also leave contentType undefined as application/x-www-form-urlencoded; charset=UTF-8 it is the jQuery default.
I would note that I only used $.ajax to better illustrate what is going on. You could also use $.post, though you will still need to send form encoded data
The ajax posted values won't appear in the request from collection however you can use the ValueProvider infrastructure in MVC to get the your Ajax posted value:
[HttpPost]
public ActionResult Index()
{
Name = ValueProvider.GetValue("Name").AttemptedValue;
}
Or the Request.InputStream contains all the posted data what you can read and deserailize as you want:
[HttpPost]
public ActionResult Index()
{
var serializer = new JavaScriptSerializer();
using (var streamReader = new StreamReader(Request.InputStream))
{
var data = (Dictionary<string,object>)serializer
.DeserializeObject(streamReader.ReadToEnd());
//assuming your posted data looks like this: '{"Name": "test"}'
string name = data["Name"].ToString();
}
}
But I highly recommend that you should not fight against the MVC infrastructure and recive the data as your action paratemer:
[HttpPost]
public ActionResult Index(string name)
{
}
I'm using jQuery ajax to build a viewmodel list and then trying to send that viewmodel to another ActionResult in order to create PartialViews. The first part works well, and I'm able to create the viewmodel (List), but when I try to send the viewmodel back to the controller to build up the partial views, everything within the viewmodel is 0. It returns the correct number of items in the list, but it seems to lose the values.
Can anyone see if I'm missing anything here?
jQuery:
$.ajax({
async: false,
type: 'GET',
dataType: "json",
url: '#Url.Action("GetMapDetails")',
success: function (data) {
$.ajax({
async: false,
type: 'POST',
dataType: "json",
url: '#Url.Action("GetMapItems")',
data: {
list: data
},
success: function (list) {
//callback
});
}
});
}
});
and the controller:
public ActionResult GetMapDetails()
{
List<ViewModel> vm = new List<ViewModel>();
//create viewmodel here
return Json(vm.ToArray(), JsonRequestBehavior.AllowGet);
}
[HttpPost]
public ActionResult GetMapItems(List<ViewModel> list)
{
return PartialView("_MapItemsPartial", list);
}
I've tried also using contentType: 'application/json' and JSON.stringify(data) but that gave me an Invalid JSON primitive error.
Any help appreciated - thanks
You could send them as JSON request:
$.ajax({
async: false,
type: 'POST',
contentType: 'application/json',
url: '#Url.Action("GetMapItems")',
data: JSON.stringify({
list: data
}),
success: function (result) {
//callback
}
});
Also notice that I have removed the dataType: 'json' parameter because your GetMapItems POST controller action doesn't return any JSON. It returns a PartialView. So I guess you did something wrong and this is not what it was meant to be returned from this controller action because from what I can see in your success callback you are expecting to manipulate JSON.
Oh, and please remove this async:false => it defeats the whole purpose of AJAX as you are no longer doing any AJAX, you are now doing SJAX.