FormData not binding values to controller - c#

I have an Asp.net core application in which I have a form. When I click on the submit button I am using jquery ajax post to submit the form. I am facing 2 problems here,
When I press the submit button, the client side validations are not happening and the form is being submitted.
I have a Break point in the SendEmail Method, and for some reason the FormData binds all null values to the object. Please help.
Here is my form
<form name="ajax-form" id="formPostComment" enctype="multipart/form-data" method="post">
<div class="col-sm-6 contact-form-item wow zoomIn">
<input name="name" id="name" type="text" placeholder="Your Name: *" required/>
<span class="error" id="err-name">please enter name</span>
</div>
<div class="col-sm-6 contact-form-item wow zoomIn">
<input name="email" id="email" type="text" placeholder="E-Mail: *" required/>
<span class="error" id="err-email">please enter e-mail</span>
<span class="error" id="err-emailvld">e-mail is not a valid format</span>
</div>
<div class="col-sm-6 contact-form-item wow zoomIn">
<label for="myfiles">Select file (If Any):</label>
<input name="attachment" id="attachment" type="file" />
</div>
<div class="col-sm-12 contact-form-item wow zoomIn">
<textarea name="message" id="message" placeholder="Your Message" required></textarea>
</div>
<div class="col-sm-12 contact-form-item">
<input class="send_message btn btn-main btn-theme wow fadeInUp" type="submit" id="submit" name="submit" data-lang="en" onclick="SendEmail();"></input>
</div>
<div class="clear"></div>
<div class="error text-align-center" id="err-form">There was a problem validating the form please check!</div>
<div class="error text-align-center" id="err-timedout">The connection to the server timed out!</div>
<div class="error" id="err-state"></div>
</form>
<script>
function SendEmail() {
var formData = new FormData();
formData.append("Name", $("#name").val());
formData.append("Email", $("#email").val());
formData.append("Attachment", $("#attachment")[0]);
formData.append("Message", $("#message").val());
alert($("#name").val());
$.ajax({
type: 'POST',
url: "/Home/SendEmail",
data: formData,
processData: false,
contentType: false,
cache: false,
success: function (response) {
alert("Done");
$('#formPostComment')[0].reset();
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
//}).done(function (data) {
// console.log(data);
// $("#ajaxwaiting").hide();
// $("#ajaxsuccess").show();
//});
event.preventDefault();
}
</script>
Here is my Controller action method.
[HttpPost]
public IActionResult SendEmail([Bind("Name,Email,Attachment,Message")] SingleEmailMessage message)
{
return Json(new { data = "DONE" });
}
The SingleEmailMessage class is as follows,
public class SingleEmailMessage
{
public string Name { get; set; }
public string Email { get; set; }
public IFormFile Attachment { get; set; }
public string Message { get; set; }
}

you might be sending two POSTs here... don't use onclick on the submit... instead use onsubmit on the form tag... ex:
<form ... onsubmit="SendEmail(); return false;"> Don't forget the "return false;" bit that replaces your event.preventDefault() call. It's also easier to pass the form's ID into your function... so
SendEmail("formPostComment")... then function SendEmail(id) {
...
thisForm = document.getElementById(id);
var formData = new FormData(thisForm);
On controller side get the file by using:
if (Request.Form.Files.Count > 0)
{
IFormFile file = Request.Form.Files[0];
}
Not sure that the file is going to bind to your model.... get it from the raw request.
The full JS function I use is this (just for reference):
//for uploads
function PostFileFormID(id, buttonid, destURL) {
$('#' + buttonid).attr('value', "Uploading...");
thisForm = document.getElementById(id);
var formData = new FormData(thisForm);
jQuery.ajax({
type: 'POST',
url: destURL,
data: formData,
processData: false,
contentType: false,
success: function (data) {
params = convertJsonToParams(data);
url = "?" + params;
setLocation(url);
},
error: function (jqXHR, textStatus, error) {
DisplaySuperError(jqXHR, textStatus, error);
}
});
}

Related

AJAX parameter still null

I have a simple modal form used to insert data; when i submit data, i correctly go to my method but the parameter still null value.
This is my Razor code:
<form id="SaveKeyForm" asp-page-handler="SaveExternalKEY" data-ajax="true" data-ajax-method="post">
<div class="modal-body">
<input name="IsValid" type="hidden" value="#ViewData.ModelState.IsValid.ToString()" />
<div class="form-group">
<label asp-for="wItem.Guid"></label>
<input asp-for="wItem.Guid" name="GUID" class="form-control" id="modalCustomerGUID" readonly required />
<span asp-validation-for="wItem.Guid" class="text-danger"></span>
</div>
<div class="form-group">
#Html.Hidden("External_Key_Type_ID", "")
<select class="custom-select mr-sm-2" asp-items="_KeyOptions" name="Selected_Key_Type_ID"><option selected>Choose</option></select>
</div>
<div class="form-group">
<label asp-for="wExternal_ID.ExternalKey"></label>
<input asp-for="wExternal_ID.ExternalKey" name="ExternalKEY" class="form-control" required/>
<span asp-validation-for="wExternal_ID.ExternalKey" class="text-danger"></span>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" id="saveKey" class="btn btn-primary">Save</button>
</div>
This is my JS code:
$("#saveKey").click(function (e) {
e.preventDefault();
console.log('Ajax submit');
var form = $(this).parents('.modal').find('form');
var formAction = form.attr('action');
var fdata = form.serialize();
console.log(fdata);
var sdata = { GUID: 'fdsfas' };
$.ajax({
type: 'post',
url: formAction,
data: sdata,
dataType: "text",
processData: false,
headers: {
RequestVerificationToken:
$('input:hidden[name="__RequestVerificationToken"]').val()
},
statusCode: {
404: function () {
console.log("page not found");
},
200: function () {
console.log("Status Ok");
}
}
}).done(function (result) {
console.log('Result: ' + result);
});
});
and this is my method:
public IActionResult OnPostSaveExternalKEY(string GUID)
{
try
{
return new OkResult();
}
catch (Exception ex)
{
return new StatusCodeResult(404);
}
}
}
i have try to:
- pass data as 'fdata' variable: still null
- pass fixed data as 'sdata' variable: still null
- try to Json serialize: still null
If i use jquery-ajax-unobtrusive, i can pass correctly value to my method, but i cannot manage error message in modal form and url change.
Thanks for any help.

sending checkbox value true if checked else false with form object using jQuery in mvc [duplicate]

This question already has answers here:
Getting Checkbox Value in ASP.NET MVC 4
(19 answers)
Closed 4 years ago.
I have a problem sending data to asp.net-mvc controller method
after ajax call every data from 'form' is sending to parameters of method, except "isActive" parameter of type "bool", whether 'checkbox' is selected or not it passing 'false' to mvc controller method.
$(".btnEntity").on("click", function () {
var name = $(this).val();
var _data = $("#myForm").serializeArray();
var _url;
if (name === "EntitySubmit") {
_url = "/Home/EntitySend";
}
else {
_url = "/Home/AdoSend";
}
var isActive=$("#isActive").prop('checked');
var objdata = new FormData($("#myForm").get(0));
objdata.append("ImageFile", $("#ImageFile").get(0).files);
objdata.append("isActive", isActive);
$.ajax({
type: "post",
url: _url,
dataType: "json",
//contentType: "application/json; charset=utf-8",
processData: false,
cache:false,
contentType: false,
data: objdata,
success: function (response) {
console.log(objdata);
coursesData();
console.log(_data);
},
error: function (error) {
console.log(error);
}
});
});
<form name="myForm" id="myForm" method="post" class="form-inline" enctype="multipart/form-data">
<div style="border-right:1px solid black">
<input type="text" name="FirstName" id="FirstName" placeholder="Please enter First Name" class="form-control" /><br />
<input type="text" name="LastName" id="LastName" placeholder="Please enter Last Name" class="form-control" /><br />
<span class="radio-inline">
<input type="radio" name="Gender" id="Gender" value="Male" class="radio" />
<label class="control-label">Male</label>
</span>
<span class="radio-inline">
<input type="radio" name="Gender" id="Gender" value="FeMale" class="radio" />
<label>Female</label>
</span>
<span class="radio-inline">
<input type="radio" name="Gender" id="Gender" value="Others" class="radio" />
<label>Others</label>
</span><br />
<input type="text" id="Age" name="Age" placeholder="Please enter Age" class="form-control" /><br />
<input type="date" name="DateofBirth" id="DateofBirth" class="form-control" /><br />
<span id="CourseDDL"></span>
<input type="file" name="ImageFile" id="ImageFile" class="form-control" /><br />
<div class="form-group">
<input type="checkbox" name="isActive" id="isActive" class="checkbox" />
<label class="control-label" for="isActive">isActive</label>
</div>
<br />
<br />
<button value="EntitySubmit" name="btnEntity" id="btnEntity" class="btn btn-primary btnEntity">EntitySubmit</button>
<span style="padding-left:10px;padding-right:10px">|</span>
<button value="AdoSubmit" name="btnAdo" id="btnAdo" class="btn btn-success btnEntity">AdoSubmit</button>
</div>
</form>
Controller:
public ActionResult EntitySend(userdetails objUser)
{
byte[] bytes;
using (BinaryReader br = new BinaryReader(objUser.ImageFile.InputStream))
{
bytes = br.ReadBytes(objUser.ImageFile.ContentLength);
}
using (MVCTutorialEntities db = new MVCTutorialEntities())
{
db.tblUsers.Add( new tblUser
{
FirstName = objUser.FirstName,
LastName=objUser.LastName,
Gender=Convert.ToBoolean(objUser.Gender),
DateofBirth=objUser.DateofBirth,
isActive= objUser.isActive,
FileImage= new string(Encoding.ASCII.GetChars(bytes)),
});
db.SaveChanges();
}
return Json("Success....", JsonRequestBehavior.AllowGet);
}
model:
public class userdetails
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public int Age { get; set; }
public DateTime DateofBirth { get; set; }
public string Courses { get; set; }
public HttpPostedFileBase ImageFile { get; set; }
public bool isActive { get; set; }
}
I changed 'isActive' type to 'string' in model, then the value sending is taken as 'on' if "checkbox" is checked, else it takes 'off'.
by doing that converting string to bool is not getting possible, like eg.,convert.toboolean(); or by bool.parse();
checkbox and file are special parts of a form, they could be a simple string value or an array, JQuery cannot know what it is, unless you specify a special attribute to check.
combine the 2 code:
https://gist.github.com/oswaldoacauan/7580474
jQuery serialize does not register checkboxes
(function($) {
$.fn.serializeAll = function() {
var form = $(this),
formData = new FormData(),
formParams = form.serializeArray();
//the following code return files array, but if could be 1 only to match your viewmodel
$.each(form.find('input[type="file"]'), function(i, tag) {
// check whether you need multiple files
if($(tag)[0].attr('data-multiple')=='true'){
$.each($(tag)[0].files, function(i, file) {
formData.append(tag.name, file);
});
}
else{
//...get 1 file only
}
});
//Checkbox: you need to debug this part, I just copied it
//check whether multiple options are checked , I won't code it here.
formParams.concat(
form.find('input[type=checkbox]:not(:checked)').map(
function() {
return {"name": this.name, "value": this.value}
}).get());
$.each(formParams, function(i, val) {
formData.append(val.name, val.value);
});
return formData;
};
})(jQuery);
then use it:
$(document).on("click", ".btnEntity", function (e){
e.preventDefault();
....
var $form = $(this).closest('form');// or $(this).parent('form');// or what ever
....
$.ajax({
...
data: $form.serializeAll();
...
});
});
to make the above extension work widely in the whole project, probably you need to render 1 more attribute in html: data-multiple=true/false (Default is false). then check this attribute in extension: if it's true, serialize values to array, otherwise to a bool or file value, so it would match all your viewmodels.

Delete files in Edit view

In my application I try to delete single files from Edit view. It works ok, but doesn't refresh a site.
Item in FileDetails Class contains Id, Extension, FileName and TicketId(which is connected with Ticket class)
My code:
Method in Controller
#section Scripts {
<script>
$('.deleteItem').click(function (e) {
e.preventDefault();
var $ctrl = $(this);
if (confirm('Do you really want to delete this file?')) {
$.ajax({
url: '#Url.Action("DeleteFile")',
type: 'POST',
data: { id: $(this).data('id') }
}).done(function (data) {
if (data.Result == "OK") {
$ctrl.closest('li').remove();
}
else if (data.Result.Message) {
alert(data.Result.Message);
}
}).fail(function () {
alert("There is something wrong. Please try again.");
})
}
});
</script>
}
<div class="form-group">
<div class="col-md-10">
<p>Upload one or more files</p>
<input type="file" name="file" multiple />
</div>
<ul class="attachment">
#foreach (var item in Model.Ticket.FileDetails)
{
<li>
<a class="title" href="/Tickets/Download/?fileName=#(item.Id + item.Extension)&ticketId=#item.TicketId">#item.FileName</a>
X
</li>
}
</ul>
I get TypeError: data.Result is undefined
Check your data variable before getting its Result property. Your data should be available in data.

Ajax refreshing page in MVC

I'm using Ajax to pass some data to a Controller and save to database, and it works, the issue that is refreshing the page with every POST and I need to prevent that.
Ajax:
function AddComment(commet, auto) {
$.ajax({
type: "POST",
url: '/bff/SaveComment',
data: { id: idParte, commenta: commet, autoriza: auto },
dataType: 'json',
success: function (correct) {
$("#win1").show().kendoWindow({
width: "300px",
height: "100px",
modal: true,
title: "Added"
});
},
errror: function(inc) {
}
});
}
Controller:
[HttpPost]
public JsonResult SaveComment(int id, string commenta, string autoriza)
{
// Some logic here
return Json("");
}
Tried this way with correct.preventDefault(); but didn't work
Is there a way to do it?
EDITED:
This is my HTML:
<form role="form">
<div class="form-group">
#Html.Label("Commentario:")
<textarea id="Comment" style="resize:none;" class="form-control"></textarea>
</div>
<div class="form-group">
<input type="submit" value="Guardar" onclick="AddComment(Comment.value,'Comentario')" />
</div>
</form>
EDITED 2:
Fixed by changing type="submit" for type="button" Thanks to Hasta Pasta
i think you should put return false; after the ajax request
function AddComment(commet, auto) {
$.ajax({
type: "POST",
url: '/bff/SaveComment',
data: { id: idParte, commenta: commet, autoriza: auto },
dataType: 'json',
success: function (correct) {
$("#win1").show().kendoWindow({
width: "300px",
height: "100px",
modal: true,
title: "Added"
});
},
error: function(inc) {
}
});
return false;
}
based on you need to return false as you sayed :)
<form role="form">
<div class="form-group">
#Html.Label("Commentario:")
<textarea id="Comment" style="resize:none;" class="form-control"></textarea>
</div>
<div class="form-group">
<input type="submit" value="Guardar" onclick="return AddComment(Comment.value,'Comentario')" />
</div>
</form>

