ajax POST in .NET MVC 4 parameters are not resolved - ajax

I have this function in my view:
function EditButtonClick(e1) {
var urlString = '#Url.Action( "Create", "Group")';
var groupItem = {
GroupCode: e1.getAttribute("data-GroupCode"),
GroupType: e1.getAttribute("data-GroupType"),
Description: e1.getAttribute("data-Description"),
InternalNotes: e1.getAttribute("data-InternalNotes"),
StatusCode: e1.getAttribute("data-StatusCode"),
Edit: "true"
};
$.ajax({
type: 'POST',
url: urlString,
data: { '': groupItem },
dataType: 'json'
}).fail(function () {
alert('Edit process failed');
});
}
My view model looks like this:
[Serializable]
public class GroupItem : ApplicationModel, IValidatableObject
{
public GroupItem() { }
[DisplayName("Group Code")]
public int GroupCode { get; set; }
public string GroupTypeDescription { get; set; }
[DisplayName("Group Type")]
public int GroupType { get; set; }
[DisplayName("Group Name")]
public string Description { get; set; }
[DisplayName("Internal Notes")]
public string InternalNotes { get; set; }
public string PartialInternalNotes { get; set; }
public string Status { get; set; }
[DisplayName("Status Code")]
public int StatusCode { get; set; }
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy HH:mm:ss}")]
public DateTime EnterTime { get; set; }
public string UserId { get; set; }
public string ActionType { get; set; }
public bool Edit { get; set; }
and, finally, my action looks like this:
[HttpPost]
public ActionResult Create(GroupItem groupItem)
{
if (ModelState.IsValid)
{
_groupService.SaveGroup(groupItem);
return RedirectToAction("List", "Group", new { showAll = false });
}
ViewBag.GroupTypeList = _MasterDataService.GetCodeMasterList((int)Constants.CodeType.GroupType);
ViewBag.StatusList = _MasterDataService.GetCodeMasterList((int)Constants.CodeType.GroupStatus);
if (groupItem.GroupCode > 0)groupItem.Edit = true;
return this.RazorView(groupItem);
}
Now, I put a break point in the view just before the ajax call, and another in the controller at the top of the action. The properties that I have set up in my groupItem object in the view are all populated as expected, according to an inspection just before the ajax call. However, at the breakpoint in the action, all the properties in the GroupItem argument are default values.
In other code in another view, I call this very same Action method via a form submit. In that case, all the properties are populated as expected. What am I missing in my ajax call?

You need to use JSON.stringify to first serialize your object to JSON, and then specify the contentType so your server understands it's JSON data.
So you complete AJAX function call would become,
$.ajax({
type: 'POST',
url: urlString,
data: JSON.stringify(groupItem),
contentType: "application/json",
dataType: 'json'
}).fail(function () {
alert('Edit process failed');
});

try this:
$.ajax({
type: 'POST',
url: urlString,
data: { 'groupItem': groupItem },
dataType: 'json'
}).fail(function () {
alert('Edit process failed');
});

Related

How do I populate a drop-down list with List<string> using knockout.JS

