I'm trying to create a json object and pass it as a parameter using Ajax. Here's the js
var model = {
"Name": "test",
"Location": "Place",
"Interests": ["Code", "Coffee"]
};
$.ajax({
type: "POST",
url: "/CT01211/test",
contentType: "application/json'",
dataType: "json",
data: {
message: model
}
});
Here's the c#:
public class ModelTest
{
public string Name { set; get; }
public string Location { set; get; }
System.Collections.Generic.List<string> Interests { set; get; }
}
[HttpPost]
public ActionResult test (ModelTest message)
{
return Json(message);
}
Everything time I try I get the error: "Invalid JSON primitive".
I've tried JSON.stringify(model)
I've tried single quotes instead of double when building the model variable
I've tried changing the contentType and dataType
I've tried not having quotes around the properties:
var model = {
Name: "test",
Location: "Place",
Interests: ["Code", "Coffee"]
};
No matter what, I get the error.
Little help?
Related
How do I get the component factory to bind and resolve to the JSON property attribute names, in an AJAX request to Razor action result?
Right now, I have a workaround where I just send the JSON string and deserialize it server-side, but thinking there must be a way for the action to do this.
For example, I have the following model:
public class ExampleClass
{
[JsonProperty("#first-name")]
public string FirstName { get; set; }
[JsonProperty("#last-name")]
public string LastName { get; set; }
}
I then try to send my model using the following script (note I have removed the double '##' for razor view model binding to avoid confusion). This is the "rendered" script:
var model = {
"#first-name": "test",
"#last-name": "test"
};
$.ajax({
url: '/Dashboard?handler=test',
type: "POST",
contentType: "application/json",
data: JSON.stringify(model),
beforeSend: function (xhr) {
xhr.setRequestHeader("RequestVerificationToken", $('input:hidden[name="__RequestVerificationToken"]').val());
},
success: function (result) {
},
error: function (result) {
}
});
On my handler, I then get a null object (model values are null)
public IActionResult OnPostTest([FromBody] ExampleClass model)
If I change the model to the following, everything works fine:
var model = {
"FirstName": "test",
"LastName": "test"
};
I can see the object is getting passed correctly
I made a silly mistake... I was using Newtonsoft.Json library attribute property binding (JsonProperty), instead of the serializer factory being used by the action (JsonPropertyName) in System.Text.Json.Serialization... very silly moment. Realized once I removed the Newtonsoft import and saw my class now had errors,
Now working...
public class ExampleClass
{
[JsonPropertyName("#first-name")]
public int FirstName { get; set; }
[JsonPropertyName("#last-name")]
public int LastName { get; set; }
}
I have the following models in my ASP.NET Core code:
public class TestItem
{
public string Id { get; set; }
public string Name { get; set; }
public List<TestSubItem> SubItems { get; set; }
}
public class TestSubItem
{
public string Id { get; set; }
}
and the following method in my Controllers/TestController.cs:
// POST: Test/Create
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Create([FromBody]TestItem item)
{
// Use item here...
return View(item);
}
I have the following JavaScript in my page:
var mySubItems = [{"Id": "1"}];
function submitForm() {
// myForm contains an Id textbox and a Name textbox
$("#myForm").submit();
};
function doPost() {
var testItem = {
Id: "2",
Name: "testName",
SubItems: mySubItems
};
$.ajax({
url: '#Url.Action("Create" ,"Test")',
type: "POST",
contentType: "application/json",
data: JSON.stringify(testItem),
success: function (data) {
alert(data);
},
error: function (error) {
var x = error; //break here for debugging.
}
});
};
When I use doPost, I always get 400 Bad Request back from the server. submitForm on the other hand works fine, but I don't know how to include mySubItems in the data sent to the server.
What's the quickest way out of this?
Including [ValidateAntiForgeryToken] on your controller is causing the problem. You need to include the token when you post the data. MVC automatically includes it the form which is why submitForm() works.
The challenge is that I do not know how to make it work with JSON data getting posted. You might be able to by adding the following into testItem:
__RequestVerificationToken: $('input[name="__RequestVerificationToken"]', form).val()
For more information, check out include antiforgerytoken in ajax post ASP.NET MVC
I'm trying to post JSON to a mvc controller through AJAX. I use this code but it does not do the post.
$(document).ready(function(){
$(".btn-success").click(function(e){
var urData = { City: 'Moscow', Age: 25 };
$.ajax({
url: "/Category/Create/",
type: "POST",
dataType: "json",
traditional: true,
contentType : "application/json",
data: urData,
success: function(maindta) {
alert(maindta);
},
error: function(jqXHR, textStatus){
}
});
e.preventDefault(); //STOP default action
});
});
This is controller action
[HttpPost]
public virtual JsonResult Create(List<object> urData){
}
Your posting back an object with 2 properties so you need a model with those 2 properties
public class MyModel
{
public string City { get; set; }
public int Age { get; set; }
}
and the method needs to be changed to
public JsonResult Create(MyModel model)
{
.... // model will be populated with the values you sent
return Json(...);`
}
and you need to remove the following options from the ajax method
contentType : "application/json",
traditional: true,
Alternatively, you method can be
public JsonResult Create(string city, int age)
but you lose the benefits of model validation
Side note: Always use the Url.Action() method to ensure your url's are correctly generated
url: '#Url.Action("Create", "Category")',
I cant any value from json.Values come 'null'.Where is the problem?
MY:JQUERY CODE IN siparis.cshtml
var array_table = [];
array_table.push({
arrayName: "Name Value",
arrayMail: "Mail Value",
arrayMobile: "mobile Value"
});
}
$.ajax({
url: '#Url.Action("SiparisOlustur")', type: "POST", dataType: "json",
data: JSON.stringify( array_table),
type: 'POST',
contentType: "application/json; charset=utf-8",
success: function (data) {
$('#POCStatus').html('<div class="success">POC Removed Successfully.</div>');
},
error: function () {
$('#POCStatus').html('<div class="field-validation-error">Some Error Occured in Removing POC.</div>');
}
});
My JSON Model:
public class JsonModel
{
public string arrayName { get; set; }
public string arrayMail { get; set; }
public string arrayMobile { get; set; }
}
My SiparisController:
[HttpPost]
public ActionResult SiparisOlustur(List<JsonModel> array_table)
{
return View();
}
Result is this:
ARRAY_TABLE IS COMING NULL
Thank You,
Regards,
B.Y.
Give array_table name in data in ajax call as :
data: {array_table : JSON.stringify( array_table)}
I have been trying all the daylong to build a model in asp.net mvc3 for handling this json post. I have looked at most of stackoverflow'post but still couldn't succeed building it. The json data is as below
{"form":[{
"ora1":{"start":"08:00:00","end":"08:50:00"},
"ora2":{"start":"09:00:00","end":"09:50:00"},
"ora3":{"start":"10:00:00","end":"10:50:00"},
"...":{"start":"12:10:00","end":"13:00:00"},
"oran":{"start":"12:10:00","end":"13:00:00"}
}]}
or even
{"form":
{"Monday":
{
"ora1":{"start":"08:00:00","end":"08:50:00"},
"ora2":{"start":"09:00:00","end":"09:50:00"},
"ora3":{"start":"10:00:00","end":"10:50:00"},
"....":{"start":"11:10:00","end":"12:00:00"},
"oran":{"start":"12:10:00","end":"13:00:00"}
}
},
{"Tuesday":
{
"ora1":{"start":"08:00:00","end":"08:50:00"},
"ora2":{"start":"09:00:00","end":"09:50:00"},
"ora3":{"start":"10:00:00","end":"10:50:00"},
"....":{"start":"11:10:00","end":"12:00:00"},
"oran":{"start":"12:10:00","end":"13:00:00"}
}
}
}
Any kind of help will be appreciated.
Thank you dynamicus
I was curious to see if I could get a custom model binder to work for your scenario. Below is a very crude example that works with your incoming data. Please note it needs much improvement, but does bind successfully:
Given the following view models:
public class OraFormData
{
public IDictionary<string, Duration> form { get; set; }
}
public class Duration
{
public string Start { get; set; }
public string End { get; set; }
}
Using this custom model binder:
public class OraFormDataModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
const string FORMKEY = "form[0][{0}][{1}]";
const string PREFIX = "form[0][";
try
{
var form = controllerContext.HttpContext.Request.Form;
var vm = new OraFormData();
var oraKeys = (from mainKey in form.AllKeys
where mainKey.StartsWith(PREFIX)
let trimmedKey = mainKey.Replace(PREFIX, String.Empty)
select trimmedKey.Substring(0, trimmedKey.IndexOf(']'))).Distinct().ToList();
vm.form = new Dictionary<string, Duration>(oraKeys.Count);
foreach (var oraKey in oraKeys)
{
vm.form.Add(oraKey, new Duration
{
Start = form[string.Format(FORMKEY, oraKey, "start")],
End = form[string.Format(FORMKEY, oraKey, "end")]
});
}
return vm;
}
catch
{
return null;
}
}
}
The following action binds when using the string from your first example:
[HttpPost]
public ActionResult TestPost([ModelBinder(typeof(OraFormDataModelBinder))]OraFormData form)
{
// added modelbinder here just for example, could move to global.asax
return Json(...);
}
According to the answers in this post, binding to a Dictionary object as you have outlined is not natively supported. However, one of the answers to that same question apparently created a custom ModelBinder to achieve the desired result.
If you have more control over the incoming json data, you could do something like this:
public class OraViewModel
{
public IList<LineItem> LineItems { get; set; }
}
public class LineItem
{
public string Name { get; set; }
public Duration Duration { get; set; }
}
public class Duration
{
public string Start { get; set; }
public string End { get; set; }
}
Then from your view you would post like this:
$('#buttonId').click(function () {
var data = { LineItems: [{ Name: "name 0", Duration: { Start: "start 0", End: "end 0"} }, { Name: "name 1", Duration: { Start: "start 1", End: "end 1"} }, { Name: "name 2", Duration: { Start: "start 2", End: "end 2"} }, { Name: "name 3", Duration: { Start: "start 3", End: "end 3"} }, { Name: "name 4", Duration: { Start: "start 4", End: "end 4"}}] };
$.ajax({
url: "/home/testpost2",
data: JSON.stringify(data), //*** using JSON2.js to stringify the js object
type: "POST",
contentType: 'application/json', // *** note the content type is set to json
dataType: 'json',
});
});
Doing so allowed the following controller action to properly bind the incoming data to my object:
[HttpPost]
public ActionResult TestPost2(OraViewModel data)
{
return Json("whatever you want the return to be");
}