How to pass a javascript object to a C# MVC 4 controller - javascript

In MVC4, how do you pass a javascript object to a C# controller in AJAX?
Finally I tried this but it did not work.
Javascript Client side:
var myData = {Propr1: '', Propr2: ''};
$.ajax({
type: 'POST',
data: JSON.stringify(myData),
url: '/Home/SubmitMyData',
contentType: 'application/json',
dataType: 'json',
success: alert('Youhou'),
error: alert('not good')
});
C# Server side method:
public ActionResult SubmitMyData(MyParamModel myParam)
{
// Do my stuff here with my parameter
return View();
}
public class MyParamModel
{
string Prop1 { get; set; }
string Prop2 { get; set; }
}
My parameter is always null. I tried to change the contentType but it still not work.
Where are my mistakes? I found some posts but I did not find what I did wrong.
Thanks a lot.

Make sure the property names match between the javascript and the C# model. In your question you had Propr1 and Propr2 for the javascript object, but in the C# model you had Prop1 and Prop2 (missing the "r").
Do not stringify the data before sending it, and do not set dataType to json. MVC can parse just fine with a collection of post parameters without the json serialization in your code.
Omit the contentType, it is not necessary. WebAPI should autodetect this. You can leave it, but it's extraneous.
Make sure the model properties are public.
Javascript Client side:
var myData = {Prop1: '', Prop2: ''}; // #1
$.ajax({
type: 'POST',
data: myData, // #2
url: '/Home/SubmitMyData',
//contentType: 'application/json', #3
//dataType: 'json', #2
success: alert('Youhou'),
error: alert('not good')
});
C# Server side method:
public ActionResult SubmitMyData(MyParamModel myParam)
{
// Do my stuff here with my parameter
return View();
}
public class MyParamModel // #4
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}

The value you pass for the data property should be an object, not a string:
data: myData,
the property names need to match:
var myData = { Prop1: '', Prop2: ''};
you need to use the [FromBody] attribute on your parameter value:
public ActionResult SubmitMyData([FromBody] MyParamModel myParam)
and the properties on your model type need to be public:
public class MyParamModel
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}

Related

How to bind JavaScript array of JSON objects to a List of objects in viewModel. dotnetcore mvc

