MVC Controller receiving null values from ajax - ajax

I'm trying to send an Ajax post to mvc controller contains two parameters.
First parameter: serialized model (Folder)
Second parameter: Array (Periods)
The problem is the controller received null values in the first parameter:
Javascript code :
var data = JSON.stringify({
Folder: $('#Folder').serialize(),
Periods: periodsArr
});
function save(data) {
return $.ajax({
type: 'POST',
//cache: false,
contentType: 'application/json', //Without folder not empty and period is empty
//traditional: true,
//dataType: "json",
url: '#Url.Action("AddOrEditFolder", "Folder")',
data: data,
success: function (result) {
alert(result);
location.reload();
},
error: function () {
alert("Error!" + Error);
}
});
}
Html code:
<div class="card-body">
#using (Html.BeginForm(null, null, new { #id = string.Empty }, FormMethod.Post, new { #id = "Folder" }))
{
#Html.HiddenFor(model => model.FolderID)
<div class="row">
<label for="FirstNameAR" class="col-sm-2 control-label">الإسم الشخصي</label>
<div class="col-sm-4">
#Html.EditorFor(model => model.Trainee.FirstNameAR, new { htmlAttributes = new { #id= "FirstNameAr", #class = "form-control" } })
</div>
<label for="FirstNameFR" class="col-sm-2 control-label">الإسم العائلي</label>
<div class="col-sm-4">
#Html.EditorFor(model => model.Trainee.FirstNameFR, new { htmlAttributes = new { #id = "FirstNameFr", #class = "form-control" } })
</div>
</div> <br />
Controller code:
[HttpPost]
//[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AddOrEditFolder(Folder Folder, Period[] Periods)
{
//Folder Folder = JsonConvert.DeserializeObject<Folder>(Obj);
using (InternshipsEntities dbContext = new InternshipsEntities())
{
//Some code here
}
}
How can I solve that problem ?

Use below code to create data object to pass in Ajax request.
var Folder = { };
$.each($('#Folder').serializeArray(), function() {
Folder[this.name] = this.value;
});
var data = {
Folder: Folder
Periods: periodsArr
};

Related

How to get input data from MVC ViewModel into ajax post

I am fetching data from a SQL database table into an ASP.NET MVC Razor view but I have troubles getting changed input data into an Ajax post such as:
#model MyViewModel
<div class="row">
<div class="col-1">
#Html.LabelFor(model => model.Id, "Id:", new {})
</div>
<div class="col-4">
#Html.Label(Model.Id.ToString(), new { title = "" })
</div>
</div>
<div class="row">
<div class="col-1">
#Html.LabelFor(model => model.Test, "Test:", new { })
</div>
<div class="col-9">
#Html.TextBoxFor(model => model.Test, new { data_bind = "value: Test", #type = "text" })
</div>
</div>
#section scripts {
<script type="text/javascript">
$("#save-click").click(function () {
var nr = #Model.Id;
var postData = #Html.Raw(Json.Encode(#Model));
//alert(postData.Test);
$.ajax({
type: "POST",
url: actions.test.createOrUpdate + "?id=" + nr,
dataType: "json",
traditional: true,
data: postData,
success: function (response) {
if (response.Code == 0) {
else {
window.location.reload(false);
}
} else {
alert('err');
}
}
});
});
});
</script>
}
When I load the view everything is displayed correctly. The controller action is triggered correctly and the Id (which can not be altered) is passed properly too. However when input fields are changed not the changed values get passed to the controller but the original values that were fetched into the view.
The serialization seems to work, since the alert (postData.Test) returns a value - but always the unchanged one.
Any help would be appreciated.
var postData = #Html.Raw(Json.Encode(#Model));
This line is the culprit. When Razor renders the script, it will assign the original/unchanged model to your postData variable.
If you use "Inspect Element" or dev tools to check the value of postData, you'll see that the values won't change because they're statically assigned.
You need to check for the new values every time you click the button by using
var postData = $("form").serialize();
And be sure to wrap your input fields inside a form tag. See code below:
<form>
<div class="row">
<div class="col-1">
#Html.LabelFor(model => model.Id, "Id:", new {})
</div>
<div class="col-4">
#Html.Label(Model.Id.ToString(), new { title = "" })
</div>
</div>
<div class="row">
<div class="col-1">
#Html.LabelFor(model => model.Test, "Test:", new { })
</div>
<div class="col-9">
#Html.TextBoxFor(model => model.Test, new { data_bind = "value: Test", #type = "text" })
</div>
</div>
</form>
#section scripts {
<script type="text/javascript">
$("#save-click").click(function () {
var nr = #Model.Id;
// use form.serialize or use the id/class of your form
var postData = $("form").serialize();
$.ajax({
type: "POST",
url: actions.test.createOrUpdate + "?id=" + nr,
dataType: "json",
traditional: true,
data: postData,
success: function (response) {
if (response.Code == 0) {
else {
window.location.reload(false);
}
} else {
alert('err');
}
}
});
});
});
</script>
}

