Post a Complex object to MVC controller using AngularJS - javascript

So I am trying to build a travel-based site where I take some values from the UI and am trying to bind it to an object, and then hit an Http post to a controller, which will then take care of the DB part of the JOB. The problem is the controller will be receiving the post data as a complex object. So my present question is actually multifold.
How do I construct an instance and assign values for such a complex object in my client(AngularJS)code?
Is there any way razor can help us by fetching the object.
Once I have the finished, object if I stringify the JSON will the controller be able to accept that version.
I will be giving some code for reference.
ModelClass:
public class SearchCriteria
{
public Routes Routes { get; set; }
public int JType { get; set; }
public PaxInfo PaxInfo { get; set; }
public string SearchFingerPrintID { get; set; }
}
in the above class Routes is a complex type that needs to be addressed.
Razor Code to import the Model Object
#{
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var SampleReqObj = serializer.Serialize(Model.MyRequest);
}
Some Angularjs code.
$scope.ButtonClick = function () {
var ReqObjFinal = JSON.parse(SampleReqObj);
var post = $http({
method: "POST",
url: "/Main/DemoFormDataSubmit",
dataType: 'json',
data: JSON.stringify(ReqObjFinal),
headers: { "Content-Type": "application/json" }
});
post.success(function () {
$window.alert("Successful Call");
});
post.error(function () {
$window.alert("Not working bro");
});
}
Field that i want to fetch from my UI.
<input type="text" name="Departure" ng-click="DeptLoadList()"
ng-model="Departure" id="Departure" ng-keydown="completeDept(Departure)"
class="form-control" />
I am a beginner for angular-js so thanks in advance for the help!!!

You can create a ViewModel. And use to it your view page head
#Model.YourViewModel
and use page input name ex :
<form action="post" action="YourController/Save">
<input name="YourViewModel.PropName" type="text" value="#YourViewModel.PropName" />
</form>
and you can post to controller ex:
[HttpPost]
function void Save(YourViewModel data){
string value=data.YourProperty;
}
You can create a structure;
public class YourViewModel{
...
public string DataJson{get;set;}
}
and
var pageData=Json.parse(#Model.DataJson);
pageData.YourProp="Your value";
$http({ method: "POST", url: "/YourController/Save", dataType: 'json', data:
pageData, .. })
that object goes to your controller

Related

Null value when posting data from a html form to a c# controller method using a JavaScript function

I am teaching myself how to program and I am having a hard time identifying an issue with my most recent experiment. The following is within the context of an 'ASP.NET Web Application (.NetFramework) C#' and MVC architecture.
I am attempting to post data from a html form to a c# controller method using a JavaScript function.
The JavaScript function invokes the controller method; however, the string passed to the method always has a null value. (I know that the new 'Organisation' instance is successfully created, as new instances appear with an ID in my database yet with a null name - as per my model).
I have searched similar questions and tested contentType: application/json; charset=utf-8 also; however, my issue persists.
The error reads: System.ArgumentNullException: 'Value cannot be null. Parameter name: s' and occurs at var jsonDataParsed = JObject.Parse(jsonData); in my c# controller method.
I was hoping someone may be kind enough to help me :)
The form:
<form id="createOrganisationForm">
<label for="organisationName">Organisation name</label>
<input type="text" id="organisationName" />
<input type="submit" onclick="createOrganisation()" value="submit" />
</form>
The Javascript function:
function createOrganisation() {
var formData = {
"OrganisationName": $("#organisationName").val()
}
$.ajax({
url: '#Url.Action("CreateOrganisation", "Organisations")',
type: "POST",
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
data: JSON.stringify(formData)
})
}
The c# method in a controller:
[HttpPost]
public void CreateOrganisation(string jsonData)
{
var jsonDataParsed = JObject.Parse(jsonData);
var organisationName = jsonDataParsed["OrganisationName"].ToString();
var organisation = new Organisation();
organisation.Name = organisationName;
db.Organisations.Add(organisation);
db.SaveChanges();
}
The model:
public class Organisation
{
public int OrganisationID { get; set; }
public string Name { get; set; }
}
Try this:
function createOrganisation() {
var formData = {
"OrganisationName": $("#organisationName").val()
}
$.ajax({
url: '#Url.Action("CreateOrganisation", "Organisations")',
type: "POST",
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
dataType: 'json',
data: {'formData': formData }
})
}
Thank you everyone for your help. Special thanks go to #Teemu for pointing me towards the final solution.
Below is a working solution; I hope this may help others with future issues.
Key changes:
name="organisationName" atrribute added to input
<input type="submit" edited to <button type="button"
"parameter=" added to data: in ajax request
["OrganisationName"] edited to ["organisationName"] in C# method
Please refer to #Teemu advice in the question's comment section for the rationale behind these changes.
The HTML form:
<form id="createOrganisationForm">
<label for="organisationName">Organisation name</label>
<input type="text" id="organisationName" name="organisationName" />
<button type="button" onclick="createOrganisation()">Submit</button>
</form>
The JavaScript function:
function createOrganisation() {
var formData = JSON.stringify({ organisationName: $("#organisationName").val()})
$.ajax({
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
data: "jsonData=" + formData,
url: '#Url.Action("CreateOrganisation", "Organisations")',
type: "POST"
})
}
Helpful note: the above script should be in the view file (not an external file) if you are using a razor #URL.Action
The c# controller method:
[HttpPost]
public void CreateOrganisation(string jsonData)
{
var jsonDataParsed = JObject.Parse(jsonData);
var organisationName = jsonDataParsed["organisationName"].ToString();
var organisation = new Organisation();
organisation.Name = organisationName;
db.Organisations.Add(organisation);
db.SaveChanges();
}

