Pass custom model *with List<CustClass>* through ajax call - c#

I am having a bit of trouble passing my json string to the jsonResult within my controller. All the first-level variables come in fine except for the List<CustClass> which always returns a default empty list when it should be filled with the list of objects (List<>) I passed in.
The ajax call that looks along the lines of:
var model = {
Id: id,
Name: name,
Items: [{
Name: itemName[0],
Color: itemColor[0]
},{
Name: itemName[1],
Color: itemColor[2]
}]
};
$.ajax({
url: "/#path",
type: "POST",
data: JSON.stringify(model),
dataType: "json",
contentType: "application/json; charset=utf-8",
cache: false,
traditional: true
});
With my C# model looking along the lines of
public class MyModel
{
public int Id { get; set; }
public string Name { get; set; }
public class Item {
public string Name { get; set; }
public string Color { get; set; }
}
public List<Item> Items = new List<Item>();
}
And the result:
[HttpPost]
public JsonResult MyResult(MyModel model)
{
// Do Stuff
}
What am I doing wrong here? Is this even possible to do?

Dont instantiate your list to map it properly. Since binding of model takes place after instantiation of the class.
public class MyModel
{
public int Id { get; set; }
public string Name { get; set; }
public class Item {
public string Name { get; set; }
public string Color { get; set; }
}
public List<Item> Items {get; set;}
}

Related

Ajax form post not binding to object in ASP.net core 6 MVC

I cannot figure this out. I have similar code in other areas of my project that works fine. What am I missing?
Why is studentDTO object null?
The Controller Action
[HttpPost("SaveStudent")]
public async Task<IActionResult> SaveStudent(
[Bind(Prefix = "Student")][FromForm] StudentDTO studentDTO
)
{
// blah blah
}
The Class
public class StudentDTO
{
public Guid StudentID { get; set; }
public Guid AccountID { get; set; }
public int TuitionID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public decimal AnnualTuitionCost { get; set; }
public int TuitionMonths { get; set; }
public string StartDate { get; set; }
public string EndDate { get; set; }
}
The AJAX call
var formData = $("#addEditStudentFrm").serialize();
console.log(formData);
$.ajax({
url : '/api/blah/SaveStudent/',
dataType: 'json',
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
data: formData,
type: 'POST',
success: function (result) {
// blah blah
},
error: function (result) {
// blah blah
}
});
The Request
I am hitting the controller action, but I'm not getting the form data. Suggestions?
If I remove [FromForm] I get a response of "415 Unsupported Media Type"
I have been using the information provided here to no avail:
https://learn.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-6.0
Figured it out. Prefix needed to be Student. and not Student_ in the name attribute of the form elements:

MVC ajax POST info about ApplicationUser

I have an entity that consists of ApllicationUser as a foreign Key:
public class Trades
{
public int ID { get; set; }
public double Price { get; set; }
public double Volume { get; set; }
public string InstrumentName { get; set; }
public ApplicationUser User { get; set; }
}
Then i try to post a trade using AJAX.
var tradeData = {
"Price": 1,
"Volume": 1,
"InstrumentName": "instrumentName",
"User": "#User.Identity.Name"
};
$.ajax({
url: "/api/TradesAPI/",
method: "POST",
data: JSON.stringify(tradeData),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function () {
alert('executed!');
},
error: function (error) {
alert("Transacion has not been executed");
}
});
Unfortunetely ApplicationUser is not being serialised to ApplicationUSer as it is posted a string. What have I done wrong? Thanks for any help in advance.
If we have a class "A" that contains a reference to "B" and this "B" has also a reference to "A" (even if not direct), the proccess of serialization doesn't work. It's like an "infinite loop".
I suggest you change the ApplicationUser(type of User) to string and use it to get the model (on code-behind), if you need it.
If you need to get the user from within the controller, use the User property of Controller.
If you need it from the view, would populate what you specifically need in the ViewData, or you could just call User.
Ex. #User.Identity.Name
Thank you Indrit Kello. I changed my model so I have
public class Trades
{
public int ID { get; set; }
public double Price { get; set; }
public double Volume { get; set; }
public string InstrumentName { get; set; }
public string UserId { get; set; }
}
I decided to take info about user on server in API controller insted of taking data about User in a View.
public void CreateTradeAPI(Trades trade)
{
trade.UserID =User.Identity.Name;
_context.UsersTrades.Add(trade);
_context.SaveChanges();
}
And I have what i wanted :)