Partial View not printing values in mvc 5

I'm using ajax call to execute partial view controller action to print max batch number. Everything executes, but the value doesn't print in partial view. On selected dropdown list I'm calling ajax method to execute. Below is my code that i'm using.
Models.Batch.cs
[Required]
[StringLength(100)]
[DataType(DataType.Text)]
[Display(Name = "Batch Number")]
public string BatchNumber { get; set; }
BatchController.cs
public PartialViewResult GetBatchNumber(string CourseID)
{
Context.Batches contBatch = new Context.Batches();
Models.Batches b = new Models.Batches();
b.BatchNumber = contBatch.GetallBatchList().ToList().Where(p => p.CourseId == CourseID).Select(p => p.BatchNumber).Max().FirstOrDefault().ToString();
ViewBag.Message = b.BatchNumber;
return PartialView(b);
}
CreateBatch.cshtml
<div class="col-md-10">
#Html.DropDownListFor(m => m.CourseId, Model.Courses, new { id = "ddlCourse" })
<div id="partialDiv">
#{
Html.RenderPartial("GetBatchNumber", Model);
}
</div>
<script>
$("#ddlCourse").on('change', function () {
var selValue = $('#ddlCourse').val();
$.ajax({
type: "GET",
url: '/Batch/GetBatchNumber?CourseId=' + selValue,
dataType: "json",
data: "",
success: function (data) {
$("#partialDiv").html(data);
},
failure: function (data) {
alert('oops something went wrong');
}
});
});
</script>
</div>
GetBatchNumber.cshtml
#model WebApplication1.Models.Batches
<div class="form-group">
#Html.LabelFor(model => model.BatchNumber, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DisplayFor(model => model.BatchNumber)
#Html.ValidationMessageFor(model => model.BatchNumber, "", new { #class = "text-danger" })
</div>
</div>

How to use ajax to post Kendo upload files to controller