How to submit AJAX Form using radio button change event?

I have a AJAX form & I want to submit it on radio button change event.
AJAX Form:
#using (Ajax.BeginForm("Vote", "Rate", null ,
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET",
OnFailure = "searchFailed",
LoadingElementId = "ajax-loader",
UpdateTargetId = "searchresults",
},new { id = "voteForm" }))
{
<input type="radio" name="Stars" value="1">
<input type="radio" name="Stars" value="2">
<input type="radio" name="Stars" value="3">
}
I uses following code but it does not work.
$("#voteForm").ajaxSubmit({ url: '/Vote/Vote', type: 'get' });
Try this:
<script type="text/javascript">
$(function () {
$("input[name='Stars']").change(function() {
$("#voteForm").ajaxSubmit({ url: '/Vote/Vote', type: 'get' });
});
});
</script>
#Babul Mirdha Ajax.BeginForm is a mechanism that works fine, but customize specific submit behaviors very different from the standard can generate big headache. I think now you know that.
Every time I (and many other developers will say it too) need to develop some custom behavior I use the basic Jquery. Like this:
In your controller:
public JsonResult Vote(YourModel model)
{
// do something:
// model.Stars
return Json(new { message = "Success" }, JsonRequestBehavior.AllowGet);
}
Your model:
public class YourModel
{
// ...
public int Stars { get; set; }
}
And your view:
<script type="text/javascript">
$(function () {
$("#voteForm input[name=Stars]").change(function () {
$.ajax({
url: '/Home/Vote',
type: 'GET',
data: $("form#voteForm").serialize(),
dataType: 'json',
success: function (data) {
alert(data.message);
},
error: function (jq, message) {
alert(message);
}
});
});
});
</script>
<form id="voteForm" action="#Url.Action("Vote")">
<input type="radio" name="Stars" value="1" checked="checked"/>
<input type="radio" name="Stars" value="2" />
<input type="radio" name="Stars" value="3" />
<input type="text" name="Tbx" />
</form>
This way you have full control over behavior.

Categories