Issue while sharing the same model with multiple partial views

I am facing an issue while sharing the same model between a view and its multiple partial views.
I have a main view MainView which has its own model MainViewModel. In this MainView, I have a few controls which are bound to properties in the MainViewModel.
On a button click I am opening a partial view from this MainView. Say SubView1. It is a partial view and it consists of several controls which are bound to the properties in MainViewModel. At some point user enters some values in this partial view SubView1 and clicks on a button to submit the data. During this time, I am posting the data to the controller like this :
$.ajax({
type: "POST",
url: "/MainViewController/SomeAction",
data: JSON.stringify({ dataObj: dataArray }),
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
success: function (msg) {
ServiceSucceeded(msg);
},
error: function () {
return "error";
}
});
SomeAction Code :
public void SomeAction(List<ModelClass> dataObj)
{
if(dataObj != null)
{
}
}
My doubt is that, since the controls in this partial view are already bound to the MainViewModel properties, do I still need to pass it using json like this? Or can the data be directly accessed from the MainViewModel during a post method? I tried to pass the model to the post method, but its data remains as null.
My MainViewModel class :
private EnvironmentVariableTarget m_Markers;
private List<SelectListItem> startLocation = new List<SelectListItem>();
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string JobId { get; set; }
public string TaskId { get; set; }
public string TrajName { get; set; }
public int UserId { get; set; }
public DateTime StartPeriod { get; set; }
public DateTime EndPeriod { get; set; }
public int Aggr { get; set; }
public string MailId { get; set; }
public string StartLocation { get; set; }
public string EndLocation { get; set; }
public string lblGridHeaderTask { get; set; }
public string lblGridHeaderTraj { get; set; }
public string lblGridAggr { get; set; }
public string lblGridStartDate { get; set; }
public string lblGridEndDate { get; set; }
public int StartLocId { get; set; }
public int EndLocaId { get; set; }
public MySqlConnection databaseConnectionObj;
private MySqlCommand sqlCommandObj;
private Logger m_Logger;
These are the bound properties which I need :
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string TrajName { get; set; }
When user clicks on add to list, I am adding to javascript array like this :
var obj = { TaskId: ccount, TrajName: $('#drpTraj').find(":selected").text(), StartTime: $('#txtStartTime').val(), EndTime: $('#txtEndTime').val(), Aggr: $('#drpAggrInterval').find(":selected").text() }
dataArray.push(obj)
I am keeping this array in js and when user clicks submit I am passing the entire array back to the controller. My question is at this point, I am getting the control's value. I am asking whether I can get the bound value at this time.
ie the controls drpTraj, txtStartTime and drpAggrInterval are already bound to viewmodel properties.
My questions are :
Is there any other way to tackle this scenario?
If I want to pass one more data which is not bound to the viewmodel, then how to pass that?
If databinding is not used, then is this the way to pass data ie using JSON?
Check Below Code for passing model data through JSON :
//Your Master Model Properties
public partial class YourMasterModel
{
public List<YourModel> YourMasterModelList{ get; set; }
public YourModel YourModel{ get; set; }
}
//Your Model Properties
public partial class YourModel
{
public int Id { get; set; }
public string Param1 { get; set; }
public string Param2 { get; set; }
public int[] SelectedListOptions { get; set; }
}
//Your Ajax Call along with Your Model
$("#Addbtn").click(function () {
var YourModel = {
"Id": $("#hdnId").val(),
"Param1": $("#Param1").val(),
"Param2": $("#Param2").val()
};
var YourMasterModel = {
"YourMasterModelList": //You have to create a list of YourModel through for loop and stored into a list variable and pass this to here
"YourModel": YourModel
};
$.ajax(
{
url: '/MainViewController/SomeAction/',
type: "Post",
async: false,
dataType: "html",
data: JSON.stringify(YourMasterModel),
contentType: "application/json;charset=utf-8",
success: function (result) {
$("#YourResultDiv").html("");
}
});
});
//Your Action with your model
/// <summary>
/// Add Data
/// </summary>
/// <param name="YourModel"></param>
/// <returns></returns>
[HttpPost]
public ActionResult AddDataWithModel(YourMasterModel objYourMasterModel)
{
//Here you will get the list of yourmodel data
var listofdata=objYourMasterModel.YourMasterModelList;
return PartialView("_YourPartialView");
}
Hope this will help you !!
If you want to pass parameter into post method use below technique:
#using (Ajax.BeginForm("action", "controller", null, new AjaxOptions() { OnSuccess = "" }, new { #class = "form-horizontal", role = "form", id = "id" }))
{
//put partial view code into the these brackets
}
If you want to do ajax, then you need to pass data into data:
// all columnname same name as data model of action
data: {
"columnname1": "John",
"columnname2": "Smith",
"columnname2": "man",
"columnname3": 32
}