I'm playing around with knockoutJS and am struggling to get a drop-down populated with data from my model.
I'm guessing I need to convert the model data to a JSON first but for the life of me can't figure it out.
I have a basic class:
public class QuoteViewModel
{
public QuoteViewModel()
{
QuoteLines = new List<QuoteLine>();
}
public int QuoteHeaderId { get; set; }
public string QuoteNumber { get; set; }
public string Status { get; set; }
public DateTime DateCreated { get; set; }
[DisplayName("Customer")]
public SalesCustomer SelectedCustomer { get; set; }
public List<string> Customers { get; set; }
public List<QuoteLine> QuoteLines { get; set; }
}
I have an ActionMethod in a controller:
[HttpGet]
public ActionResult CreateQuote()
{
QuoteViewModel quote = new QuoteViewModel();
quote.QuoteNumber = "";
quote.Status = "P";
quote.Customers = _dbContext.SalesCustomers.Select(x => x.CustomerName).ToList();
quote.QuoteLines = new List<QuoteLine>();
return View(quote);
}
And the View():
Razor:
<select class="form-control" id="SelectedCustomer" data-bind="options: availableCustomers, optionsText: 'CustomerName', value: SelectedCustomer, optionsCaption: 'Choose...'"></select>
ViewModel:
function QuoteViewModel() {
var self = this;
self.Id = ko.observable('#Model.QuoteHeaderId');
self.QuoteNumber = ko.observable();
self.Status = ko.observable('#Model.Status');
self.DateCreated = ko.observable();
self.availableCustomers = JSON.parse('#Html.Raw(Model.Customers)');
#*$.ajax({
type: "GET",
url: '#Url.Action("GetCustomers", "Test")',
success: function (data) {
$.each(data, function (index, value) {
self.availableCustomers.push(new Customer(value));
});
},
error: function (err) {
console.log(err.responseText);
}
});*#
self.SelectedCustomer = ko.observable();
self.QuoteLines = ko.observableArray([]);
self.AddQuoteLine = function (sku, description, bomDetails) {
self.QuoteLines.push(new QuoteLineViewModel(sku, description, bomDetails));
}
self.SaveToDatabase = function () {
var dataToSend = ko.mapping.toJSON(self);
$.ajax({
type: "POST",
url: '#Url.Action("CreateQuote", "Test")',
contentType: 'application/json',
data: dataToSend,
success: function (data) {
},
error: function (err) {
console.log(err.responseText);
}
});
}
The commented out code uses ajax to get the customers and push it onto the array and that works, but is there not a way to do it directly from the model data?
Edit 1:
I don't need access to the whole SalesCustomer object, just the string name:
If I change my code as such:
Controller:
quote.Customers = _dbContext.SalesCustomers.Select(x => x.CustomerName.Trim()).ToList();
Model class property:
public List<string> Customers { get; set; }
Razor:
<select class="form-control" id="SelectedCustomer" data-bind="options: availableCustomers, value: SelectedCustomer, optionsCaption: 'Choose...'"></select>
Javascript:
self.availableCustomers = ko.observableArray([]);
var customers = '#Html.Raw(JsonConvert.SerializeObject(Model.Customers))';
self.availableCustomers = JSON.parse(customers);
self.SelectedCustomer = ko.observable();
Now the drop-down is populated with the string values of customer names. However the selected customer is not passed back to controller on POST?
Edit 2:
Well I'm not sure why its working now, but it is.
The code is the same as in Edit 1.
The only thing I can think of is I was that I erroneously had the SelectedCustomer property type still set to SalesCustomer which will obviously not work:
public SalesCustomer SelectedCustomer { get; set; }
when it should be:
public string SelectedCustomer { get; set; }
Thank you user3297291 for the assistance in pointing me in right direction.

Problems with Post Ajax in Asp.net core MVC

I can not send a Model that I am manually creating to my controller. When I send the request, it's coming up with empty properties. There is something wrong that is hindering the conversion. Does anyone know how to help me?
var operadoraChamadas = {
Id: 0,
Descricao: 'rssrrssr',
PadraoSistema: true
};
var requestData = { operadoraChamadasViewModel: operadoraChamadas}
$.ajax({
url: "/pessoa-gerenciar/changeFormaContato",
type: "POST",
data: JSON.stringify(requestData),
contentType: "application/json",
dataType: "json",
success: function (result) {
alert('ok');
},
error: function () {
alert("Oops! Algo deu errado.");
console.log(requestData);
}
});
[HttpPost]
[Route("pessoa-gerenciar/changeFormaContato")]
public IActionResult changeFormaContato(OperadoraChamadaViewModel operadoraChamadaViewModel)
{
//ViewBag.indice_new = indice;
//return PartialView("~/Views/Pessoa/PessoaContato/_PessoaContatoAdd.cshtml", _pessoaContatoAppService.CreateNew(pessoaNatureza, formaContatoId));
return null;
}
ViewModel:
public class OperadoraChamadaViewModel
{
[Key]
[DisplayName("ID")]
public int Id { get; set; }
[Required(ErrorMessage = "A Descrição é obrigatória")]
[MaxLength(50)]
[DisplayName("Descricao")]
public string Descricao { get; set; }
[DisplayName("Padrão do Sistema")]
public bool PadraoSistema { get; set; }
}
ASP.NET Core requires to add [FromBody] attribute to parameter to parse application/json content
[HttpPost]
[Route("pessoa-gerenciar/changeFormaContato")]
public IActionResult changeFormaContato([FromBody] OperadoraChamadaViewModel operadoraChamadaViewModel)

Asp Core Ajax Post with ViewModel

