Serialize SelectListItem and binding - asp.net-mvc-3

I have model
public class UploadOptionModel
{
public UploadOptionModel()
{
OutputFormat = outputFormatList.Select(i => new SelectListItem
{
Text = i,
Value = i
});
}
public string Email { get; set; }
public IEnumerable<SelectListItem> OutputFormat { get; set; }
}
and View
#model PC.Models.UploadOptionModel
#using (Html.BeginForm())
{
#Html.TextBoxFor(p => p.Email)
#Html.DropDownList("OutputFormat", Model.OutputFormat)
}
I am trying to submit the form above using Ajax call and bind it to model
//Calling ValidateFile Action controller
$.ajax({
url: '#Url.Action("ValidateFile", "Converter")',
data: JSON.stringify({ file: fileName, formData: serializedForm }),
contentType: 'application/json',
type: 'POST',
success: function (response) {
if (response.result) {
} else {
RemoveFile(fileName);
}
}
});
function serializeForm() {
var data = $("form").serializeArray();
var formData = {};
for (var i = 0; i < data.length; i++) {
formData[data[i].name] = data[i].value;
}
return formData;
}
The ValidateFile action
[HttpPost]
public JsonResult ValidateFile(string file, UploadOptionModel formData)
{
}
The problem is that UploadOptionModel.OutputFormat is not binding. I can't read selected dropdown value. UploadOptionModel.Email field is bind successfully.

You should have another property in your Model class, where you bind the selected value of the dropdownlist.
So in your model add something like
public string OutputFormatSelected { get; set; }
And then use it in your view, this way:
#model PC.Models.UploadOptionModel
#using (Html.BeginForm())
{
#Html.TextBoxFor(p => p.Email)
#Html.DropDownListFor( m => m.OutputFormatSelected, m.OutputFormat)
}
Your problem was that you wee binding both the list of elements and the result to the same property

Related

Post Model to Controller in ajax

This is My ajax Code
$('#RolesSave').click(function () {
var sRow = JSON.parse(JSON.stringify($('#table').bootstrapTable('getSelections')));
var ID = JSON.stringify(sRow, ["ID"]);
var view = {
CompanyCode: $('#Company').val(),
RolesCode: $('#Roles').val(),
ID,
};
$.ajax({
method: "POST",
url: '#Url.Action("Save")',
data: $('#formData').serialize(),
success: function (data) {
alert(data + '!!!')
},
error: function () {
alert('ERROR')
}
})
})
This is My Controller
[HttpPost]
public IActionResult Save(RightsModel view)
{
return View();
}
and This My Model
public class RightsModel
{
public List<string> ID { get; set; }
public string Company { get; set; }
public string Roles { get; set; }
}
and this is my view
<form id="formData">
#Html.DropDownListFor(m => m.Company, Model.Company)
#Html.DropDownListFor(m => m.Roles, Model.Roles)
<button id="RolesSave" class="btn btn-primary btn-light" type="submit">存檔</button>
<table id="table"></table>
My problem is when I use the code $('#formData').serialize(). It can convert the data in View into Model normally.
But when I use JSON.serialize(view), It can't achieve the same goal.
Even if I add [FormBody] to the Action, I cannot get any relevant information.
Any suggestions?
JSON.serialize is not exists in js,we usually use JSON.stringify.And you need to make sure the model structure of view is the same with model RightsModel.And you need to add contentType:"application/json", to ajax since you want to pass json type data to action.Here is a demo:
js:
$('#RolesSave').click(function () {
var sRow = JSON.parse(JSON.stringify($('#table').bootstrapTable('getSelections')));
var ID = [];
sRow.forEach(function (item, index) {
ID.push(""+item.ID);
});
var view = {
Company: $('#Company').val(),
Roles: $('#Roles').val(),
ID: ID
};
$.ajax({
method: "POST",
url: '#Url.Action("Save")',
data: JSON.stringify(view),
contentType:"application/json",
success: function (data) {
alert(data + '!!!')
},
error: function () {
alert('ERROR')
}
})
})
action:
[HttpPost]
public IActionResult Save([FromBody]RightsModel view)
{
return View();
}
result:
I try yo use var ID = ["1", "2", "3"]; to test,and it can work.ID need to be type List<string>.

call to function from the controller in index.html

