.Net Core Binding - c#

I am using .Net Core 2.1. This is the function that takes the value of the input boxName from the user and is supposed to pass it to the controller - Create function when the "save button" is clicked.
<script type="text/javascript">
function Submit() {
var boxName = $("#boxID").val();
alert(boxName);
UNTIL HERE EVERYTHING IS FINE - THE ALERT RETURNS THE CORRECT VALUE
$.ajax({
type: "POST",
contentType: "application/json",
url: '/Box/Create',
datatype: 'json',
data: JSON.stringify({ ID: "#Model.Id", BoxName: boxName }),
success: function (response) {
alert("Box created");
}
error: function (response) {
alert("error");
}
});
}
IN THE CONTROLLER
public ActionResult Create(int ID, string BoxName)
{
Box _Box = new Box();
_Box.Name= BoxName;
_db.Boxes.Add(_Box);
_db.SaveChanges();
return RedirectToAction("Index");
}
THE STRING BoxName RECEIVED AS A PARAMETER FROM THE AJAX IS NULL
I even tried
public ActionResult Create([Bind(Include = "ID,BoxName")] Box Box)
but it didn't work either. The error was
Include is not a valid named attribute argument
Any help is appreciated.

Remove the content Type and don't use stringify. So your ajax call becomes
$.ajax({
type: "POST",
url: '/Box/Create',
datatype: 'json',
data: { ID: "#Model.Id", BoxName: boxName },
success: function (response) {
alert("Box created");
}

Edit: This is partially wrong though you should do it for clarity. If there is only one action and the verb is not specified in your controller, the action is done anyway regardless if it's POST or GET.
You are using a POST verb in your ajax, by default all actions in the controller are GET. Add the [HttpPost] attribute above your controller action.
[HttpPost]
public ActionResult Create(int ID, string BoxName)
{
...
}

You should create a binding from the body of the request : ie:
class CreateBinding {
public string ID { get; set;}
public string BoxName { get; set; }
}
And in you controller:
[HttpPost]
Public ActionResult Create([FromBody] CreateBinding binding)
{
var id = binding.ID;
var name = binding.BoxName;
....
}

Related

ajax object from view to controller not containing data

>
I .net core 2.2 This is the object Object:
[Serializable]
public class oob
{
public int i { get; set; }
public string j { get; set; }
}
this is the action in "Home" Controller named Gett that takes oob as input from ajax
[HttpGet]
public IActionResult Gett(oob ww)
{
return Ok(ww);
}
Ajax
{
$.ajax({
type: "Get",
url: "Home/gett",
data: { ww: JSON.stringify({i:55,j:"weqe"})},
dataType: "json",
contentType:"json",
success: function (f) {
console.log(f);
},
error: function (f) {
console.log(f);
}
});
});
When request is made ,at the Gett(oob ww) i get an object with value of i=0 and j=null
Ideally you should not pass object to a GET request, for posting object, you should use POST.
If you still want, you need to change your GET method like following using FromQuery.
[HttpGet]
public IActionResult Gett([FromQuery] oob ww)
{
return Ok(ww);
}
And change your AJAX call like following.
$.ajax({
type: "Get",
url: "Home/gett",
data: {i:55,j:"weqe"},
dataType: "json",
contentType:"json",
success: function (f) {
console.log(f);
},
error: function (f) {
console.log(f);
}
});
Note: To pass the object you don't need JSON.stringify if you are using FromQuery for your API

How to use model binder in .net core mvc with Ajax Post?

I'm new to .net core MVC and am trying to execute an Ajax post similar to .net framework MVC. I'm simply trying to POST a single int value to the controller action below. The Ajax call hits the controller, but the action parameter is always 0. I verified that the correct integer value is being sent in the Ajax request payload. What am I missing?
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult Ajax_GenerateSecretNum([FromBody]int lower)
{
return Json(new { success = true });
}
$.ajax({
url: '#Url.Action("Ajax_GenerateSecretNum", "Home")',
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: { lower: lower },
success: function (response) {
}
});
You could create a model (DTO) for the controller parameter and use JSON.stringify() on your data before posting to the controller.
$.ajax({
url: '#Url.Action("Ajax_GenerateSecretNum", "Home")',
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify({ lower: lower }),
success: function (response) {
}
});
public class ModelDto
{
public int Lower { get; set; }
}
[HttpPost]
public IActionResult Ajax_GenerateSecretNum([FromBody]ModelDto model)
{
// model.Lower should contain your int
return Json(new { success = true });
}
$.ajax({
url: '#Url.Action("Ajax_GenerateSecretNum", "Home")',
type: 'POST',
data: { "lower": lower, "upper": upper },
success: function (response) {
}
});
Changing my jQuery ajax to the above sample solved the issue. I'm not sure why, but it looks like specifying the extra ajax parameters caused the values to fail model binding. After changing the ajax, I was also able to remove the [FromBody] attribute from the controller action.
You can do something like below:
$.ajax({
method: "POST",
data: { "Property1": "value1", "Property2": "value2"},
url: "#Url.Action("Ajax_GenerateSecretNum", "Home")",
success: function (data) {
//success login
},
error: function (data) {
alert('error' + data.status);
}
});
Controller will look like below:
[HttpPost]
public ActionResult Ajax_GenerateSecretNum(ModelClass modelClass)
{
//You logic will be here
}

ASP.NET Core MVC posting a model to controller using ajax

I am trying to post a javascript object, representative of a Model, back to a controller using an ajax post. However, the model is always showing as null.
The model in question is as follows
public class Product
{
[Key]
public int Id { get; set; }
[Required(ErrorMessage = "Name is required and must not be empty.")]
[StringLength(200, ErrorMessage = "Name should not exceed 200 characters.")]
public string Name { get; set; }
public DateTime Created { get; set; }
[Required(ErrorMessage = "Price is required and must not be empty.")]
[DataType(DataType.Currency)]
public decimal Price { get; set; }
}
With the ajax call looking like so
$('#btnSaveNewProduct').click(function (e) {
e.preventDefault();
var form = $('#frmNewProduct');
if (form.valid()) {
var data = { // to be replaced with form values
Name: 'Bob',
Price: 34
};
//ajax call to save product
$.ajax({
type: "POST",
url: "#Url.Action("AddProduct", "Admin")",
contentType: "application/json",
dataType: "json",
data: data,
success: function (response) {
alert('done');
},
error: function (response) {
alert(response);
}
});
}
});
The controller method looks like the following
[HttpPost]
public JsonResult AddProduct([FromBody] Product product)
{
bool success = false;
// save product
success = true;
return new JsonResult(success);
}
Any insight would be most appreciated.
To get your code to work as desired, make the following three modifications to your code.
From the Ajax call, remove this: dataType: "json"
From the Ajax call, remove this: data:data
In the Ajax call, add this: data:JSON.stringify(data)
IMPORTANT POINTS TO NOTE:
When you are using the [FromBody] attribute, the Content-Type value determines the formatter for the ASP.NET Core MVC Framework to use for parameter binding.
Since your Content-Type is application/json, a raw JSON string and not a JSON object, should be passed as data. Hence, apply JSON.stringify.
See this reference: Parameter Binding Using [FromBody] Attribute
I found below working:
$.ajax({
method: "POST",
data: { "Name": "bob", "Price": 10},
url: "#Url.Action("AddProduct", "Admin")",
success: function (data) {
//success login
},
error: function (data) {
alert('error' + data.status);
}
});
no need to mention dataType and contentType in ajax call. And your controller will like below:
[HttpPost]
public ActionResult AddProduct(Product product)
{
//You logic will be here
}

Using Ajax to POST to ASP.Net controller - Data for Post incorrect

This is my DisputeController method stub:
[HttpPost]
public virtual ActionResult UpdateDisputeStatus(DisputeUdpateStatusModel model)
{//some code
Here is my Ajax call:
var url = '/dispute/UpdateDisputeStatus';
var disputeStatusObj = {
DisputeId: id,
DisputeStatusId: selectedValue
}
$.ajax({
url: url,
cache: false,
type: 'POST',
contentType: "application/json; charset=utf-8",
data: disputeStatusObj,
success: function (data) {
alert('Status Changed Successfully');
},
error: function (e) {
alert('Error: ' + e.status);
}
});
I know the routing works, as without using the data parameter the code enters my method (obviously without the model in parameters)
I have tried the following data formats:
data: {'DisputeId': DisputeId, 'StatusId': DisputeStatusId},
data: {disputeStatusObj},
data: JSON.Stringify(disputeStatusObj)
using controller methods:
[HttpPost]
public virtual ActionResult UpdateDisputeStatus(string disputeId, string statusId)
[HttpPost]
public virtual ActionResult UpdateDisputeStatus(modelname model)
None of which work. I get Not found errors or 500's.
Bearing in mind that I know the routing is correct, when I send the request with no data, so what am I missing here?
Am I declaring the controller incorrectly?
Verify your model that should be the same name as well as the data type because of while post the value from Jquery that values are not mapping with the property of the model.
#Mike I tried below code
public class DisputeUpdateStatusModel
{
public string DisputeId { get; set; }
public string DisputeStatusId { get; set; }
}
public class DisputeController : Controller
{
[HttpPost]
public virtual ActionResult UpdateDisputeStatus(DisputeUpdateStatusModel model)
{
return new ContentResult() { Content = "OK" };
}
}
script on view as:
<script type="text/javascript">
var disputeStatusObj = {}
disputeStatusObj.model = {
DisputeId: 1,
DisputeStatusId: 1
}
var url = '/dispute/UpdateDisputeStatus';
$.ajax({
url: url,
cache: false,
type: 'POST',
contentType: "application/json; charset=utf-8",
data: JSON.stringify(disputeStatusObj),
success: function (data) {
alert('Status Changed Successfully');
},
error: function (e) {
alert('Error: ' + e.status);
}
});
</script>
Please see.
If this is not working, can you please show Model class?
thanks for all your input. My solution was a combination of the answers above.
I was unable to get my code to model bind, so I went back to basics.
I took out the contentType: "application/json; charset=utf-8", as suggested by Stephen Muecke, and ditched the model in my controller and replaced it with string disputeId, string statusId and as suggested by Er Pravin Suthar ensured the parametes were called the same thing. Also to note, the data section was sent as data: { disputeId: disputeId, statusId: statusId } with no quotes around the parameter names. So I ended up with:
var statusId = statusDropdown.value;
var disputeId = $("#disputeId").val();
$.ajax({
url: "/Dispute/UpdateDisputeStatus",
data: { disputeId: disputeId, statusId: statusId },
type: 'POST',
success: function (data) {
alert('Success');
},
error: function (e) {
alert('Status not changed' + e.responseText + ' : ' + e.status);
}
});
and the Controller structure is:
[HttpPost]
public virtual ActionResult UpdateDisputeStatus(string disputeId, string statusId)
Thanks Again for all your input!

ASP.Net MVC Model Binding Complex Object using GET

I have a class in my web project:
public class MyClass
{
public int? Param1 { get; set; }
public int? Param2 { get; set; }
}
which is a parameter in my controller method:
public ActionResult TheControllerMethod(MyClass myParam)
{
//etc.
}
If I call the method using POST, the model binding works automatically (I use angular on the js side, which likely doesn't matter):
$http({
method: "post",
url: controllerRoot + "TheControllerMethod",
data: {
myParam: myParam
}
}).success(function (data) {
callback(data);
}).error(function () {
alert("Error getting my stuff.");
});
If I use a GET, the parameter is always null in the controller.
$http({
method: "get",
url: controllerRoot + "TheControllerMethod",
params: {
myParam: myParam
}
}).success(function (data) {
callback(data);
}).error(function () {
alert("Error getting my stuff.");
});
Does complex model binding using the default model binder only work for POSTs, or is there something I can do to make this work with a GET?
The answer is Yes. The difference between GET and POST requests is that a POST body can have a content type so they can be interpreted correctly on the server side as XML, or Json, so on; for GET, all you have is just a querystring.
With ASP.NET MVC you can indeed bind your model on a GET request, as long as you have the same query string parameter names as of the property names of your Model class. Example from this answer:
public class ViewModel
{
public string Name { set;get;}
public string Loc{ set;get;}
}
You can do a Get request like this
MyAction?Name=jon&Loc=America
and MVC will automatically bind your model:
[HttpGet]
public ViewResult MyAction(ViewModel model)
{
// Do stuff
return View("ViewName", model);
}
Why are you calling the property "data" in the POST, and "params" in the GET? Both should be called "data".
$http({
method: "get",
url: controllerRoot + "TheControllerMethod",
data: {
myParam: myParam
}
}).success(function (data) {
callback(data);
}).error(function () {
alert("Error getting my stuff.");
});

Categories