Get data from ajax to mvc action

I want to send array of objects from ajax call to controller action.
On back-end side I have
container classes:
public class MyContainer
{
public string Id { get; set; }
public Filter[] Filters { get; set; }
}
public class Filter
{
public string Name { get; set; }
public string[] Values { get; set; }
}
and action:
public ActionResult MyAction(MyContainer container)
{
var id = container.Id;
foreach(Filter filter in container.Filters)
{
//Do something
}
}
On front-end side I have
$(document).on('click', 'mySelector', function (event) {
//Create first object
var firstIds = {};
firstIds.Name = "Custom Name 1";
firstIds.Values = GetIds('param1'); //this return an array of strings
//Create second object
var secondIds = {};
secondIds.Name = "Custome Name 2";
secondIds.Values = GetIds('param2'); //another array
var Id = $(this).attr('id'); //id of element
//Add objects to array
var filters = [];
filters.push(firstIds);
filters.push(secondIds);
$.ajax({
method: "GET",
url: baseUrl+"/MyAction",
//traditional: true, //I tried with and without that parameter
data:
{
Id: Id,
Filters: filters
},
contentType: 'application/json',
success: function (res) {
alert('success')
}
});
});
So if I use it like in example on top, container-object in action have Id value and have array of 2 elements in Filters, however both of them have Name and Values as null.
With traditional set to True, I got container.Id set but container.Filters = null.
Any suggestion?
Thank you.
Use a POST request in combination with JSON.stringify() method.
C#
[HttpPost]
public ActionResult MyAction(MyContainer container)
{
var id = container.Id;
foreach(Filter filter in container.Filters)
{
//Do something
}
}
JQUERY
$.ajax({
method: "POST",
url: baseUrl+"/MyAction",
data:JSON.stringify(
{
Id: Id,
Filters: filters
}),
contentType: 'application/json',
success: function (res) {
alert('success')
}
});
Why do you need JSON.stringify() method ?
contentType is the type of data you're sending, so application/json; The default is application/x-www-form-urlencoded; charset=UTF-8.
If you use application/json, you have to use JSON.stringify() in order to send JSON object.
JSON.stringify() turns a javascript object to json text and stores it in a string.
You should use POST method instead of GET in ajax request. As you are posting data. and also your action should have [HttpPost] decorator.
$.ajax({
method: "POST",
url: baseUrl+"/MyAction",
data:
{
Id: Id,
Filters: filters
},
contentType: 'application/json',
success: function (res) {
alert('success')
}
});
Though its an old post, adding my bit to it. I would ask if you are returning a view from the action or not? here it seems like you are not returning a view but just wanting to update some data.
But in case you wanted to return a view, for e.g like showing some product info, then you would just pass the selected product's id to the action method, retrieve the related product information and then pass on this data as a model to the view, and then return the complete view. In this case you don't need a separate ajax call to process the data, instead just do it when you are requesting for the view itself (through the action method).
On the contrary if you already have the view rendered and are just wanting to change the data inside the current view then just resort to an ajax call to get the data without any view.
Hope it helps

Why ASP MVC model binder only accept JSON in POST?

Whenever I send 'GET' with JSON.stringify() using AJAX, model value is always accept null;
Why it can only bind 'POST'?
If it is possible, can I use 'GET' and still bind data to model?
Edit: adding Code Example
JS:
$.ajax({
var modelsend = {
itemname: 'shoe',
itemcolor: 'red',
itemsize: '31',
itemvariety: 'SR-31',
}
type: "POST",
url: "#Url.Action("ShowData", "Controller")",
data: JSON.stringify(modelsend),
dataType: "json",
contentType: "application/json",
success: function (data) {
//do something with data
},
error: function (jqXHR, textStatus, errorThrown) {
//show error
}
});
Model:
public class shoemodel
{
public string itemname { get; set; }
public string itemcolor { get; set; }
public string itemsize { get; set; }
public string itemvariety { get; set; }
}
Controller:
public ActionResult ShowData(shoemodel get)
{
List<DataGrid> fetch = func.getdata(get);
return Json(fetch);
}
Perhaps you are forgetting that GET is used for viewing something, without changing it, while POST is used for changing something. And Get can be used to change something only when you use Querystring. Post on the other hand sends form data directly.
HTTP 'GET' method doesn't support a body in the request. The way to send parameters via 'GET' is using the application/x-www-form-urlencoded format appending them in the URL like this.
http://example.com/?key1=value1&key2=value2

