I am trying to post a Json string, deserialize it, and then save it to a SQL database using MVC entity framework. Here is my model:
[Serializable]
public partial class employee
{
public int id { get; set; }
public string netid { get; set; }
public string enumber { get; set; }
public string peoplesoft { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string mi { get; set; }
public string prefix { get; set; }
public string suffix { get; set; }
public string email { get; set; }
public string tenure_year { get; set; }
public byte tenure_indicator { get; set; }
public Nullable<System.DateTime> hire_date { get; set; }
public string updated_by { get; set; }
public System.DateTime created_at { get; set; }
public System.DateTime updated_at { get; set; }
public string gender { get; set; }
public Nullable<System.DateTime> birth_date { get; set; }
}
My controller:
[HttpPost]
public ActionResult Create(ChadAPI.Models.Lookup.employee employee)
{
if (ModelState.IsValid)
{
db.employees.Add(employee);
db.SaveChanges();
return new JsonResult() { Data = employee, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
return Content("Model State Invalid");
}
And My View:
#model ChadAPI.Models.Lookup.employee
#{
ViewBag.Title = "Create";
}
<script src="~/Scripts/jquery-1.10.2.intellisense.js"></script>
<h2>Create</h2>
<input type="submit" id="Save" value="Save" />
<script>
$(function () {
$("#Save").click(function () {
alert("clicked!");
var employee = {
id: 77,
netid: 'caw63231',
enumber: '00000',
peoplesoft: '1012481',
firstname: 'Christian',
updatedby: 'caw63231',
createdat: '10/14/2013 3:02:46 PM',
updatedat: '10/14/2013 3:02:46 PM'
}
$.ajax({
type: "POST",
url: "Employees/Create",
data: employee,
success: function (data) {
console.log("success!")
},
dataType: "json",
traditional: true
});
});
});
</script>
When I press the button in the view nothing happens, and using Fiddler I can see that no JSON is passed whatsoever. What am I doing wrong?
MVC will automatically map the JSON request to your Actions parameters. The action you have written will be expecting a string object and you are trying to post it a JSON object containing an array.
You should update your action to receive an Employee object and post a JSON representation of this to the action. Like so:
$(function () {
$("#Save").click(function () {
var employee = {
id: 77,
netid : 'cfw22511',
enumber : '000000',
peoplesoft : '2322381'
//..... Add the rest of your data to the JSON object
};
$.ajax({
type: "POST",
url: "/Employees/Create",
data: employee,
success: function(data){
alert(data.Result)
},
dataType: "json",
traditional: true
});
});
});
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CreateChadAPI.Models.Lookup.employee employee)
{
if (ModelState.IsValid)
{
db.employees.Add(employee);
db.SaveChanges();
db.SaveChanges();
return new JsonResult() {Data = employee, JsonRequestBehavior = JsonRequestBehavior.AllowGet};
}
return Content("Model State Invalid");
}
Json is an object parsed as string, when sending this object to the server, MVC automatically convert it to the object, you don't have to do this by your self, so:
public ActionResult Create(ChadAPI.Models.Lookup.employee jsonemployee)
on the other side, create the same object' in Js:
var emp=new Object()
{
id:777,
}
also, check if your javascript code is running
Related
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:
I have the following viewModel:
public class ProfileLocalizationViewModel
{
public ProfileViewModel Profile { get; set; }
public virtual string LanguageCode { get; set; }
public string Description { get; set; }
}
with the Profile object looking like:
public class ProfileViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsOutlet { get; set; }
public bool IsWholesaler { get; set; }
public bool IsProducer { get; set; }
public List<ProfileLocalizationViewModel> Localizations { get; set; }
}
From the client, I'm sending the following JSON:
{"Profile":{"Id":-1,"Name":"New Profiledsa","IsOutlet":false,"IsWholesaler":false,"IsProducer":false,"Localizations":null},"LanguageCode":"en","Description":"Description for selected language","__ko_mapping__":{"ignore":[],"include":["_destroy"],"copy":[],"observe":[],"mappedProperties":{"Profile.Id":true,"Profile.Name":true,"Profile.IsOutlet":true,"Profile.IsWholesaler":true,"Profile.IsProducer":true,"Profile.Localizations":true,"Profile":true,"LanguageCode":true,"Description":true},"copiedProperties":{}}}
Which gets parsed by Chrome like:
And on the server, when I try to receive a ProfileLocalizationViewModel, the values received are all null:
Any idea why this happens? Any advice greatly appreciated.
Client ajax call:
self.saveProfile = function (model, event) {
model.ItemForEditing.LanguageCode = self.SelectedLanguage.Code().toLowerCase();
var preview = ko.toJSON(model.ItemForEditing);
if (validateForm()) {
$.ajax({
type: "POST",
url: urlSaveProfile,
data: ko.toJSON(model.ItemForEditing),
contentType: 'application/json',
async: true,
beforeSend: function ()
success: function (result) {
// Handle the response here.
self.pushProfile(ko.mapping.fromJS(result.Data));
addContainer.modal('hide');
}
});
}
};
And inside preview, right before the call, there's the JSON...
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.
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"/>
I am having some challenges with validation in my ASP.NET MVC3 project when using jQuery and AJAX to post back data from a partial view.
Adding validation to the NoteText field within my partial view results in "$('#noteAdd').submit" event failing to trigger and my form posting directly to the controller. Removing the validation results in the expected behaviour.
I was hoping somebody might be able to shed some light over what's happening here, why it's happening and my provide some advice on how to resolve the issue and I've included my partial, controller, JS and view below.
My Partial
[Bind(Include = "NoteId,NoteText,Date,SourceId,Username,TypeId,ItemId,Processed")]
[MetadataType(typeof(NotePartial_Validation))]
public class NotePartial
{
public int NoteId { get; set; }
public string NoteText { get; set; }
public DateTime? Date { get; set; }
public int? Source { get; set; }
public string Username { get; set; }
public int ItemId { get; set; }
public int TypeId { get; set; }
public IEnumerable<NotePartial> ExistingNotes { get; set; }
}
public class NotePartial_Validation
{
[HiddenInput(DisplayValue = false)]
public int NoteID { get; set; }
[Required]
public string NoteText { get; set; }
[HiddenInput(DisplayValue = false)]
public int ItemId { get; set; }
[HiddenInput(DisplayValue = false)]
public int TypeId { get; set; }
}
}
My Controller
public class NoteController : Controller
{
[HttpPost]
public ActionResult Create(NotePartial model)
{
try
{
NoteMethods.CreateNote(model.NoteText, SessionManager.Current.ActiveUser.Username, model.ItemId, SessionManager.Current.ActiveUser.Company);
return Json(new { s = "Success" });
}
catch (NoPermissionException)
{
return Json(new { s = "No permission" });
}
}
}
My View
#model EF.NotePartial
#{using (Html.BeginForm("Create", "Note", new { area = "" }, FormMethod.Post, new { id = "noteAdd" }))
{
#Html.TextAreaFor(m => m.NoteText, new { #class = "note-input" }) //note-input
#Html.ValidationMessageFor(model => model.NoteText)
<input type="submit" value="Send" />
}}
<script type="text/javascript">
$(function () {
$('#noteAdd').submit(function () {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
error: function (xhr, ajaxOptions, thrownError) {
alert('An error occured when processing this request:\r\n\r\n' + thrownError);
},
success: function (result) {
alert(result.s);
}
});
// it is important to return false in order to
// cancel the default submission of the form
// and perform the AJAX call
return false;
});
});
put partial keyword on your class :
public partial class NotePartial