can't pass data to controller via ajax - ajax

I have the following model class:
[Serializable]
public class SearchHomeModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Company { get; set; }
public string Title { get; set; }
}
I have the following controller code:
public ActionResult DataTableUserList(SearchHomeModel search, UserListType type, int iDisplayStart, int iDisplayLength, string sEcho)
and the following client part:
var search = {};
search.FirstName = 'aa';
search.LastName = 'bb';
search.Company = 'kkk';
search.Title = 'aaaawww';
fnServerData: function (sSource, aoData, fnCallback) {
aoData.push({ "name": "type", "value": "All" });
aoData.push({ "name": "search", "value": search });
$.ajax({
dataType: 'json',
type: "POST",
url: sSource,
data: aoData,
but I look at debugger on server-side I see that type="All" (it's correct), but search is null. Why and how to pass data to search object from ajax?

You may or may not find this useful, but I did this so I could directly pass JSON back and forth from the controller. I had come across this approach HERE while playing around with Knockout.js.
I created this attribute
public class FromJsonAttribute : CustomModelBinderAttribute
{
private readonly static JavaScriptSerializer serializer = new JavaScriptSerializer();
public override IModelBinder GetBinder()
{
return new JsonModelBinder();
}
private class JsonModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var stringified = controllerContext.HttpContext.Request[bindingContext.ModelName];
if (string.IsNullOrEmpty(stringified))
return null;
return serializer.Deserialize(stringified, bindingContext.ModelType);
}
}
}
This is my controller code:
[HttpPost]
public ActionResult Gifts([FromJson] List<GiftModel> gifts, [FromJson] string guid)
{
}

Related

In ASP.NET Core 6 MVC - passing list of object to controller with model object

I have a model class like this:
public class DataModel
{
public int CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public List<ViewModel> ViewModel { get; set; }
}
public class ViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
}
In ASP.NET Core 6.0 MVC, from js file posting data as shown here:
let postedModel = {
CreatedBy :null,
CreatedDate :null,
ViewModel : []
}
postedModel.CreatedBy = "some id";
postedModel.CreatedDate = "today date"
$(".form-fieldset").each(function () {
let formObject = {};
$('form').find('input').each(function (index, element) {
//In cshtml Name attribute given without form index
formObject[$(element).attr('name')] = $(element).val();
})
postedModel.ViewModel.push(formObject)
}
$.ajax({
url: '/ApiController/SaveData',
type: 'POST',
crossDomain: true,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify(postedModel),
async: false
})
My api controller looks like this:
public async Task<IActionResult> SaveData([FromBody] DataModel postedModel)
{
}
but I am getting null in the api controller.
What am I doing wrong? Please help.

How to pass IEnumerable model to controller

My model is
public class InvBrojeviModel
{
public int rb { get; set; }
public int id_ulaz_sredstava { get; set; }
public int? inv_broj { get; set; }
public string serijski_broj { get; set; }
public int id_sifra { get; set; }
}
I'm trying to pass this model to controller with an ajax call
var m = '#Html.Raw(Json.Encode(Model))';
$.ajax({
url: "/Ulazna_Dokumenta/InvBrojevi_Post",
type: 'POST',
data: JSON.stringify(m),
dataType: 'json',
success: function (data) {
alert("OK");
}
});
I can see the model is serialized. Serialized structure is
"[{\"rb\":6477,\"id_ulaz_sredstava\":308,\"inv_broj\":6477,\"serijski_broj\":null,\"id_sifra\":29},{\"rb\":6478,\"id_ulaz_sredstava\":308,\"inv_broj\":6478,\"serijski_broj\":null,\"id_sifra\":29},{\"rb\":6479,\"id_ulaz_sredstava\":308,\"inv_broj\":6479,\"serijski_broj\":null,\"id_sifra\":29},{\"rb\":6480,\"id_ulaz_sredstava\":308,\"inv_broj\":6480,\"serijski_broj\":null,\"id_sifra\":29}]":
But in controller the input parameter is NULL. The controller is
[HttpPost]
public ActionResult InvBrojevi_Post(IEnumerable<Magacin.Models.InvBrojeviModel> _invBrojeviModel)
{
return Json("test");
}
The input parameter _invBrojeviModel is NULL. Why?

Ajax post model to controller action

In mvc4 i am trying to Post model data from view to controller using Jquery Ajax but don't now what's wrong with this code can any one help me in this matter.
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#save").click(function () {
$("#content").html("<b>Please Wait...</b>");
var dataObject = {
empid: 1,
EmployeeName: "rizwan",
Address: "lahore",
Country: "pakistan",
Salary: "35000.00",
DepartmentName: "Field"
}
$.ajax({
type: "POST",
url: "/Home/Index",
data: dataObject,
success: function (data)
{
$("#empname").val(''),
$("#empadd").val(''),
$("#empcountry").val(''),
$("#empsalary").val(''),
$("#empdeptname").val(''),
$("#content").html("<div class='success'>"+data+"</div>")
},
error: function (ehr)
{
$("#content").html("<div class='failed'>Error! Please try again</div>");
},
})
});
});
</script>
This is my controller action code who just receive the value of object and save into database
Problem is that i failed to receive values at controller action side.
Please help me.....
[HttpPost]
public ActionResult Index(userview dataObject)
{
department dept = new department();
employee emp = new employee();
string message = "";
try
{
emp.employeeName = dataObject.EmployeeName;
emp.address = dataObject.Address;
emp.country = dataObject.Country;
emp.salary = dataObject.Salary;
dept.departmentName = dataObject.DepartmentName;
db.employees.Add(emp);
db.departments.Add(dept);
db.SaveChanges();
}
catch(Exception ex)
{
message = "Error! Please try again";
}
if (Request.IsAjaxRequest())
{
return new JsonResult { Data = message, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
ViewBag.message = message;
return View();
}
This is my model class
public class userview
{
public int empId { get; set; }
public string EmployeeName { get; set; }
public string Address { get; set; }
public string Country { get; set; }
public decimal Salary { get; set; }
public string DepartmentName { get; set; }
}
Try using JSON.stringify
$.ajax({
type: "POST",
url: "/Home/Index",
data: JSON.stringify(dataObject), //Here is the change
success: function (data)
{
$("#empname").val(''),
$("#empadd").val(''),
$("#empcountry").val(''),
$("#empsalary").val(''),
$("#empdeptname").val(''),
$("#content").html("<div class='success'>"+data+"</div>")
},
error: function (ehr)
{
$("#content").html("<div class='failed'>Error! Please try again</div>");
},
})
You can implement BindModel yourself! get the json string and deserialize to your entity.
public class JsonBinder<T> : System.Web.Mvc.IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
using (var reader = new System.IO.StreamReader(controllerContext.HttpContext.Request.InputStream))
{
//set stream position 0, maybe previous action already read the stream.
controllerContext.HttpContext.Request.InputStream.Position = 0;
string json = reader.ReadToEnd();
if (string.IsNullOrEmpty(json) == false)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
object jsonData = serializer.DeserializeObject(json);
return serializer.Deserialize<T>(json);
}
else
{
return null;
}
}
}
}
and set the JsonBinder to the post method like
[HttpPost]
public ActionResult Index([ModelBinder(typeof(JsonBinder<userview>))] userview dataObject)
{
}
the other solution
I found that you could set DataContract to the class of Model, and set DataMember to the Properties of the class.
edit the class like this
[DataContract]
public class userview
{
[DataMember]
public int empId { get; set; }
[DataMember]
public string EmployeeName { get; set; }
[DataMember]
public string Address { get; set; }
[DataMember]
public string Country { get; set; }
[DataMember]
public decimal Salary { get; set; }
[DataMember]
public string DepartmentName { get; set; }
}
and you should add library reference "System.Runtime.Serialization"
Hope it works for you.

