I have the following code in my jQuery file
var bases = {};
for (var j = 0; j < selectedVariants.length; j++) {
bases[selectedVariants[j].BId] = selectedVariants[j].CId;
}
and i am getting some data in bases dictionary now
and my question here is how do I pass this bases dictionary to controller through ajax call.
I tried the following thing but bases count in the controller is coming as ZERO
$.ajax({
url: $.url('~/TUP/Tflow'),
type: 'POST',
data: { baseDetails: JSON.stringify(bases)},
async: true,
cache: false,
});
Here when I see in my controller ... bases count is coming as ZERO
Please help me on this
Controller :
[HttpPost]
public JsonResult Tflow(JsonFileContentInputs basedetails)
{
//some code
}
and my model :
[ModelBinder(typeof(JsonModelBinder))]
[DataContract]
public class JsonFileContentInputs
{
[JsonProperty(PropertyName = "basedetails")]
[DataMember]
public Dictionary<string, string> basedetails { get; set; }
}
Try the following approach. As #EhsanSajjad mentioned, you'll need to call JSON.stringify on all of your data, not just the bases object:
$.ajax({
url: '/TUP/Tflow',
type: 'POST',
data: "json=" + JSON.stringify({baseDetails: bases}), // stringify everything,
dataType: 'text',
async: true,
cache: false
});
Then in your controller, instead of trying to use model binding, we can just deserialize the data ourselves using Json.NET.
Controller:
[HttpPost]
public ActionResult Tflow(string json)
{
// deserialize
var data = JsonConvert.DeserializeObject<JsonFileContentInputs>(json);
// more code
}
Model:
// You can drop these two as we aren't using the modelbinding
// [ModelBinder(typeof(JsonModelBinder))]
// [DataContract]
public class JsonFileContentInputs
{
[JsonProperty(PropertyName = "baseDetails")]
public Dictionary<string, string> BaseDetails { get; set; }
}
Unfortunately, reading the raw stream of the request in the controller seems to be necessary as MVC controllers won't play nice with raw JSON by default. More info here.
EDIT: It looks like you can pass raw JSON to an MVC controller, you just need to specify the ajax dataType as text and ensure the parameter names match up. I've updated my answer accordingly.
Instead of receiving the Class object, you should receive it as string and then serialize into object like below.
public JsonResult Tflow(string basedetails)
{
//some code
var model = new JavascriptSerializer().Deserialize<JsonFileContentInputs>(basedetails);
// Your code
}
Related
I have two json array. I'm trying to send these json array to my controller. When i want to send one of them, everything is fine but i couldnt't send second one. How can i fix it ?
Post function from view
function HobiIlgiAlanKaydetGuncelle() {
var hobiler = $('#Hobiler').val(); // Json array of object
var ilgiAlanlar = $('#IlgiAlan').val();
$.ajax({
url: "/Kullanici/HobiVeIlgiAlanlariniKaydetGuncelle",
type: "POST",
contentType: 'application/json; charset=UTF-8',
dataType: 'json',
data: {hobiler : hobiler,ilgiAlanlar : ilgiAlanlar},
success: function (response) { }
});
}
Controller
[HttpPost]
public async Task<JsonResult> HobiVeIlgiAlanlariniKaydetGuncelle([FromBody] List<HobilerVM> hobiler, List<IlgiAlanlarVM> ilgiAlanlar)
{
//When I put second parameter, both of them comes with null
}
HobilerVM
public class HobilerVM
{
public int id { get; set; }
public string value { get; set; }
}
IlgiAlanVM
public class IlgiAlanVM
{
public int id { get; set; }
public string value { get; set; }
}
The issue is with the following line:
data: {hobiler : hobiler,ilgiAlanlar : ilgiAlanlar}
This is an object in javascript. The equivalent in c# should be:
public class MyData {
public List<HobilerVM> hobiler;
public List<IlgiAlanlarVM> ilgiAlanlar;
}
And then in your controller:
[HttpPost]
public async Task<JsonResult> HobiVeIlgiAlanlariniKaydetGuncelle([FromBody] MyData data)
{
//When i put second parameter, both of them comes with null
}
For more information, check Why does ASP.NET Web API allow only one parameter for POST method?
Web API doesn’t allow you to pass multiple complex objects in the
method signature of a Web API controller method — you can post only a
single value to a Web API action method. This value in turn can even
be a complex object. It is possible to pass multiple values though on
a POST or a PUT operation by mapping one parameter to the actual
content and the remaining ones via query strings.Reference: How to pass multiple parameters to Web API controller methods and How WebAPI does Parameter Binding
Solution
public class ComplexObject {
property List<HobilerVM> Hobiler { get; set; }
property List<IlgiAlanlarVM> IlgiAlanlar { get; set; }
}
[HttpPost]
public async Task<JsonResult> HobiVeIlgiAlanlariniKaydetGuncelle([FromBody] ComplexObject data)
{
//When i put second parameter, both of them comes with null
}
Happy coding, cheers!
I tried your code and it works fine for me except for some things.
First your second parameter has a different ViewModel on what you have posted on your code:
public class IlgiAlanVM
{
public int id { get; set; }
public string value { get; set; }
}
But on your parameter, you are using a different ViewModel:
([FromBody] List<HobilerVM> hobiler, List<IlgiAlanlarVM> ilgiAlanlar)
As you can see here, IlgiAlanVM is different on List<IlgiAlanlarVM>
Second, I just I used the same code but without the [FromBody]. So that would be:
//I already edited your List of Model here on the second parameter from IlgiAlanVM to IlgiAlanlarVM
[HttpPost]
public async Task<JsonResult> HobiVeIlgiAlanlariniKaydetGuncelle
(List<HobilerVM> hobiler, List<IlgiAlanlarVM> ilgiAlanlar)
Lastly, I just make sure it's an array of objects to make sure it will bind nicely on your list of models:
var hobiler = [{
id: 1,
value: 'My Value'
}];
var ilgiAlanlar = [{
id: 1,
value: 'MyValue'
}];
$.ajax({
url: '#Url.Action("HobiVeIlgiAlanlariniKaydetGuncelle", "Kullanici")',
type: "POST",
contentType: 'application/json; charset=UTF-8',
dataType: 'json',
data: JSON.stringify({ hobiler : hobiler, ilgiAlanlar : ilgiAlanlar }),
success: function (response) { }
});
Before I begin, I'd like to say - I realize that this question is very similar to many others that have been posted and answered on this site. I have read through and tried as many solutions as I could find that was related to my issue, and none have worked thus far.
I'm attempting to pass data from my web page to a controller method. The web page is very simple and only needs to capture information input by the user and send it off. I'm using Telerik's Kendo Grid to bind to and organize my data. No matter what I try, though, my AJAX post request never passes parameters forward correctly. When using my browser's debugger, I can see that the parameters being passed into the AJAX request are valid, but by the time they hit my breakpoint in the controller method, they are all either null or default.
Function Containing AJAX Request
function saveShiftDataToServer() {
var grid = $("#myGrid").data("kendoGrid");
var dataSource = grid.dataSource;
var allData = dataSource.data();
var comments = '#Model.Comments';
var loadInfoCorrect = '#Model.LoadInfoCorrect';
$.ajax({
type: "POST",
url: '/Home/SaveData',
data: JSON.stringify({ accessorials: allData, comments: comments, loadInfoCorrect: loadInfoCorrect }),
contentType: "application/json; charset=utf-8",
datatype: "json"
})
}
Controller Method
[AcceptVerbs("Post")]
public ActionResult SaveData(Accessorial[] accessorials, string comments, bool loadInfoCorrect)
{
// Code removed for brevity
}
My Kendo Grid is typed as Accessorial (the first controller method parameter type), so my assumption is that retrieving a collection of all present rows should return an array of that model. Even so, "comments" is a string, but is only ever passed to the controller method as null.
I'm new to ASP.NET Core and Kendo, so I'm sure there is something obvious that I'm missing. Any help would be appreciated!
I appreciate all of the responses! I was able to finally see valid data in my controller by changing the AJAX data type to "text" and simply passing the JSON directly for deserialization server-side. For some reason this is the only way that I've been able to make this work thus far.
AJAX POST Call
function saveShiftDataToServer() {
var grid = $("#accessorialGrid").data("kendoGrid");
var dataSource = grid.dataSource;
var allData = dataSource.data();
var shiftOverview = {
ShiftId: 0,
UserName: "test",
ShiftDate: null,
LoadList: null,
AccessorialList: allData,
LoadInfoCorrect: true,
Comments: ""
};
var jsonData = JSON.stringify(shiftOverview);
$.ajax({
type: "POST",
url: '/Home/SaveData',
data: { json: jsonData },
datatype: "text",
success: function (response) {
alert("111");
}
})
}
Controller Method
[AcceptVerbs("Post")]
public ActionResult SaveData(string json)
{
JsonConvert.DeserializeObject<ShiftOverview>(json); // This produces an object with valid data!
}
You could pass all your data in a ViewModel and get access to it using [FromBody] on action
public class ViewModel
{
public List<Accessorial> Accessorials{ get; set; }
public string Comments { get; set; }
public bool LoadInfoCorrect { get; set; }
}
Ajax:
var model = {};//pass all you data to an object
model.Accessorials = allData ;
model.comments = comments ;
model.loadInfoCorrect = loadInfoCorrect;
var items = JSON.stringify(model);
$.ajax({
url: '/GetAllCustDetails/SaveData',
type: "POST",
data: items,
contentType: 'application/json; charset=utf-8',
//dataType: "json",
success: function (response) {
alert("111");
}
});
Controller:
[HttpPost]
public ActionResult SaveData([FromBody]ViewModel model)
You are passing JSON object which corresponds to C# one like this:
public class Model {
public Accessorial[] Accessorials { get; set; }
public string Comments { get; set; }
public bool loadInfoCorrect { get; set; }
}
Try to declare such class above and adjust your action method this way:
public ActionResult SaveData(Model model)
{
// Code removed for brevity
}
If won't help - make model parameter object and check in debug mode what you are getting from AJAX call.
You juste have to use the [FromBody] attribute in your action method, like this :
[HttpPost]
public ActionResult SaveData([FromBody]Model model)
{
// Code removed for brevity
}
I have an ASP.NET web api built into my MVC application and it currently receives all data accompanying a request as form encoded data.
I receive this as a FormDataCollection object and parse like so:
public string Post(FormDataCollection data)
{
var first = data.Get("FirstName");
//for every supported field.
}
My response is always a JSON string.
This is fine and I want to continue to accomodate this, however I'd like my users to be able to send a JSON with content type header application/JSON as well so that I can support both.
How do I accommodate both in a simple way? Will it have to involve checking the content header and having different code to extract the attributes in each case?
Let the asp.net model binder handle the bindings for you. Define a class that will represent your model:
public class Person
{
public string Firsname{ get; set; }
}
then have your controller action take this view model as argument:
public class PersonController : ApiController
{
public void Post(Person model)
{
...
}
}
Finally you can post using jquery ajax or whatever you pick. e.g
$.ajax({
type: 'POST',
url: '/api/person',
cache: false,
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ Firstname: "John Doe" }),
success: function() {
...
}
});
Try using a model class like below;
public class MyTargetModel
{
public string FirstName { get; set; }
}
public string Post(MyTargetModel model)
{
var first = model.FirstName;
//for every supported field.
}
When I say model class I mean a POCO class. ASP.NET MVC and Web API should be able to parse the request data in to the class as appropriate.
I am facing problem while posting multiple objects via ajax jquery to MVC 4 controller. It has been weeks but I can't seem to find a solution.
I tried several approaches, sometimes the filterModel object is null and sometimes string parameters are null (doesn't matter even if I stringify of if I specify contentType or not)
What I want?
I want to pass three objects: 1. filterModel 2.testparamA 3.testparamB
What should I do to pass all three objects to MVC controller? What do I need to write in data: so I get all 3 object values?
The simplest Controller
[HttpPost]
public JsonResult Test(string testparamA, string testparamB, FilterModel filter)
{
using (RBSystemEntities repository = new RBSystemEntities())
{
return Json(new {
DataList = repository.Items.Select(x => new {x.PKID, x.ItemName}).ToList(),
Result = "OK"
});
}
}
The simplest View
var filterModel = #Html.Raw(Json.Encode(new FilterModel("ItemName", "Pepperoni Pizza")))
//filterModel = JSON.stringify(filterModel);
function testme() {
// post the javascript variable back to the controller
$.ajax({
url: '/Menu/Test',
type: 'POST',
//contentType: 'application/json; charset=utf-8',
data: {
filter: filterModel,
testparamA: 'A value',
testparamB: 'B value'
}, // with this approach I get filterModel null in the controller however testparamA and testparamB has values
data: filterModel, // with this approach I get values for filterModel but I can't pass testparamA and testparamB
success: function (result) {
// TODO: do something with the results
alert('success');
}
});
}
testme();
The simplest FilterModel class
public class FilterModel
{
public FilterModel() { }
public FilterModel(string filtercolumn, string filtervalue)
{
this.FilterColumn = filtercolumn;
this.FilterValue = filtervalue;
this.FilterColumnCriteria = "=";
}
public string FilterColumn { get; set; }
public string FilterValue { get; set; }
public string FilterColumnCriteria { get; set; }
}
Hope you don't mind me posting my comment (which was helpful) as an answer...
If you use stringify as follows it should work...
JSON.stringify({ fm: filterModel, ta: testparamA, tb: testparamA })
#PaulZahra guided me to the right direction.
Below changes fixed my problem:
contentType: 'application/json; charset=utf-8', // uncomment this
data: JSON.stringify({ filter: filterModel, testparamA: 'A value', testparamB: 'B value' }), //stringify whole thing and not just c# class
I am trying to map Json to Dictionary. Earlier I had Dictionary with key of type 'long' . But after realizing for mapping to happen key needs to be of type 'string or 'object'.
Now my type definition in c# is like this :
public class StyleItemCreateCommand
{
public long StyleId { get; set; }
public Dictionary<String, string> SelectedItemToColorMap { get; set; }
}
And json which I am generating is like this:
{"StyleId":"1710","SelectedItemToColorMap":{"1391":"583","21531":"7733"}}
But still somehow it is not being mapped. I am using asp.net mvc controllers as a service, which is being consumed by jquery client.
MVC method signature is as following:
[HttpPost]
public ActionResult Create(StyleItemCreateCommand command)
{
}
The dictionary object is always null. Any help is appreciated. Thanks.
Now after searching around web I found out that ASP.Net MVC is not gonna do it implicitly. Found this answer :
[https://stackoverflow.com/a/15220050/756722]
I think the reason why this is happening is that
"SelectedItemToColorMap":{"1391":"583","21531":"7733"}
is an object and your StyleItemCreateCommand
class defines a Dictionary. Change the class property to:
public object SelectedItemToColorMap { get; set; }
and you should be able to see the values. You can then redesign your class/es.
Alternatively amend the json by surrounding the { } with [ ] converts SelectedItemToColorMap to an array of key value items.
UPDATE
Just tried in asp.net mvc 4 with a simple view
<input type="button" value="click1" id="click1" />
#Scripts.Render("~/bundles/jquery")
<script>
$(function () {
//this is called by a Get action on the controller
$('#click1').click(function (e) {
var jsonObject = { "StyleId": "1710", "SelectedItemToColorMap": { "1391": "583", "21531": "7733" } };
$.ajax({
url: "#Url.Action("Create")",
type: "POST",
data: JSON.stringify(jsonObject),
contentType: "application/json; charset=utf-8",
dataType: "json",
error: function (response) {
//process error;
},
success: function (response) {
//process success;
}
});
});
});
</script>
The above appears in the body of the view. And the controller is
[HttpPost]
public ActionResult Create(StyleItemCreateCommand command)
{
if (command != null) {
string value1 = command.SelectedItemToColorMap["1391"];
string value2 = command.SelectedItemToColorMap["21531"];
Debug.Assert(value1 == "583" && value2 == "7733");
}
return View();
}
Which uses your StyleItemCreateCommand - and it all works. Ok the above uses JSON.stringify(jsonObject) so what format is your json object that is actually coming from the post request? It would be interesting to see the request body (eg using chrome developer tools under the network section).
.Net serialization (not being used here) will wrap requests in a .d object as a security measure against auto execution of code, could this be what is happening?