Trouble with Knockout JSON Model parsing MVC 4 Controller

So I have a ViewModel:
public class PrelimViewModel
{
public int? PrelimId { get; set; }
public int JobId { get; set; }
public string Code { get; set; }
public string Description { get; set; }
public string Comment { get; set; }
public string Unit { get; set; }
public int? Qty { get; set; }
public decimal? BidPrice { get; set; }
public bool Accepted { get; set; }
public int? OriginalPrelimId { get; set; }
public string Option { get; set; }
public List<RefCodeViewModel> Codes { get; set; }
public List<UnitViewModel> Units { get; set; }
public List<OptionLetterViewModel> Options { get; set; }
}
A GetPrelim controller method that returns List<PrelimViewModel>
A ko.mapper of the List of PrelimViewModel client side:
viewModel = ko.mapping.fromJS({ Prelims: data });
ko.applyBindings(viewModel);
Do some work, ready to save:
function savePrelims(elem) {
var $form = $(elem).parents('form');
$.ajax({
url: $form.attr('action'),
type: "POST",
data: ko.toJSON(viewModel),
datatype: "json",
contentType: "application/json charset=utf-8",
success: function(data) { toastr.success('Options Saved!'); },
error: function(data) { }
});
}
And I cannot get my MVC Method to parse the JSON:
public void AddPrelims(List<PrelimViewModel> Prelims)
You have wrapped your list into the Prelims property in your KO viewmodel, but on the server side you are expecting just a list not with an object which has the list in its Prelims property.
So to fix this you just need to send the list in your ajax request:
data: ko.toJSON(viewModel.Prelims()),
However you don't necessary need to wrap your list if you won't have any additional properties on your viewmodel, because you can just do:
viewModel = ko.mapping.fromJS(data);
ko.applyBindings(viewModel);
And then in your view you can bind to $data which is refering the current viewmodel which will be your array:
<div data-bind="foreach: $data">
...
</div>
And in this case you don't have to change your ajax call and data: ko.toJSON(viewModel), should work fine.
However this foreach: $data is kinda strange and it is not the best solution so you are probably better if you stick to your original approach with ko.mapping.fromJS({ Prelims: data }); and sending the correct data back to your controller.

How to send nested json object to mvc controller using ajax

I am working on an ASP.NET MVC application. I have the following view model in c#:
public class ContactModel
{
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
}
public class PersonModel
{
public ContactModel Contact;
public PersonModel()
{
Contact = new ContactModel();
}
public string FirstName { get; set; }
public string LastName { get; set; }
public string Profession { get; set; }
}
Now i have the same json model at client side which i want to post to server. I am using following jquery ajax:
$.ajax({
url: "address to controller",
type: "post",
data: JSON.stringify(data),
contentType: "application/json",
success: function () {
alert("data saved successfully");
}
});
But only PersonModel properties are get mapped but Contact properties are null. Can anybody please tell me what i am missing??
You need for format your string to proper json -
Say if you model is -
public class ContactModel
{
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
}
public class PersonModel
{
public ContactModel Contact { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Profession { get; set; }
}
Then you AJAX Post should be like this -
<script>
$(function () {
$('#click1').click(function (e) {
var studentData = {
"FirstName": "Rami",
"LastName": "Vemula" ,
"Contact": { "City": "Hyd"}
};
$.ajax({
url: "#Url.Action("Submit")",
type: "POST",
data: JSON.stringify(studentData),
contentType: "application/json; charset=utf-8",
dataType: "json",
error: function (response) {
alert(response.responseText);
},
success: function (response) {
alert(response);
}
});
});
});
</script>
Then output is going to be -
Create a instance of ContactModel and assign it to contact under PersonModel after creating instance of PersonModel.
Please let me know in case of any clarification needed
If you are using #html helper for properties then form.serialize() method will bind all the properties otherwise if you are using html elements like <input> the assign their name property same as model property.
<input type="text" name="Contact.FirstName" value="#Model.Contact.FirstName"/>

Categories

Resources