In my mvc app I have combobox, I am trying to do the following: when the user choose some item that will call to some function from the controller.
Index.html:
#using (Ajax.BeginForm("dor", "Home", new AjaxOptions
{
HttpMethod = "Get",
//UpdateTargetId = "myPic",
InsertionMode = System.Web.Mvc.Ajax.InsertionMode.Replace
}))
{
#Html.DropDownListFor(x => x.SelectedFileName, Model.Files, new { Name = "map", #class = "form-control", onchange = "CallChangefunc()" })
}
.
.
.
<script type="text/javascript">
function CallChangefunc() {
window.location.href = '#Url.Action("dor","Home")';
}
</script>
HomeVM:
public class HomeVM
{
public List<SelectListItem> Files { get; set; }
public string SelectedFileName { get; internal set; }
public List<string> DynamicAlgorithems { get; set; }
}
Homecontroller:
public void dor()
{
//some code
}
The problem: when the user choose some item from combobox it redirect me to blank page i.e to http://localhost:55354/Home/dor, but I only want to call the function named dor, not to go to blank page!.
what am I missing?
Related
window.location.href always redirect to a new page URL assigned to it. You should use jQuery.ajax() to call the action method when onchange method triggered and return desired result:
jQuery (inside $(document).ready())
$('#SelectedFileName').change(function() {
var selectedFileName = $(this).val();
$.ajax({
type: 'GET',
url: '#Url.Action("Dor", "Home")',
data: { fileName: selectedFileName },
success: function (result) {
// do something
}
});
});
Controller
[HttpGet]
public ActionResult Dor(string fileName)
{
// do something
}
Note: Make sure that action method argument has same name with assigned data passed from AJAX callback.

Typed Model in Controller action is always null when doing $.post