How to access Model Data in Ajax response

I have two forms, consider Form1 and Form2, both are MVC forms only. These forms using two different view models as shown below :
public class Form1ViewModel
{
//some public properties
public string QueryString { get; set; }
}
public class Form2ViewModel
{
//some public properties
public string PreviousQueryString { get; set; }
}
In the controller Post Action I'm writing like this :
[HttpPost]
public ActionResult ProcessForm1(Form1ViewModel form1Obj)
{
//some logic goes here
//I'm preparing Querystring from form1 data and appending to Form2 model like
Form2ViewModel form2Obj=new Form2ViewModel();
form2Obj.PreviousQueryString = form1Obj.QueryString;
return View("Form2",form2Obj) ;
}
And in Form1, I'm submitting through Jquery Ajax as
frm.submit(function(ev) {
var formData = frm.serialize();
$.ajax({
type: "POST",
url: 'ControllerName/ProcessForm1',
data: formData,
success: function(response) {
//Here i need to read the PreviousQueryString and need to push to window.history.pushState()
}
error: function() {}
});
});
In the Ajax success, I need to read the PreviousQueryString from the response.
I knew how to do it client side(using pure JS) but it's my requirement.
How can I do it?
Try this
[HttpPost]
public string ProcessForm1(Form1ViewModel form1Obj)
{
JavaScriptSerializer js = new JavaScriptSerializer();
Form2ViewModel form2Obj=new Form2ViewModel();
form2Obj.PreviousQueryString = form1Obj.QueryString;
return js.Serialize(form2Obj);
}
success: function(response) {
var objResponse = $.parseJSON(response);
if (objResponse.PreviousQueryString != "") {
alert(objResponse.PreviousQueryString);
}
}

Pass object from Javascript to MVC Controller

I have tried many different solutions from other people but have had no luck with either, and I can't seem to be able to debug javascript.
These are some of the variables just so you can see the types. All variables contain data
My view is as follows:
var startTime = new Date();
var images = #Html.Raw(Json.Encode(ViewBag.Images));
var sound = #Html.Raw(Json.Encode(ViewBag.Tones));
var gamePlayed = #Html.Raw(Json.Encode(ViewBag.GamePlayedId));
function SaveGameData()
{
$.ajax({
type: 'POST',
url: '#Url.Action("Play", "Game")',
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: {
GamePlayedId: gamePlayed,
Level: level,
ExpectedImageName: expectedImageArray,
ExpectedToneName: expectedToneArray,
SelectedImageName: selectedImageArray,
SelectedToneName:selectedToneArray,
StartTime: startTimeArray,
EndTime: endTimeArray
},
success: function () {
alert('suc');
},
error: function (args) {
alert('error');
}
});
}
My controller is as follows:
[Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Play(SaveGameViewModel model)
{
// Do something
return Json(new { success = true , message ="successful"});
}
My viewmodel is as follows:
public class SaveGameViewModel
{
public int GamePlayedId { get; set; }
public int Level { get; set; }
public List<string> ExpectedImageName { get; set; }
public List<string> ExpectedToneName { get; set; }
public List<string> SelectedImageName { get; set; }
public List<string> SelectedToneName { get; set; }
public List<DateTime> StartTime { get; set; }
public List<DateTime?> EndTime { get; set; }
}
I keep getting the error message from the ajax alert. I have tried many different things and nothing seems to work. I appreciate any help that you can give. Thanks a lot!
There are at least 2 issues with the code your have shown.
First your method is marked with the [ValidateAntiForgeryToken] attribute but you do not pass the token so the method will never be run. Either remove the attribute, or include it using (this assumes your form includes #Html.AntiForgeryToken())
data: {
__RequestVerificationToken: $('[name=__RequestVerificationToken]').val(),
.... // your other properties
},
Second, your posting a javascript object so you need to remove the contentType: "application/json; charset=utf-8", option (or alternatively you need to stringify the data using JSON.stringify()
Side note: Its unclear from you code why you are manually constructing an object to send to the controller. If your form controls are based on SaveGameViewModel and are correctly generated using the strongly typed html helpers, then you can post it all back using
$.ajax({
data: $('form').serialize(),
....
});

Categories