When i use ajax to post the form data to controller, i cannot get the files when using Kendo upload. I used IEnumerable but i only can get the date value and the file is null. May i know how to make it work? Thanks.
(I use ajax because i need call the onsuccess event)
//Here is the form control in view
<div class="editForm">
#using (Html.BeginForm("UpdateReportFix", "Defect", FormMethod.Post, new { id = "form" }))
{
#Html.HiddenFor(model => model.DefectFixID)
<div>
#Html.Label("Report Date")
</div>
<div>
#(Html.Kendo().DatePickerFor(model => model.ReportDate)
.Name("ReportDate")
.Value(DateTime.Now).Format("dd/MM/yyyy")
.HtmlAttributes(new { #class = "EditFormField" })
)
#Html.ValidationMessageFor(model => model.ReportDate)
</div>
<div>
#Html.Label("Photos")
<br />
<span class="PhotosMessage">System Allow 2 Pictures</span>
</div>
<div class="k-content">
#(Html.Kendo().Upload()
.Name("files") <-----i cannot get this value in controller
)
</div>
<br />
<div class="col-md-12 tFIx no-padding">
#(Html.Kendo().Button().Name("Cancel").Content("Cancel").SpriteCssClass("k-icon k-i-close"))
#(Html.Kendo().Button().Name("submit").Content("Submit").SpriteCssClass("k-icon k-i-tick"))
</div>
}
//script
$('form').submit(function (e) {
e.preventDefault();
var frm = $('#form');
$.ajax({
url: '#Url.Action("UpdateReportFix")',
type: 'POST',
data: frm.serialize(),
beforeSend: function () {
},
onsuccess: function () { },
success: function (result) { },
error: function () { }
});
});
For "Uploading files using Ajax & Retain model values after Ajax call and Return TempData as JSON" try the following example:
View:
#using (Html.BeginForm("Create", "Issue", FormMethod.Post,
new { id = "frmCreate", enctype = "multipart/form-data" }))
{
<div id="divMessage" class="empty-alert"></div>
#Html.LabelFor(m => m.FileAttachments, new { #class = "editor-label" })
#(Html.Kendo().Upload()
.HtmlAttributes(new { #class = "editor-field" })
.Name("files")
)
}
<script>
$(function () {
//Populate model values of the partialview after form reloaded (in case there is a problem and returns from Controller after Submit)
$('form').submit(function (event) {
event.preventDefault();
showKendoLoading();
var selectedProjectId = $('#ProjectID').val(); /* Get the selected value of dropdownlist */
if (selectedProjectId != 0) {
//var formdata = JSON.stringify(#Model); //For posting uploaded files use as below instead of this
var formdata = new FormData($('#frmCreate').get(0));
$.ajax({
type: "POST",
url: '#Url.Action("Create", "Issue")',
//contentType: "application/json; charset=utf-8", //For posting uploaded files use as below instead of this
data: formdata,
dataType: "json",
processData: false, //For posting uploaded files we add this
contentType: false, //For posting uploaded files we add this
success: function (response) {
if (response.success) {
window.location.href = response.url;
#*window.location.href = '#Url.Action("Completed", "Issue", new { /* params */ })';*#
}
else if (!response.success) {
hideKendoLoading();
//Scroll top of the page and div over a period of one second (1,000 milliseconds = 1 second).
$('html, body').animate({ scrollTop: (0) }, 1000);
$('#popupDiv').animate({ scrollTop: (0) }, 1000);
var errorMsg = response.message;
$('#divMessage').html(errorMsg).attr('class', 'alert alert-danger fade in');
$('#divMessage').show();
}
else {
var errorMsg = null;
$('#divMessage').html(errorMsg).attr('class', 'empty-alert');
$('#divMessage').hide();
}
}
});
}
else {
$('#partialPlaceHolder').html(""); //Clear div
}
});
});
</script>
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Exclude = null)] Model viewModel, IEnumerable<HttpPostedFileBase> files)
{
//...
return Json(new { success = false, message = "Max. file size is 10MB" }, JsonRequestBehavior.AllowGet);
}

Routing a custom controller in Orchard CMS