I am trying to post back some data to one of my action methods in an MVC project. I already have an Ajax form that does something different so I can't use another Ajax form. So I resorted to using $.post function. Then problem is, when my action method gets called, my model is null.
This is my view:
#model ActivityViewModel
#using (Ajax.BeginForm("Create", "Activities", new AjaxOptions() { UpdateTargetId = "panelContent", InsertionMode = InsertionMode.Replace }, new { id = "createactivity", autocomplete = "off" }))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.EmployeeId)
#Html.HiddenFor(m => m.IsAbscence)
#Html.HiddenFor(m => m.Id)
#Html.HiddenFor(m => m.ConflictIds)
#Html.HiddenFor(m => m.IsAbscence)
#Html.TextBoxFor(model => model.Date, "{0:dd.MM.yyyy}", new { #type = "date", #class = "ms-TextField-field", #autocomplete = "off" })
#if (!Model.IsAbscence)
{
#Html.HiddenFor(m => Model.Favorites, new { #id = "favoritehidden" })
#Html.HiddenFor(m => Model.Archive, new { #id = "archivehidden" })
<script type="text/javascript">
attachFabricCheckBoxHandler('#favoritehidden', '#favoritelabel');
attachFabricCheckBoxHandler('#archivehidden', '#archivelabel');
$(document).ready(function () {
$('#favoritelabel').click(function () {
var frm = $('#createactivity').serialize();
var token = $('[name=__RequestVerificationToken]').val();
$.post({
type: 'POST',
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
url: '/Activities/FilterProjects/',
data: { __RequestVerificationToken: token, model: frm.substring(frm.indexOf("&") + 1) },
statusCode: {
404: function (content) { showErrorDialog(content); },
500: function (content) { showErrorDialog(content); }
},
success: function (data) {
alert(data);
},
error: function (req, status, errorObj) {
showErrorDialog(status);
}
});
});
});
</script>
#Html.DropDownListFor(m => m.ProjectId, new SelectList(ViewBag.Projects, "Id", "ProjectDescription"), new { #class = "ms-Dropdown-select" })
}
#Html.TextBoxFor(model => model.StartTime, "{0:HH:mm}", new { #readonly = "readonly", #class = "ms-TextField-field", #placeholder = "Click to choose time" })
#Html.TextBoxFor(model => model.EndTime, "{0:HH:mm}", new { #readonly = "readonly", #class = "ms-TextField-field", #placeholder = "Click to choose time" })
#Html.TextAreaFor(model => model.Description, new { #class = "ms-TextField-field", #style = "height:100px; resize:vertical;" })
#if (!Model.IsAbscence)
{
#Html.TextAreaFor(model => model.Comment, new { #class = "ms-TextField-field", #style = "height:100px; resize:vertical;" })
}
}
Notice I removed all the unnecessary HTML, the structure is basically the same. Here is my ViewModel:
public class ActivityViewModel
{
public int Id { get; set; }
public DateTime Date { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Description { get; set; }
public int EmployeeId { get; set; }
public string ConflictIds { get; set; }
public string Comment { get; set; }
public int ProjectId { get; set; }
public bool IsAbscence { get; set; }
public bool Archive { get; set; }
public bool Favorites { get; set; }
}
When I use this, I always get null in my action method:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult FilterProjects(ActivityViewModel model)
{
//When 'object model' is being passed, the serialized string and all the properties are there...
return PartialView("Create");
}
The weird thing is, when I pass an object instead of my typed ViewModel into my action method, I get the serialized string with all my properties:
EmployeeId=1&
IsAbscence=False&
Id=0&
ConflictIds=&
IsAbscence=False&
Date=27.04.2016&
Favorites=True&
Archive=False&
ProjectId=1&
StartTime=10%3A25& //Maybe these two values are screwing up the model?
EndTime=11%3A25&
Description=&
Comment=&
I could re-instantiate my viewmodel from this string but it would be much nicer if I had my typed model passed into my action. How do you properly serialize the form so that it's not null when your action is called? I tried leaving out the "StartTime" and "EndTime" properties and I cut out the validation token string because I thought they were interfering here, but obviously that didn't work.
When you serialize form, AntiForgeryToken will be included. try to send form without specifying __RequestVerificationToken:
$('#favoritelabel').click(function () {
var frm = $('#createactivity').serialize();
$.post('/Activities/FilterProjects/', frm, function (data) {
}).fail(function (xhr, status, errorThrown) {
showErrorDialog(status);
});
});

reading ASP.NET MVC json result in kendo Grid

i am using ASP.NET MVC5 and intended to read json data from controller to view in razor page using kendo grid. I am using trial version for time being so i don't have access to kendo server scripting and helper classes... i have jsonResult in controller and i want ajax to call this function from view--> javascript to read and print data...
model class
[Table("FeeZone")]
public class FeeZone
{
public FeeZone()
{
}
[Key]
public int FeeZoneID { get; set; }
[Required]
public string FeeZoneDescription { get; set; }
[StringLength(50, ErrorMessage = "Description Max Length is 50")]
[Required]
public string CurrencyLabel { get; set; }
[StringLength(10, ErrorMessage = "Description Max Length is 10")]
[Required]
public string CurrencySymbol { get; set; }
[StringLength(50, ErrorMessage = "Description Max Length is 50")]
[Required]
public string CurrencyCode { get; set; }
}
Controller class
public ActionResult FreeZone()
{
var query_result = Q_UOF.GetAllFeeZone();
return View(query_result.ToList());
}
public JsonResult GetAllFreeZone()
{
var allFreeZone = Q_UOF.GetAllFeeZone().ToList();
return Json(allFreeZone, JsonRequestBehavior.AllowGet);
}
razor -- view page
model IEnumerable<DatabaseLayer.TableMappings.FeeZone>
#{
ViewBag.Title = "FreeZone";
Layout = "~/Views/Shared/_Layout_Master.cshtml";
}
<script type="text/javascript">
$(document).ready(function () {
//load ALl freeZone from JSON Method
var RemoteJsonData = new kendo.data.DataSource(
{
transport:
{
read: {
type: "Get",
dataType: "json",
url: "Qualification/GetAllFreeZone"
},
pageSize: 4
}
})
//View all FreeZone data in Kendo Grid
$("#FreeZone_ViewAll_Grid").kendoGrid({
columns: [
{ title: "FeeZoneID" },
{ title: "FeeZoneDescription" },
{ title: "CurrencyLabel" },
{ title: "CurrencySymbol" },
{ title: "CurrencyCode" }
],
dataSource: RemoteJsonData
});
})
</script>
<div id="FreeZone_ViewAll_Grid"></div>
$.ajax({
url: '#Url.Action("GetAllFreeZone", "Qualification")',
type: 'POST',
dataType: "json",
success: function (result) {
var Freezone=result.Freezone;
var dataSource = new kendo.data.DataSource({
data:Freezone
});
$('#FreeZone_ViewAll_Grid').data('kendoGrid').dataSource.data(Freezone);
},
async: false
});
Controller function
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult GetAllFreeZone([DataSourceRequest] DataSourceRequest request)
{
var allFreeZone = Q_UOF.GetAllFeeZone().ToList();
return Json(allFreeZone.ToDataSourceResult(request));
}

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