Why is the parameter always null when I call the below Post method with the below ajax?
public IEnumerable<string> Post([FromBody]string value)
{
return new string[] { "value1", "value2", value };
}
Here is the call to the Web API method via ajax:
function SearchText() {
$("#txtSearch").autocomplete({
source: function (request, response) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "api/search/",
data: "test",
dataType: "text",
success: function (data) {
response(data.d);
},
error: function (result) {
alert("Error");
}
});
}
});
}
$.ajax({
url: '/api/search',
type: 'POST',
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
data: '=' + encodeURIComponent(request.term),
success: function (data) {
response(data.d);
},
error: function (result) {
alert('Error');
}
});
Basically you can have only one parameter of scalar type which is decorated with the [FromBody] attribute and your request needs to use application/x-www-form-urlencoded and the POST payload should look like this:
=somevalue
Notice that contrary to standard protocols the parameter name is missing. You are sending only the value.
You can read more about how model binding in the Web Api works in this article.
But of course this hacking around is a sick thing. You should use a view model:
public class MyViewModel
{
public string Value { get; set; }
}
and then get rid of the [FromBody] attribute:
public IEnumerable<string> Post(MyViewModel model)
{
return new string[] { "value1", "value2", model.Value };
}
and then use a JSON request:
$.ajax({
url: '/api/search',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ value: request.term }),
success: function (data) {
response(data.d);
},
error: function (result) {
alert('Error');
}
});
You cannot use a simple type for the [FromBody] attribute with the JSON content type. Although the default in Visual Studio has a string from body this is for the application/x-www-form-urlencoded content type.
Put the string value as a property on a basic model class and the deserialiser will work.
public class SimpleModel()
{
public string Value {get;set;}
}
public IEnumerable<string> Post([FromBody]SimpleModel model)
{
return new string[] { "value1", "value2", model.Value };
}
Change the JSON you are sending to:
{"Value":"test"}
whenever we are calling web api action and which take [frombody] parameter then input parameter prefix with =
for example
public string GetActiveEvents([FromBody] string XMLRequestString) {
}
to call above web api action
URI
2.
User-Agent: Fiddler
Content-Type: application/x-www-form-urlencoded
Host: localhost:54702
Content-Length: 936
request body is =data
I hope this will give clear idea.
I've just had a beast of a time with this and .NET Core Web API. So hopefully to save time for someone: The actual problem for me was simple - I wasn't converting to the correct type (Notice #Darins answer uses a VM rather than a string).
The default type in the template is string. I thought because we're sending stringified JSON, we would see a JSON string, but this was not the case. I had to make it the correct type.
E.g. This failed
[EnableCors("AllowAll")]
[HttpPost]
public HttpResponseMessage Post([FromBody]string value)
{
// Do something with the blog here....
var msg = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
return msg;
}
But this worked.
[EnableCors("AllowAll")]
[HttpPost]
public HttpResponseMessage Post([FromBody]Blog value)
{
// Do something with the blog here....
var msg = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
return msg;
}
Ajax Call
function HandleClick() {
// Warning - ID's should be hidden in a real application
// - or have covering GUIDs.
var entityData = {
"blogId": 2,
"url": "http://myblog.com/blog1",
"posts": [
{
"postId": 3,
"title": "Post 1-1",
"content": "This is post 1 for blog 1",
"blogId": 2
},
{
"postId": 4,
"title": "Post 1-2",
"content": "This is post 2 for blog 1",
"blogId": 2
}
]
};
$.ajax({
type: "POST",
url: "http://localhost:64633/api/blogs",
async: true,
cache: false,
crossDomain: true,
data: JSON.stringify(entityData),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (responseData, textStatus, jqXHR) {
var value = responseData;
},
error: function (responseData, textStatus, errorThrown) {
alert('POST failed.');
}
});
}
Related
I sending a post request to controller by ajax:
This is my code in cshtml file:
<script>
$("#btnSeachAjax").click(function () {
var token = $('input[name="__RequestVerificationToken"]').val();
$.ajax({
url: '#Url.Action("Search")',
data: { id: "1",title:"ba"},
contentType: 'application/json',
type: 'POST',
headers: {
"RequestVerificationToken": token
},
success: function (data) {
$("#data").html(data);
}
,
error: function (req, status, error) {
alert(error);
}
});
return false;
});
</script>
This is my code in controller:
[HttpPost, ActionName("Search")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Search([FromBody] string id,string title)
{
var movie = await _context.Movies.FindAsync(id);
return View(movie);
}
Value of id , title in controller = null.
Why ajax send parameters to controller is null?
I using Asp.net mvc net core 3.1.
public async Task<IActionResult> Search([FromBody] string id,string title)
Value of id , title in controller = null.
Based on your action method and accepted parameters, you can try to modify the Ajax code as below.
$.ajax({
url: '#Url.Action("Search")'+'?title=ba',
data: JSON.stringify("1"),
contentType: 'application/json',
type: 'POST',
//...
Besides, you can create a viewmodel and modify your action accept a complex type parameter, like below.
public class MyData
{
public string Id { get; set; }
public string Title { get; set; }
}
Action method
public async Task<IActionResult> Search([FromBody] MyData myData)
{
//...
On JS client side
$.ajax({
url: '#Url.Action("Search")',
data: JSON.stringify({ id: "1", title: "ba" }),
contentType: 'application/json',
type: 'POST',
//...
I want to send a string type id from View to the controller, do some calculations in the relevant action in the controller, and return a string back to the view. I can receive the returnData from controller, however the parameter of the action which is 'String data' is always null. It means i cannot send data from view to controller.
Thank you for your help.
View Side:
var data= "some string";
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(data),
url: "/Identities/Ajax",
success: function (data) {
alert("data: " + data);
},
error: function (result) {
alert("error!!");
}
})
Controller Side:
public JsonResult Ajax(String data)
{
var returnData= "some string";
Console.WriteLine(data); // Always Null
return Json(returnData);
}
You must create object first, then stringify object to pass object value to controller. Example:
var data= "some string";
$.ajax({
var objParam = new Object();
objParam.data = data;
type: "POST",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(objParam),
url: "/Identities/Ajax",
success: function (data) {
alert("data: " + data);
},
error: function (result) {
alert("error!!");
}
})
Also you have to change in your controller
public ActionResult Ajax(String data)
{
var returnData= "some string";
Console.WriteLine(data); // Always Null
return Json(returnData);
}
Use FromBody attribute on your parameter.
public ActionResult Ajax([FromBody]String data)
and name parameter in your jquery part:
data: {data: JSON.stringify(data)},
I am creating a web application for event management using .net mvc and jquery.
I created a mvc web app.contoller named SeatPlansController and model named SeatPlanes and I am able to insert the data to database.
But I am not able pass the data from jquery to database using the mvc controller.
My controller action code is as shown below
// GET: SeatPlans/Create
public ActionResult Create()
{
return View();
}
// POST: SeatPlans/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(String seat_id, String seat_no)
{
int id = 10;
SeatPlans S = new SeatPlans();
S.seat_id = seat_id;
S.seat_no = seat_no;
if (ModelState.IsValid)
{
db.SEATPLAN.Add(S);
db.SaveChanges();
// return RedirectToAction("Index");
}
return View(S);
}
In post create controller Id is primary key, so I want to pass seat_id,seat_no as argument and it should update the database.
I used following javascript
function getPerson(id) {
$.ajax({
type: "GET",
url: '#Url.Action("create", "SeatPlanesController")',
contentType: "application/json; charset=utf-8",
data: {eat_id :6, seat_no:8},
dataType: "json",
success: function (result) {
alert(result);
//window.locationre = result.url;
}
});
}
I am able to run the create get method using
http://localhost:52348/SeatPlans/Create
but how can I run post method directly from browser with argument
something like
http://localhost:52348/SeatPlans/Create/2/3t/e
I have changed the script as bellow,it works for GET method but if i made TYPE:"post" it popup an alert box with alert
"localhost:52348 says:
internal server error"
$(document).ready(function () {
$("button").click(function () {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: '#Url.Action("Create", "SeatPlans", new { Area = "" })',
data: { seat_id: "34", seat_no: "98" },
dataType: "json",
async: false,
success: function (result) {
$("#div1").html(result);
},
error: function (abc) {
alert(abc.statusText);
},
});
});
});
Finally i got the sollution
i changed the script as bellow
//jQuery.noConflict();
// var $j = jQuery.noConflict();
function clickevent()
{
var form = $("#frm");
var token = $('input[name="__RequestVerificationToken"]', form).val();
$.ajax({
type: "post",
// headers: { "__RequestVerificationToken": token },
url: '#Url.Action("Create", "SeatPlans")',
data: {
seat_id: "34", seat_no: "98"
},
success: function (result) {
$("#div1").html(result);
}
});
}
and change the create post method as bellow
<pre>
public ActionResult Create(String seat_id, String seat_no)
{
int id = 10;
SeatPlans S = new SeatPlans();
S.seat_id = seat_id;
S.seat_no = seat_no;
if (ModelState.IsValid)
{
db.SEATPLAN.Add(S);
db.SaveChanges();
// return RedirectToAction("Index");
}
return View(S);
}
I am using webapi2 and here is my client side code
var tbody = $('#files-table').find('tbody'); // tbody where all rows exists
var sortOrder = $(tbody).sortable('toArray').toString(); // geting ids of all rows
var updateSortOrder = $.ajax({
url: baseUrl + 'mycontroller/updateimagesorder',
dataType: 'json',
traditional: true,
contentType: 'application/json',
data: JSON.stringify({ "sortOrder": sortOrder.split(',') }),
type: 'PUT'
});
updateSortOrder.done(function (result) {
closeModel('images-model');
});
and here is my server side method
[Route("updateimagesorder")]
public HttpResponseMessage PutImagesSortOrder([FromBody]string[] sortOrder)
{
// do stuff with parameters
}
Note : /mycontroller is route prefix here and baseUrl is my domain url
so , what the issue in my code ?
Try passing the value like this:
data: JSON.stringify(sortOrder.split(',')),
So that your request payload looks like a string array:
["foo", "bar"]
If you want to pass the value like that:
data: JSON.stringify({ "sortOrder": sortOrder.split(',') }),
then make sure that you have declared a view model:
public class MyViewModel
{
public string[] SortOrder { get; set; }
}
that your controller action will take as parameter:
[Route("updateimagesorder")]
public HttpResponseMessage PutImagesSortOrder(MyViewModel model)
{
// do stuff with parameters
}
I have been trying the whole afternoon crawling through the web trying to receive a JSON object in the action controller.
What is the correct and or easier way to go about doing it?
I have tried the following:
1:
//Post/ Roles/AddUser
[HttpPost]
public ActionResult AddUser(String model)
{
if(model != null)
{
return Json("Success");
}else
{
return Json("An Error Has occoured");
}
}
Which gave me a null value on my input.
2:
//Post/ Roles/AddUser
[HttpPost]
public ActionResult AddUser(IDictionary<string, object> model)
{
if(model != null)
{
return Json("Success");
}else
{
return Json("An Error Has occoured");
}
}
which gives me a 500 error on the jquery side which is trying to post to it? (meaning that it didn't bind correctly).
here is my jQuery code:
<script>
function submitForm() {
var usersRoles = new Array;
jQuery("#dualSelectRoles2 option").each(function () {
usersRoles.push(jQuery(this).val());
});
console.log(usersRoles);
jQuery.ajax({
type: "POST",
url: "#Url.Action("AddUser")",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(usersRoles),
success: function (data) { alert(data); },
failure: function (errMsg) {
alert(errMsg);
}
});
}
All I want to do is receive my JSON object in my mvc action?
Unfortunately, Dictionary has problems with Model Binding in MVC. Read the full story here. Instead, create a custom model binder to get the Dictionary as a parameter for the controller action.
To solve your requirement, here is the working solution -
First create your ViewModels in following way. PersonModel can have list of RoleModels.
public class PersonModel
{
public List<RoleModel> Roles { get; set; }
public string Name { get; set; }
}
public class RoleModel
{
public string RoleName { get; set;}
public string Description { get; set;}
}
Then have a index action which will be serving basic index view -
public ActionResult Index()
{
return View();
}
Index view will be having following JQuery AJAX POST operation -
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>
$(function () {
$('#click1').click(function (e) {
var jsonObject = {
"Name" : "Rami",
"Roles": [{ "RoleName": "Admin", "Description" : "Admin Role"}, { "RoleName": "User", "Description" : "User Role"}]
};
$.ajax({
url: "#Url.Action("AddUser")",
type: "POST",
data: JSON.stringify(jsonObject),
contentType: "application/json; charset=utf-8",
dataType: "json",
error: function (response) {
alert(response.responseText);
},
success: function (response) {
alert(response);
}
});
});
});
</script>
<input type="button" value="click1" id="click1" />
Index action posts to AddUser action -
[HttpPost]
public ActionResult AddUser(PersonModel model)
{
if (model != null)
{
return Json("Success");
}
else
{
return Json("An Error Has occoured");
}
}
So now when the post happens you can get all the posted data in the model parameter of action.
Update:
For asp.net core, to get JSON data as your action parameter you should add the [FromBody] attribute before your param name in your controller action. Note: if you're using ASP.NET Core 2.1, you can also use the [ApiController] attribute to automatically infer the [FromBody] binding source for your complex action method parameters. (Doc)
There are a couple issues here. First, you need to make sure to bind your JSON object back to the model in the controller. This is done by changing
data: JSON.stringify(usersRoles),
to
data: { model: JSON.stringify(usersRoles) },
Secondly, you aren't binding types correctly with your jquery call. If you remove
contentType: "application/json; charset=utf-8",
it will inherently bind back to a string.
All together, use the first ActionResult method and the following jquery ajax call:
jQuery.ajax({
type: "POST",
url: "#Url.Action("AddUser")",
dataType: "json",
data: { model: JSON.stringify(usersRoles) },
success: function (data) { alert(data); },
failure: function (errMsg) {
alert(errMsg);
}
});
You are sending a array of string
var usersRoles = [];
jQuery("#dualSelectRoles2 option").each(function () {
usersRoles.push(jQuery(this).val());
});
So change model type accordingly
public ActionResult AddUser(List<string> model)
{
}
fwiw, this didn't work for me until I had this in the ajax call:
contentType: "application/json; charset=utf-8",
using Asp.Net MVC 4.