How to model bind a class that implements an interface?

The model binding worked fine until i implemented interfaces on top of the following classes:
public class QuestionAnswer : IQuestionAnswer
{
public Int32 Row_ID { get; set; }
public Int32 Column_ID { get; set; }
public String Value { get; set; }
}
public class HiddenAnswer : IHiddenAnswer
{
public Int32 Hidden_Field_ID { get; set; }
public String Hidden_Field_Value { get; set; }
}
public class SurveyAnswer : ISurveyAnswer
{
public string SessionID { get; set; }
public List<IQuestionAnswer> QuestionAnswerList { get; set; }
public List<IHiddenAnswer> HiddenAnswerList { get; set; }
public SurveyAnswer()
{
QuestionAnswerList = new List<IQuestionAnswer>();
HiddenAnswerList = new List<IHiddenAnswer>();
}
}
Now that the interfaces are there, i get a 500 (Internal Server Error)
The javascript that i use to model bind is the following:
$('#submitbutton').click(function () {
var answers = new Array();
var hiddenfields = new Array();
var formname = "#" + $("#formname").val();
$(':input', formname).each(function () {
if ($(this).is(":text") || $(this).is(":radio") || $(this).is(":checkbox"))
{
var answerObject = {
Column_ID: $(this).attr('data-column_id'),
Row_ID: $(this).attr('data-row_id'),
Value: $(this).attr('data-theValue')
};
answers.push(answerObject);
}
else if($(this).is(":hidden")) {
var hiddenObject =
{
Hidden_Field_ID: $(this).attr('data-hidden_field_id'),
Hidden_Field_Value: $(this).attr('data-hidden_field_value')
}
hiddenfields.push(hiddenObject);
}
});
$('textarea', formname).each(function () {
var answerObject = {
Column_ID: $(this).attr('data-column_id'),
Row_ID: $(this).attr('data-row_id'),
Value: $(this).val(),
};
answers.push(answerObject);
});
var allAnswers = {
SessionID: 0,
QuestionAnswerList: answers,
HiddenAnswerList: hiddenfields
}
postForm(allAnswers);
});
The Controller Action looks like this:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SubmitSurvey(SurveyAnswer answers)
{
// Dette tillader CORS
Response.AppendHeader("Access-Control-Allow-Origin", "*");
bc.SaveSurvey(answers);
return null;
}
what am i doing wrong?
what am i doing wrong?
You cannot expect the model binder to know that when it encounters the IQuestionAnswer interface on your SurveyAnswer view model it should use the QuestionAnswer type. It's nice that you have declared this implementation of the interface but the model binder has no clue about it.
So you will have to write a custom model binder for the IQuestionAnswer interface (same for the IHiddenAnswer interface) and indicate which implementation do you want to be used:
public class QuestionAnswerModelBinder : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
var type = typeof(QuestionAnswer);
var model = Activator.CreateInstance(type);
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, type);
return model;
}
}
which will be registered in your Application_Start:
ModelBinders.Binders.Add(typeof(IQuestionAnswer), new QuestionAnswerModelBinder());