I'm having some trouble setting up the routing to a custom controller in Orchard.
I've created a View:
#model dynamic
#{
Script.Require("jQuery");
}
#using (Html.BeginForm("Send", "Email", FormMethod.Post, new { id = "contactUsForm" }))
{
<fieldset>
<legend>Contact Us</legend>
<div class="editor-label">Name:</div>
<div class="editor-field">
#Html.TextBox("Name", "", new {style = "width: 200px"})
</div>
<div class="editor-label">Email Address:</div>
<div class="editor-field">
#Html.TextBox("Email", "", new {style = "width: 200px"})
</div>
<div class="editor-label">Telephone Number:</div>
<div class="editor-field">
#Html.TextBox("Telephone", "", new {style = "width: 200px"})
</div>
<div class="editor-label">Message:</div>
<div class="editor-field">
#Html.TextArea("Message", "", new {style = "width: 200px"})
</div>
<br/>
<input id="ContactUsSend" type="button" value="Submit" />
</fieldset>
}
#using (Script.Foot()) {
<script>
$(function() {
$('#ContactUsSend').click(function () {
alert('#Url.Action("Send", "Email")');
var formData = $("#contactUsForm").serializeArray();
$.ajax({
type: "POST",
url: '#Url.Action("Send", "Email")',
data: formData,
dataType: "json",
success: function (data) {
alert(data);
}
});
});
});
</script>
}
With a Controller:
public class EmailController : Controller
{
[HttpPost]
public ActionResult Send()
{
var orchardServices = DependencyResolver.Current.GetService<IOrchardServices>();
var messageHandler = DependencyResolver.Current.GetService<IMessageManager>();
var svc = new ContactUsService(orchardServices, messageHandler);
svc.DoSomething();
return new EmptyResult();
}
}
And setup the route:
public class Routes : IRouteProvider {
public void GetRoutes(ICollection<RouteDescriptor> routes) {
foreach (var routeDescriptor in GetRoutes()) {
routes.Add(routeDescriptor);
}
}
public IEnumerable<RouteDescriptor> GetRoutes() {
return new[] {
new RouteDescriptor {
Priority = 15,
Route = new Route(
"ContactUsWidget",
new RouteValueDictionary {
{"area", "ContactUsWidget"},
{"controller", "Email"},
{"action", "Send"}
},
new RouteValueDictionary(),
new RouteValueDictionary {
{"area", "ContactUsWidget"}
},
new MvcRouteHandler())
}
};
}
}
But when I click the submit button, it tries to post to
OrchardLocal/Contents/Email/Send
and obviously fails. Can anyone point me in the direction of what I'm doing wrong?
Try this:
#using (Html.BeginForm("Send", "Email", new { area = "Your.Module" }, FormMethod.Post, new { id = "contactUsForm" }))
Adding the area is like an extra clause that ensures only your module is searched for a matching controller/action method pair.

How to do Jquery ajax post to controller mvc

I just can't figure out what I am not doing right,From a viewmodel,I try to grab from user {**Tousername and messagebody},#ToUserName** is correctly sent while #Body is null in controller when I debug .I have the following Jquery code:
$("#SendMessage").click(function () {
var message = GrabMessage();
var jsonData = JSON.stringify(message, null, 2);
$.ajax({
url: '#Url.Content("~/Message/Compose/")',
type: 'POST',
data: jsonData,
datatype: 'json',
contentType: 'application/json; charset=utf-8',
success: function () {
$('#default_message').append("message sent ");
switchToSentMessagesTab();
},
error: function (request, status, err) {
alert(status);
alert(err);
}
});
return false;
});
function switchToSentMessagesTab() {
$('a[href="#default_message"]').click();
}
function GrabMessage() {
var touser = $("#ToUserName").val();
var text = $("#Body").val();
var result =
{
Body: text,
ToUserName: touser
};
return result;
}
});
And the razer View:
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<div class="editor-label">
#Html.LabelFor(model => model.ToUserName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ToUserName, new { #class ="autocomplete"})
#Html.ValidationMessageFor(model => model.ToUserName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Body)
#Html.ValidationMessageFor(model => model.Body)
</div>
<p>
<input id="SendMessage" type="submit" value="Send" />
</p>
}
and controller Action:
[HttpPost]
public ActionResult Compose(PrivateMessageViewModel m)
{
if (User.Identity.IsAuthenticated )
{
if (ModelState.IsValid)
{
var ToUserName = users.Profiles.First(x => x.UserName == m.ToUserName);
PrivateMessage message = new PrivateMessage
{
//do some stuff here:
};
db.SendMessage(message);
return RedirectToAction(//Some view here...)
}
}
return PartialView(m);
}

Resources