This is my javascript array of json objects
var pObjIds = [{"Id":"2","Name":"small"},{"Id":"3","Name":"average"}]
I have collected my form fields into a FormData() like this
var form = new FormData($(this)[0]);
I have appended the array of json objects to the FormData like this
form.append("Availability", pObjIds);
I have a ViewModel with a property
public List<Item> Availability { get; set; }
The Item class looks like this
public class Item
{
[JsonProperty(PropertyName = "Id")]
public int Id { get; set; }
[JsonProperty(PropertyName = "Name")]
public string Name { get; set; }
}
My controller method to receive the form data is
[HttpPost]
public IActionResult AddSupplier(SupplierVM vm, List<Item> list)
{
if (ModelState.IsValid)
{
}
return View("AddSupplier", vm);
}
My intention is to bind the appended Availability in the formData to the property
public List<Item> Availability { get; set; } in the ViewModel.
The above code is what I have tried but its not binding. Always returning count=0 for Availability.
Are my doing something wrong or is there a better way i can do it?
I have used FormCollection in controller but still not seen the appended array of json objects but i can log it in the console and see that it is appended successfully.
I am using dotnet core 3.0 mvc.
Thanks in advance.
This is the client side code that calls the AddSupplier
var form = new FormData($(this)[0]);
form.append("Availability", pObjIds);
$.ajax({
type: 'POST',
url: '/supplier/addsupplier/',
data: form,
processData: false,
contentType: false,
datatype: 'json',
success: function (result) {
if (result.status == false) {
swal({
title: 'Error!',
text: result.msg,
icon: "error",
button: "Ok",
});
}
},
error: function () {
swal({
title: "Unknown Error!",
text: "unable to process request!",
icon: "error",
button: "Ok",
});
}
});
I have a ViewModel with a property
public List<Item> Availability { get; set; }
My intention is to bind the appended Availability in the formData to the property public List<Item> Availability { get; set; } in the ViewModel.
To achieve your requirement, you can try to append values for FormData object like below.
var form = new FormData($(this)[0]);
//form.append("Availability", pObjIds);
$(pObjIds).each(function (index, el) {
form.append(`Availability[${index}].Id`, el.Id);
form.append(`Availability[${index}].Name`, el.Name);
});
$.ajax({
type: 'POST',
url: '/supplier/addsupplier/',
data: form,
processData: false,
contentType: false,
datatype: 'json',
success: function (result) {
// code logic here
//...
In controller action AddSupplier
[HttpPost]
public IActionResult AddSupplier(SupplierVM vm)
{
//code logic here
View model class SupplierVM
public class SupplierVM
{
public int Id { get; set; }
//other properties
public List<Item> Availability { get; set; }
}
Test Result

Send Multiple objects with Ajax to the ASP.NET MVC controller

I have one ViewModel that contains three Collection of ExternalProjectViewModel, CertificateUniverSityViewModel, CertificateInstitutionsViewModel.
CreateFreelancerProfileViewModel.cs
public class CreateFreelancerProfileViewModel : BaseViewModel
{
// More ...
public List<ExternalProjectViewModel> ExternalProjects { get; set; }
public List<CertificateUniverSityViewModel> CertificateUniverSitys { get; set; }
public List<CertificateInstitutionsViewModel> CertificateInstitutions { get; set; }
}
My Ajax code:
$('#Controller').on('click','#SaveProfile',
function() {
debugger;
var CertificateInstitutions =
JSON.parse(localStorage.getItem("CertificateInstitutionsListLocal"));
var CertificateUniverSitys =
JSON.parse(localStorage.getItem("CertificateUniverSitysListLocal"));
var ExternalProjects =
JSON.parse(localStorage.getItem("ExProjectListLocal"));
$.ajax({
url : '#Url.Action(MVC.Freelancer.Profile.CreatePrfile())',
method: "POST",
data: {
ExternalProjects,
CertificateUniverSitys,
CertificateInstitutions
}
});
});
When I Want Send Objects to Controller, First Get It from LocalStorage
And After Get it Send it to Controller Action:
public virtual ActionResult CreatePrfile(CreateFreelancerProfileViewModel viewModel)
When I see viewModel Values Show My Objects Count That is 2 but Objects Properties is null.so that my server object properties name equally with the client Object properties name.
LocalStorage Values
[{"ExternalProjects":{"Name":"wqeqwe","Body":"wqewqe","Url":‌​"wqewqe"}}]
[{"CertificateUniverSity":{"Name":"sad","Description":"sadas‌​","DateOfGets":"sad"‌​,"CertificateType":"‌​2","Field":"sadasd",‌​"UniName":"sad","Cer‌​tificateUniverSityLe‌​vel":"2"}}]
You could send them as JSON payload:
$.ajax({
url : '#Url.Action(MVC.Freelancer.Profile.CreatePrfile())',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify({
externalProjects: ExternalProjects,
certificateUniverSitys: CertificateUniverSitys,
certificateInstitutions: CertificateInstitutions
}),
success: function(result) {
alert('data sent successfully');
}
});
This assumes that the instances you got from the localStorage of those 3 variables represent javascript arrays with the corresponding objects in it.

AJAX call with parameters not working

I've got troubles making an ajax post with parameters to my controller. While this works:
$.post("../api/vorgang/blubb");
[HttpPost]
[Route(#"blubb")]
public void blubb()
{
// do amazing things here
}
The method is not being hit when I extend it for parameters:
$.post("../api/vorgang/blubb", { param1: "param1", param2: "param2"} );
[HttpPost]
[Route(#"blubb")]
public void blubb(string param1, string param2)
{
// method is not hit, why oh why
}
// the request text
param1=param1&param2=param2
I see that it results in
404: "no HTTP-Resource could be found that fits the URI http://localhost:49412/api/vorgang/blubb.
I have tried changing the ajax call to
$.post("../api/vorgang/blubb", JSON.stringify({
param1: "param1",
param2: "param2"
}));
this changes the request text to
{"param1":"param1","param2":"param2"}
but the controller still does not get hit.
I'd be thankful for a hint!
The way you are passing parameter's with HttpPost, I am not sure if it's gonna work. Was going thru FromBody approach mentioned here.
Alternatively, you could try creating a Model object and let the MVC do the heavy lifting.
public class TestController : ApiController
{
[HttpPost]
public void blubb(Parameters param1)
{
// method is not hit, why oh why
}
}
public class Parameters
{
public string param1 { get; set; }
public string param2 { get; set; }
}
Your AJAX call:
var _parameters = {
param1: "param1",
param2: "param2"
};
$.ajax({
type: "POST",
url: "/api/Test/blubb",
cache: false,
data: JSON.stringify(_parameters),
contentType: "application/json; charset=utf-8",
success: function (data) { console.log("Success"); }
});
Final Result :
Not sure, how much will it help!

ajax post on MVC .NET does not pass array correctly

I have a simple modal that uses select2 to get a list of Products from the server. User can multiple choose products and hit Ok to refine a search.
My following setup grabs the data from the modal and does an ajax call against a Controller action with a strongly typed view model that matches what the JS is trying to send via the ajax call.
Ajax:
var exploreFilters = {
"type" : exploreType,
"products" : $('#s2id_select2-products').select2('data'),
"locations" : $("#page-report__data").data("criteria__locations"),
"companies" : $("#page-report__data").data("criteria__companies"),
"usertypes" : $("#page-report__data").data("criteria__usertypes"),
"groupusers" : $("#page-report__data").data("criteria__groupusers"),
"datestart" : $("#page-report__data").data("criteria__datestart"),
"dateend" : $("#page-report__data").data("criteria__dateend")
};
$.ajax({
dataType: "html",
type: "POST",
url: "/Report/Group/FilteredView",
data: exploreFilters,
success: function(html) {
if($.trim(html) === "")
$targetSection.html('<div class="page-report__empty">No data found. Please adjust your search filters and try again.</div>');
else
$targetSection.html(html);
},
error: function(xhr, text, err) {
if(text === "timeout")
$targetSection.html('<div class="page-report__empty">The request timed out. Please try again.</div>');
else
$targetSection.html('<div class="page-report__empty">There has been an error.</div>');
}
});
Right before the ajax call goes to the controller I inspect the content and structure of exploreFilters:
Here is how the form data looks on the POST request:
On the other side I got a controller which takes a strongly-typed parameter with a structure similar to what exploreFilters has:
public ActionResult FilteredView(ReportCriteriaViewModel criteria)
{
throw new NotImplementedException();
}
And my strongly-typed view model:
public class ReportCriteriaViewModel
{
public ProductViewModel[] Products { get; set; }
public string[] Locations { get; set; }
public string[] Companies { get; set; }
public string UserTypes { get; set; }
public string GroupUsers { get; set; }
public string DateStart { get; set; }
public string DateEnd { get; set; }
}
public class ProductViewModel
{
public Guid Id { get; set; }
public string Text { get; set; }
}
Once the controller action gets hit I can see that DateStart and DateEnd have been successfully bound but not my list of products.
I cannot change the datatype on the json request, it has to be html because my controller action is going to be returning html.
I've tried changing the capitalization on Id and Text, JSON.stringify (which actually makes the dates not bind anymore)
What am I doing wrong?
Try to add contentType: "application/json" in your Ajax request
$.ajax({
...
contentType: "application/json",
...
});
The problem is in how you are serializing the list:
products[0][id]
products[0][text]
You need to send your list in this format:
products[0].id
products[0].text
id and text should be properties, without the [] otherwise it is treated as an index to a two-dimensional array.
You should try
contentType: "application/json; charset=utf-8"
in the options of the $.ajax call
$.ajax({
dataType: "html",
type: "POST",
url: "/Report/Group/FilteredView",
data: exploreFilters,
contentType: "application/json; charset=utf-8" ....

How to send AJAX/Jquery object to Controller (discrepancy) MVC4

I have had this confusion for a while and it's because of the following reason:
I am trying to send a jquery object
var myObject = {
Title: $('#Title').val(),
Title2: $('#Title2').val(),
Title3: $('#Title3').val(),
};
through an ajax call
$.ajax({
data: { myObjectName = myObject
},
datatype: "json",
url: "myUrl",
cache: false,
error: function (ts)
{//handle error},
success: function (result)
{//handle success}
});
I'm receiving my object in my controller like this:
public ActionResult MyAction(ObjectType myObjectName)
However, when receiving the object from javascript, it does not recognize it as such and just instantiates a new ObjectType.
I know I can send it as a string, serialize it if I put my object inside a form, etc...what I want to know is why this approach seems to work for me sometimes (I have gotten it to work with other ObjectType(s)) and in other instances it doesn't. Does it have anything to do with how complex the object is? Sending an incomplete object? (The latter one doesn't seem to be it since I have sent 'incomplete' objects and the empty fields just get instantiated with null)
ANY insight would be appreciated. Thanks!
Change your code to;
$.ajax({
data: myObject,
datatype: "application/json",
type: "POST",
url: "myUrl",
cache: false,
error: function (ts)
{//handle error},
success: function (result)
{//handle success}
});
Notice that the type is a POST which means you will also need to add [HttpPost] to your ActioResult.
As long as ObjectType is a class with the fields
public class ObjectType
{
public string Title { get; set; }
public string Title2 { get; set; }
public string Title3 { get; set; }
}
Your current code is attempting to bind your model to something which would resemble
public class SomeObject
{
ObjectType myObjectName { get; set; }
}
public class ObjectType{
public string Title { get; set; }
public string Title2 { get; set; }
public string Title3 { get; set; }
}

Categories

Resources