I am working on an Asp Core Project and trying to Ajax post a filepicker blob Javascript Object back to a action to upload the image to Amazon S3. I have tried several different ways and haven't been able to get this to work. It appears to be a model binding issue.
This functionality worked when I was only posting the image url to the action with a string parameter, but I need the filename also.
Issue: model object in action is null
Ajax Code:
function pickit() {
//Start the filepicker
filepicker.pick(
{
//cropRatio: 4 / 3,
////cropMin: [200, 100],
//cropForce: true,
mimetype: 'image/*',
//services: ['CONVERT', 'COMPUTER', 'FACEBOOK', 'FLICKR', 'DROPBOX', 'INSTAGRAM', 'BOX', 'EVERNOTE', 'GMAIL', 'PICASA', 'IMAGE_SEARCH', 'FTP', 'GOOGLE_DRIVE', 'SKYDRIVE', 'URL', 'WEBCAM', 'CLOUDDRIVE', 'IMGUR', 'CLOUDAPP'],
conversions: ['crop', 'rotate', 'filter', 'scale']
},
function (Blob) {
$("#imagespinner").removeClass("invisible")
$.ajax({
type: "POST",
url: '#Url.Action("CreateImage","Photos")',
contentType: 'application/json',
dataType: "json",
data: JSON.stringify(Blob),
success: function (data, textStatus, jqXHR) {
$("#ImageURL").val(data);
var img = document.getElementById("imgImageURL");
img.src = data;
$("#imagespinner").addClass("invisible")
},
error: function (jqXHR, textStatus, error) {
alertify.alert(jqXHR.responseText);
$("#imagespinner").addClass("invisible")
}
});
setTimeout(function () { $('#image-loading-message').fadeOut() }, 500);
},
function (FPError) {
},
function (FPProgress) {
}
);
};
Controller Action:
[HttpPost]
public async Task<JsonResult> CreateImage(FilePickerViewModel model)
{
if (!String.IsNullOrWhiteSpace(model.url))
{
//Code to Upload to S3
return Json("ImageURL");
else
{
Response.StatusCode = 400;
return Json("Url is needed");
}
}
ViewModel:
public class FilePickerViewModel
{
public Int32 id { get; set; }
public String url { get; set; }
public String filename { get; set; }
public Int32 size { get; set; }
public String client { get; set; }
public String mimetype { get; set; }
public Boolean isWriteable { get; set; }
}
Thank you for any help
I figured out the issue, the controller action needs to have the declaration of [FromBody] since this is coming from an ajax post

How to send Javascript array object to the MVC5 controller method

Hi below is my question.
How to send Javascript array object to the MVC5 controller method.
The code successfully hit the action method but the list value param value is null. I tried different combination with the JSON.stringify as well.
//object class
public class MassPayoutItem
{
public string ReciverEmailID { get; set; }
public string Amount { get; set; }
public int ProviderID { get; set;}
public string AppintmentsID { get; set; }
public string TransictionID{get;set;}
public string TransictionStatus { get; set; }
public string ProviderName { get; set;}
}
//Action method
public ActionResult GetProviderMassPaymentDetail(List<MassPayoutItem> PayoutItemList){
return Json(new { Result = true, ResultData = ResaultData, Message = "" }, JsonRequestBehavior.AllowGet);
}
//JavaScript Code
function MassPay() {
alert("called MassPay");
var MassPymentList = new Array();
var objs;
$('.Include_Payment:checked').each(function () {
var ReciverEmailId = $(this).parents('tr').attr("emailid");
var appointmentids = $(this).parents('tr').attr("appointmentids");
var ProviderID = $(this).parents('tr').attr("UserId");
var Amount = $(this).parents('tr').find(".Amount").text();
var ProviderName = $(this).parents('tr').find(".OwnerName").text();
MassPymentList.push({ "ReciverEmailID": ReciverEmailId, "Amount": Amount, "ProviderID": ProviderID, "AppintmentsID": appointmentids, "ProviderName": ProviderName, "TransictionID": "abc", "TransictionStatus": "bcd" });
});
objs = JSON.stringify({ "PayoutItemList": MassPymentList });
debugger;
// _PageUrl.PayMassTransiction
// '#Url.Action("GetProviderMassPaymentDetail","Controller")'
//The call hits the method but the value is null
$.ajax({
Type: "POST"
, url: _PageUrl.PayMassTransiction
, contentType: "application/json,charset=utf-8",
traditional: true
, data: objs,
datatype: "json",
success: function (result) {
debugger;
alert("called");
}
, error: function (result) {
}
});
}
Hi Finally I solve the issue.
public class MassPayoutItem
{
public string ReciverEmailID { get; set; }
public string Amount { get; set; }
public int ProviderID { get; set;}
public string AppintmentsID { get; set; }
public string TransictionID{get;set;}
public string TransictionStatus { get; set; }
public string ProviderName { get; set;}
}
//Action method
**//This is first change i have make.**
[HttpPost, ActionName("GetProviderMassPaymentDetail")]
public ActionResult GetProviderMassPaymentDetail(List<MassPayoutItem> PayoutItemList){
return Json(new { Result = true, ResultData = ResaultData, Message = "" }, JsonRequestBehavior.AllowGet);
}
//JavaScript Code
function MassPay() {
alert("called MassPay");
var MassPymentList = new Array();
var objs;
$('.Include_Payment:checked').each(function () {
var ReciverEmailId = $(this).parents('tr').attr("emailid");
var appointmentids = $(this).parents('tr').attr("appointmentids");
var ProviderID = $(this).parents('tr').attr("UserId");
var Amount = $(this).parents('tr').find(".Amount").text();
var ProviderName = $(this).parents('tr').find(".OwnerName").text();
MassPymentList.push({ "ReciverEmailID": ReciverEmailId, "Amount": Amount, "ProviderID": ProviderID, "AppintmentsID": appointmentids, "ProviderName": ProviderName, "TransictionID": "abc", "TransictionStatus": "bcd" });
});
objs = JSON.stringify({PayoutItemList: MassPymentList });
debugger;
// _PageUrl.PayMassTransiction
// '#Url.Action("GetProviderMassPaymentDetail","Controller")'
//The call hits the method but the value is null
// below is the changed ajax calll change Type to type
$.ajax({
type: "POST"
, url: _PageUrl.PayMassTransiction
, contentType: "application/json,charset=utf-8"
,async: false
,traditional: true
, data: objs,
datatype: "json",
success: function (result) {
debugger;
alert("called");
}
, error: function (result) {
}
});
}

Passing JSON object to Controller but loose model binding

I am trying to pass a simple JSON object to a controller using MVC3 and JSON. The object gets passed but I loose all the properties. I see all the properties in firebug on the request but am not sure why I am loosing them on the server. Do all the properties of the object need to be set in order for the mapping to work? I am using MVC3 so the binding should be build in. What am I missing?
Class:
[Serializable]
public class StoryNote
{
public int Id { get; set; }
public string Note { get; set; }
public Nullable<int> StoryCardId { get; set; }
public string CreatedBy { get; set; }
public Nullable<System.DateTime> CreateDate { get; set; }
public virtual StoryCard StoryCard { get; set; }
}
JSON:
$(document).ready(function () {
$('#newNote').click(function (e) {
e.preventDefault();
var storynote = {
StoryNote: {
Note: $('#Note').val(),
StoryCardId: $('#StoryCard_Id').val(),
CreatedBy: 'Xyz', }
};
$.ajax({
url: '#Url.Action("PostNote")',
type: 'POST',
data: JSON.stringify(storynote),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function (data) {
$('#previousNotes').append(data.Note + '<br/>' + data.CreatedBy + '<br/><hr/>');
},
});
});
});
Controller:
[HttpPost]
public JsonResult PostNote(StoryNote newStoryNote)
{
StoryNote newNote = new StoryNote { Note = newStoryNote.Note, CreatedBy = newStoryNote.CreatedBy, StoryCardId = newStoryNote.StoryCardId, CreateDate = DateTime.Now };
db.StoryNotes.Add(newStoryNote);
return Json(newStoryNote, JsonRequestBehavior.AllowGet);
}
You have a name mismatch in your code - parameter is named "StoryNote" in Javascript code and "newStoryNote" in Controller. Those names should be equal. I believe if you change
var storynote = {
StoryNote: {
Note: $('#Note').val(),
StoryCardId: $('#StoryCard_Id').val(),
CreatedBy: 'Xyz', }
};
to
var storynote = {
newStoryNote: {
Note: $('#Note').val(),
StoryCardId: $('#StoryCard_Id').val(),
CreatedBy: 'Xyz', }
};
then your code should work.

Resources