Sending model data from Knockout back to MVC 3

I am new to knockout and am having a hard time trying to get my data from Knockout back to my server. I keep getting an error of 'No parameterless constructor defined for this object.' Any help would be appreciated.
My Knockout model is as follows
function partSummary(item) {
var self = this;
self.ID = ko.observable(item.ID);
self.serialNumber = ko.observable(item.SerialNumber);
self.description = ko.observable(item.Description);
self.manufacturer = ko.observable(item.Manufacturer);
self.creationDate = ko.observable(item.DateCreated);
self.active = ko.observable(item.IsActive);
}
My code to send the data back the server is
self.savePart = function() {
$.ajax("/PartKO/UpdatePart", {
data: ko.toJSON(self.partDetails),
type: "post",
contentType: 'application/json',
dataType: 'json'
});
};
My MVC controller is
[HttpPost]
public JsonResult UpdatePart(PartDetail part)
{
var dbPart = new PartGenericAccessor();
dbPart.ID = part.ID;
dbPart.Load();
dbPart.Description = part.Description;
dbPart.IsActive = Convert.ToBoolean(part.IsActive);
var manufacturers = ManufacturerAccessor.LoadAll<ManufacturerAccessor>();
if (part.Manufacturer != null)
{
var manufacturer = (from p in manufacturers where p.Name == part.Manufacturer select p.ID).First();
dbPart.ManufacturerID = manufacturer;
}
dbPart.Save();
return Json("Success!!");
}
And my server side model is
public class PartDetail
{
public PartDetail(Guid id, string serial, string description, string manufacturer, DateTime created, bool isActive)
{
ID = id;
SerialNumber = serial;
Description = description;
Manufacturer = manufacturer;
DateCreated = created.ToShortDateString();
IsActive = isActive.ToString(CultureInfo.InvariantCulture);
}
public Guid ID { get; set; }
public string SerialNumber { get; set; }
public string Description { get; set; }
public string Manufacturer { get; set; }
public string DateCreated { get; set; }
public string IsActive { get; set; }
}
You need to supply a parameterless constructor for your MVC model:
public class PartDetail
{
public PartDetail()
{ ... }
}
When the data comes back from the server, MVC will create an empty object, using the parameterless constructor and then call the 'set' methods to set each property that matches the data coming in.
Once I made stupid mistake:
Named controller argument 'action' - and on post it allways null.
[HttpPost]
public JsonResult AddMetaAction(ActionModel action)
I didn't know about that and spend on debug and solving that problem about a half of hour:(

Resources