jQuery and ASP.NET Custom Validator - asp.net

I'm trying to learn jQuery and it occurred to me that existing JS in some of my sites could be replaced with just a few lines of jQuery code. In the following code, I'm trying to set the value of a custom validator by making an AJAX call. The first block of code does not work as it should, whereas the second block works fine. The whole "if it ain't broke don't fix it" answer isn't helpful, I really want to learn jQuery. For the record, I've placed alerts in the code and they both return the exact same result, just one is setting the args and the other is not for some reason.
Why does this code NOT work:
function CheckForUserName(sender, args)
{
args.IsValid = true;
var url = "/somepage.aspx";
MakeCall(url, function(txt) {
if (txt == "false") {
args.IsValid = false;
}
});
}
function MakeCall(url,callback) {
$.ajax({
url: url,
dataType: "text",
success: callback
});
}
This code DOES work:
function CheckForUserName(sender, args)
{
args.IsValid = true;
var call = MakeCall();
if (call == "false")
{
args.IsValid = false;
}
}
function MakeCall()
{
var xmlHttp;
var validation=true;
xmlHttp=GetXmlHttpObject();
if (xmlHttp==null)
{
alert ("Your browser does not support AJAX!");
return;
}
var url="/somepage.aspx";
xmlHttp.onreadystatechange=function ()
{
if (xmlHttp.readyState==4)
{
if (xmlHttp.status==200)
{
return xmlHttp.responseText;
}
else
{
alert(xmlHttp.status);
}
}
};
xmlHttp.open("GET",url,false);
xmlHttp.send(null);
return xmlHttp.responseText;
}
function GetXmlHttpObject()
{
var xmlHttp=null;
try
{
// Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
}
catch (e)
{
// Internet Explorer
try
{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}

In order to make it work, you need to specify the async option as false:
function MakeCall(url,callback) {
$.ajax({
async: false,
url: url,
dataType: "text",
success: callback
});
}

This works fyi.. ignore my custom javascript namespace functions, but you should get the concept.
<script type="text/javascript">
function VerifyCustomerNumber(s, a) {
var r = ProcessCustomerNumber(a.Value);
a.IsValid = r;
}
function ProcessCustomerNumber(n) {
var u = '/Services/WebServices/Customer.asmx/CountByCustomerNumber';
var d = '{"Number": "' + n + '"}';
$j.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: u,
cache: false,
async: false,
data: d,
dataType: "json",
success: function(r) {
var v = Data.JS.Ajax.ParseJSON(r);
return v;
}
});
}
</script>

Just for the record. Having a custom validator that allows AJAX calls is possible, but is a litle complicated. Here is an article about the issue.
Basically, one must do these things:
Say "Invalid!" immediately.
Show a "processing..." message instead of your "invalid" message.
Start your long-runing process, AKA your AJAX request.
As soon as your request ends, replace the ClientValidationFunction for a dummy function.
Reset the original message.
Update the validation state.
Reset the original validation function but only when the validated control changes.
Here is the final function that accomplishes the task (taken from the article):
//Create our respond functions...
var Respond_True = function (sender, args) { args.IsValid = true; };
var Respond_False = function (sender, args) { args.IsValid = false; };
function AjaxValidator(sender, args, ajaxSettings){
args.IsValid = false;
//This is a reference to our validator control
var $sender = $(sender);
//Save the original message, color and validation function to restore them later.
var originalMessage = $sender.text();
var originalColor = $sender.css("color");
var originalFunction = sender.clientvalidationfunction;
var validatedControl = $("#" + sender.controltovalidate);
//Change the error message for a friendlier one.
$sender.text("Checking...").css({ color: "black" });
var setRespondFunction = function (respondFunction) {
sender.clientvalidationfunction = respondFunction;
//Reconstitute original styles.
$sender.text(originalMessage).css({ color: originalColor });
//Re-validate our control
ValidatorValidate(sender, null, null);
ValidatorUpdateIsValid();
var onChange = function(){
//Reset the original validation function
sender.clientvalidationfunction = originalFunction;
//Re-validate to ensure the original validation function gets called
ValidatorValidate(sender, null, null);
ValidatorUpdateIsValid();
//Ensure the validation function is called just once.
validatedControl.unbind("change", onChange);
};
validatedControl.on("change", onChange);
}
var originalSuccessFunction = ajaxSettings.success;
//Start the AJAX call..
$.ajax($.extend(ajaxSettings, {
success: function(data){
setRespondFunction(originalSuccessFunction(data) ? "Respond_True" : "Respond_False");
}
}));
}
And here is a sample usage:
function MyJavascriptValidationFunctionName(sender, args){
AjaxValidator(sender, args, {
url: ...,
type: ...,
data: ...,
success: function(data){
return /*True or false*/;
}
});
}

Related

Autocomplete Web Service in ASP.Net web forms

I have a web service for multiple item selection, its working fine but i am getting Undefined data. anyone can tell me solution for it. I am attaching my error screenshot too with this post, please see them below.
Web Service JSON Code
<script type="text/javascript">
$(document).ready(function () {
SearchText();
});
function SearchText() {
$("[id*=ctl00_ContentMain_TextBoxSkills]").autocomplete({
source: function (request, response) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: '<%=ResolveUrl("WebServiceSkills.asmx/GetAutoCompleteData")%>',
data: "{'skill':'" + extractLast(request.term) + "'}",
dataType: "json",
success: function (data) {
response(data.d);
},
error: function (result) {
alert("No Result Found");
}
});
},
focus: function () {
// prevent value inserted on focus
return false;
},
select: function (event, ui) {
var terms = split(this.value);
// remove the current input
terms.pop();
// add the selected item
terms.push(ui.item.value);
// add placeholder to get the comma-and-space at the end
terms.push("");
this.value = terms.join(", ");
return false;
}
});
$("#ctl00_ContentMain_TextBoxSkills").bind("keydown", function (event) {
if (event.keyCode === $.ui.keyCode.TAB &&
$(this).data("autocomplete").menu.active) {
event.preventDefault();
}
})
function split(val) {
return val.split(/,\s*/);
}
function extractLast(term) {
return split(term).pop();
}
}
</script>
Web Service:
[WebMethod]
public List<UserRegistration> GetAutoCompleteData(string skill)
{
List<UserRegistration> list = new List<UserRegistration>();
UserRegistrationHelper userRegistrationHelper = new UserRegistrationHelper();
using (DataTable dataTable = userRegistrationHelper.GetSkillsList(skill))
{
if (CommonFunctions.ValidateDataTable(dataTable))
{
foreach (DataRow dr in dataTable.Rows)
{
var SkillsList = new UserRegistration
{
SkillId = Convert.ToInt32(dr["SkillId"].ToString()),
Skills=dr["SkillName"].ToString()
};
list.Add(SkillsList);
}
}
}
return list;
}
Screenshot here:
I got answer for it:
1: Change SQL Query:
select concat('[', STUFF
(
(
SELECT top 15 '","'+ CAST(skillname AS VARCHAR(MAX))
from DNH_Master_Skills where SkillName LIKE '%' + #SkillName + '%'
FOR XMl PATH('')
),1,2,''
),'"]')
2: Change JSON Code:
From: response(data.d); TO: response(Array.parse(data.d));
Now its working feeling happy.

jQuery Ajax success response returns HTML and not my intended value

I'm calling the Page Method and it's returning all of the HTML in this page and not the value of 1 or 0.
I don't know why this is. Can someone point me in the right direction ?
JavaScript:
$.ajax({
async: false,
type: "POST",
contentType: "application/json; charset=utf-8",
data: '{}',
url: "main.aspx/IsInfoComplete",
success: function(data, textStatus, jqXHR) {
console.log(textStatus);
console.log(data.d);
// act on return value:
if(data==0) {
// todo -
} else if (data==1) {
// todo -
}
}
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(textStatus);
}
});
Server:
[System.Web.Services.WebMethod()]
public int IsInfoComplete()
{
int returnValue = 0;
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = conn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "GetIsUserInfoComplete";
cmd.Parameters.AddWithValue("#UserName", userName);
conn.Open();
try
{
returnValue = (int)cmd.ExecuteScalar();
}
catch (Exception) { /* todo - */ }
}
return returnValue;
}
One thing you might try is to write your success function like this,
success: function (result) {
if (result!="False") {
//it worked
}
else {
//it failed
}
},
And change your server side method to return a bool. This would probably get you the desired results. I had to do this in something I wrote and it worked just fine. Little silly that you have to check for "False" but it worked.
Note: Case matters when looking for the word "False"
Look's like this is messing it up.. data here is an object and you are trying to compare the data with a 0 or a 1
success: function(data, textStatus, jqXHR) {
console.log(data); // Check the format of data in object
if(data != null){
console.log(data.d); // Generally your actual dat is in here
// act on return value:
if(data.d ==0) {
// todo -
} else if (data.d ==1) {
// todo -
}
}
},
If thats the case is your WebService returning a json object in the first place..
You need to decorate your webservice with this..
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
[System.Web.Services.WebMethod()]
public int IsInfoComplete()
{
And set the dataType :'json' in your ajax request

ASP.NET Validate membership email from ClientSideEvents and WebMethod

I have ASPxGridview and i want to check if email already registered before or not in editform using ClientSideEvents.
Any help to resolve this problem ?
aspx section
this is the javascript section
function OnEmailValidation(s, e) {
var error = "";
var tfld = trim(e.value);
var illegalChars = /^\w+([-+.'''']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
if (!illegalChars.test(tfld)) {
$get("spanEmail").innerHTML = "invalid email";
} else {
PageMethods.CheckEmail(e.value.toString(), OnCheckEmail);
// how to check OnCheckEmail before continue
//if(email already registered) {
// return false
//}
$get("spanEmail").innerHTML = "";
}
return true;
}
function OnCheckEmail(unavailable) {
if (unavailable == true) {
$get("spanEmail").innerHTML = "already registered";
$get("spanEmail").style.color = "red";
}
else if (unavailable != true) {
$get("spanEmail").innerHTML = "Available";
$get("spanEmail").style.color = "#76EB69";
}
}
aspx.cs
col_Email.PropertiesTextEdit.ClientSideEvents.Validation = "OnEmailValidation";
grid.Columns.Add(col_Email);
[WebMethod]
public static bool CheckEmail(string email)
{
System.Threading.Thread.Sleep(200);
if (Membership.FindUsersByEmail(email) != null)
{
if (Membership.FindUsersByEmail(email).Count <= 0)
{
return false;
}
return true;
}
else
{
return false;
}
}
This is my final code after the
Filip
advice but i have mini problem:
When i use
(async: false) and cntr.SetIsValid(false);
the control doesn't apply the action
but If i use
(async: true) and cntr.SetIsValid(false);
the control apply the action
Why ?
I want to use async: false
function OnEmailValidation(s, e) {
var illegalChars = /^\w+([-+.'''']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
var spanEmail = document.getElementById("spanEmail");
var obj = GetObj('txt_Email');
var cntr = aspxGetControlCollection().Get(obj.id);
if (!illegalChars.test(e.value)) {
spanEmail.innerHTML = "Invalid Email";
spanEmail.style.color = "red";
cntr.SetIsValid(false);
} else {
$.ajax({
type: "POST",
async: false,
url: "myweb_service.asmx/CheckEmail",
data: "{'email':'" + e.value.toString() + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(res) {
if (res.d == "true") {
spanEmail.innerHTML = "Email register before";
spanEmail.style.color = "red";
cntr.SetIsValid(false);
}
if (res.d == "false") {
spanEmail.innerHTML = "Available";
spanEmail.style.color = "#76EB69";
cntr.SetIsValid(true);
}
}
});
}}
You can use jQuery to call PageMethods (replace PageMethods.CheckEmail call with this code):
$.ajax({
type: "POST",
async: false,
url: "<PageName>.aspx/CheckEmail",
data: "{" + e.value.toString() + "}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(res) {
if (res.d)
return false;
}
});
Replace PageName with your page name.
Be careful with synchronous (async: false) ajax calls. They will block your page until request finishes.
If res.d doesn't return result or you just want detailed explanation of posted code check these links:
Using jQuery to directly call aspnet ajax page methods
A breaking change between versions of aspnet ajax
You will need to set up a web service on the server side that will check if the email already exists. Then you will use JavaScript AJAX (preferably a library like jQuery or Prototype) to query the web service during your validation method.
it will be a good deal of work to get it all set up. Good luck. See one of these links for more information:
http://msdn.microsoft.com/en-us/library/bb532367.aspx
http://msdn.microsoft.com/en-us/library/t745kdsh.aspx

making ajax call (in jquery) for webservice in asp.net

I want to validate product code for duplication using ajax call(in jquery) for webservice in which web method is written. now if success function executes as 'duplicate product code' it should not allow the user to save record. so how can i check this on Save buttons click event
First, create the below method in the page code behind.
using System.Web.Services;
[WebMethod]
public static bool CheckDuplicateCode(string productCode)
{
bool isDuplicate = false;
int pCode = Convert.ToInt32(productCode);
//check pCode with database
List<int> productCodes = GetProductCodeInDb();
foreach (var code in productCodes)
{
if (pCode == code)
{
isDuplicate = true;
break;
}
}
return isDuplicate;
}
And in the page markup just before the end body tag insert this code
<script type="text/javascript">
$(document).ready(function () {
$('#<%=btnSave.ClientID %>').click(function () {
SaveProduct();
});
});
function SaveProduct() {
//Get all the data that you are trying to save
var pCode = $('#<%= txtProductCode.ClientID %>').val();
//pass the product code to web method to check for any duplicate
$.ajax({
type: "POST",
url: "/InsertProductPage.aspx/CheckDuplicateCode",
data: "{'productCode': '" + pCode + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
AjaxSuccees(msg);
},
error: AjaxFailed
});
}
function AjaxSuccees(msg) {
if (msg.d == true) {
return true;
//insert the rest of data
}
else {
alert("Product code already exists");
return false;
}
}
function AjaxFailed(msg) {
alert(result.status + ' ' + result.statusText);
}
</script>
Hope this helps

How to do a ASP.NET MVC Ajax form post with multipart/form-data?

I am working on a ASP.NET MVC web site which has a form that allows for the upload of files using the multipart/form data enctype option on the form tag like so
<form enctype="multipart/form-data" method="post" action='<%= Url.Action("Post","Entries",new {id=ViewData.Model.MemberDetermination.DeterminationMemberID}) %>'>
How would I write this to do an ASP.NET MVC Ajax form post instead?
It is possible but it's a long way.
Step 1: write your form
ex:
#using (Ajax.BeginForm(YourMethod, YourController, new { id= Model.Id }, new AjaxOptions {//needed options }, new { enctype = "multipart/form-data" }))
{
<input type="file" id="image" name="image" />
<input type="submit" value="Modify" />
}
Step 2: intercept the request and send it to the server
<script type="text/javascript">
$(function() {
$("#form0").submit(function(event) {
var dataString;
event.preventDefault();
var action = $("#form0").attr("action");
if ($("#form0").attr("enctype") == "multipart/form-data") {
//this only works in some browsers.
//purpose? to submit files over ajax. because screw iframes.
//also, we need to call .get(0) on the jQuery element to turn it into a regular DOM element so that FormData can use it.
dataString = new FormData($("#form0").get(0));
contentType = false;
processData = false;
} else {
// regular form, do your own thing if you need it
}
$.ajax({
type: "POST",
url: action,
data: dataString,
dataType: "json", //change to your own, else read my note above on enabling the JsonValueProviderFactory in MVC
contentType: contentType,
processData: processData,
success: function(data) {
//BTW, data is one of the worst names you can make for a variable
//handleSuccessFunctionHERE(data);
},
error: function(jqXHR, textStatus, errorThrown) {
//do your own thing
alert("fail");
}
});
}); //end .submit()
});
</script>
Step 3: Because you make an ajax call you probably want to replace some image or something of multipart/form-data
ex:
handleSuccessFunctionHERE(data)
{
$.ajax({
type: "GET",
url: "/Profile/GetImageModified",
data: {},
dataType: "text",
success: function (MSG) {
$("#imageUploaded").attr("src", "data:image/gif;base64,"+msg);
},
error: function (msg) {
alert(msg);
}
});
}
The MSG variable is an base64 encrypted string. In my case it's the source of the image.
In this way I managed to change a profile picture and after that the picture is immediately updated.
Also make sure you add in Application_Start (global.asax)
ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
Pretty nice no?
P.S.: This Solution works so don't hesitate to ask more details.
I came across this little hack, which resolves it nicely
window.addEventListener("submit", function (e) {
var form = e.target;
if (form.getAttribute("enctype") === "multipart/form-data") {
if (form.dataset.ajax) {
e.preventDefault();
e.stopImmediatePropagation();
var xhr = new XMLHttpRequest();
xhr.open(form.method, form.action);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
if (form.dataset.ajaxUpdate) {
var updateTarget = document.querySelector(form.dataset.ajaxUpdate);
if (updateTarget) {
updateTarget.innerHTML = xhr.responseText;
}
}
}
};
xhr.send(new FormData(form));
}
}
}, true);
You can use some additional uploaders (e.g. jQuery multiple file uploader) (I prefer this way and I prefer not to use MS Ajax)
Use:
AjaxHelper.BeginForm("Post", "Entries", new {id=ViewData.Model.MemberDetermination.DeterminationMemberID}, new AjaxOptions(){/*some options*/}, new {enctype="multipart/form-data"})
But in second case I'm not sure that it will work.
The jquery forms plugin supports file uploads in this way.
Code which I used and it works !! It's a copy of #James 'Fluffy' Burton solution. I just improvising his answer so that people who is new to MVC will be able to quickly understand the consequences.
Following are my View:
#using (Ajax.BeginForm("FileUploader", null, new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "AjaxUpdatePanel" }, new { enctype = "multipart/form-data", id = "frmUploader" })){
<div id="AjaxUpdatePanel">
<div class="form-group">
<input type="file" id="dataFile" name="upload" />
</div>
<div class="form-group">
<input type="submit" value="Upload" class="btn btn-default" id="btnUpload"/>
</div>
</div>}
<script>
window.addEventListener("submit", function (e) {
var form = e.target;
if (form.getAttribute("enctype") === "multipart/form-data") {
if (form.dataset.ajax) {
e.preventDefault();
e.stopImmediatePropagation();
var xhr = new XMLHttpRequest();
xhr.open(form.method, form.action);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
if (form.dataset.ajaxUpdate) {
var updateTarget = document.querySelector(form.dataset.ajaxUpdate);
if (updateTarget) {
updateTarget.innerHTML = xhr.responseText;
}
}
}
};
xhr.send(new FormData(form));
}
}
}, true);
Following are my controller:
[HttpPost]
public JsonResult FileUploader(HttpPostedFileBase upload)
{
if (ModelState.IsValid)
{
if (upload != null && upload.ContentLength > 0)
{
if (upload.FileName.EndsWith(".csv"))
{
Stream stream = upload.InputStream;
DataTable csvTable = new DataTable();
using (CsvReader csvReader = new CsvReader(new StreamReader(stream), true))
{
csvTable.Load(csvReader);
}
}
else
{
return Json(new { dataerror = true, errormsg = "This file format is not supported" });
}
}
else
{
return Json(new { dataerror = true, errormsg = "Please Upload Your file" });
}
}
return Json(new { result = true });
}
Following is the quick Note of above code:
Through Ajax, I have posted my excel (*.csv) file to Server and read it to an DataTable using a Nuget package (LumenWorksCsvReader).
Hurray! It works. Thanks #James
I actually answered the question myself...
<% using (Ajax.BeginForm("Post", "Entries", new { id = ViewData.Model.MemberDetermination.DeterminationMemberID }, new AjaxOptions { UpdateTargetId = "dc_goal_placeholder" }, new { enctype = "multipart/form-data" }))
For those who still have problems using #Ajax.BeginForm for multipart enctypes / file uploads in MVC
Diagnosis and proposed solution
Running the “Inspect element” tool on a form element generated by the #Ajax.BeginForm helper reveals that the helper, rather inexplicably, overrides the controller parameter specified. This is the case if you implemented a separate controller for your partial postback.
A quick-fix for the problem is to explicitly specify your html action attribute value as /<yourcontrollername>/<youractionname>.
Example
#using (Ajax.BeginForm("", "", new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "<TargetElementId>", InsertionMode = InsertionMode.Replace }, new { enctype = "multipart/form-data", action = "/<Controller>/<Action>" }))
If you need to use the OnSuccess AjaxOption and/or use Request.IsAjaxRequest() in the controller to check the request type i.e.
#using (Ajax.BeginForm("FileUploader", null, new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "elementToUpdate", OnSuccess = "mySuccessFuntion(returnedData)", OnFailure = "myFailureFuntion(returnedData)"}, new { enctype = "multipart/form-data" }))
Then you can use the following code (I've modified #James 'Fluffy' Burton's answer). This will also convert the response text to JSON object if it can (you can omit this if you want).
<script>
if(typeof window.FormData === 'undefined') {
alert("This browser doesn't support HTML5 file uploads!");
}
window.addEventListener("submit", function (e) {
var form = e.target;
if (form.getAttribute("enctype") === "multipart/form-data") {
if (form.dataset.ajax) {
e.preventDefault();
e.stopImmediatePropagation();
var xhr = new XMLHttpRequest();
xhr.open(form.method, form.action);
xhr.setRequestHeader("x-Requested-With", "XMLHttpRequest"); // this allows 'Request.IsAjaxRequest()' to work in the controller code
xhr.onreadystatechange = function () {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
var returnedData; //this variable needs to be named the same as the parameter in the function call specified for the AjaxOptions.OnSuccess
try {
returnedData = JSON.parse(xhr.responseText); //I also want my returned data to be parsed if it is a JSON object
}catch(e){
returnedData = xhr.responseText;
}
if (form.dataset.ajaxSuccess) {
eval(form.dataset.ajaxSuccess); //converts function text to real function and executes (not very safe though)
}
else if (form.dataset.ajaxFailure) {
eval(form.dataset.ajaxFailure);
}
if (form.dataset.ajaxUpdate) {
var updateTarget = document.querySelector(form.dataset.ajaxUpdate);
if (updateTarget) {
updateTarget.innerHTML = data;
}
}
}
};
xhr.send(new FormData(form));
}
}
}, true);
</script>
N.B. I use the javascript function eval() to convert the string in to a function... if anyone has a better solution please comment.
I also use JQuery JSON.parse() so this isn't a vanilla javascript solution but it isn't required for the script to function so it could be removed.
I mixed Brad Larson answer with Amirhossein Mehrvarzi, because Brad answer wasn't providing any way to handle the response and Amirhossein was causing 2 postbacks.
I just added ($('#formBacklink').valid()) to call model validation before send.
window.addEventListener("submit", function (e) {
if ($('#formBacklink').valid()) {
var form = e.target;
if (form.getAttribute("enctype") === "multipart/form-data") {
if (form.dataset.ajax) {
e.preventDefault();
e.stopImmediatePropagation();
var dataString;
event.preventDefault();
var action = $("#formBacklink").attr("action");
if ($("#formBacklink").attr("enctype") == "multipart/form-data") {
//this only works in some browsers.
//purpose? to submit files over ajax. because screw iframes.
//also, we need to call .get(0) on the jQuery element to turn it into a regular DOM element so that FormData can use it.
dataString = new FormData($("#formBacklink").get(0));
contentType = false;
processData = false;
} else {
// regular form, do your own thing if you need it
}
$.ajax({
type: "POST",
url: action,
data: dataString,
dataType: "json", //change to your own, else read my note above on enabling the JsonValueProviderFactory in MVC
contentType: contentType,
processData: processData,
success: function (data) {
//BTW, data is one of the worst names you can make for a variable
//handleSuccessFunctionHERE(data);
},
error: function (jqXHR, textStatus, errorThrown) {
//do your own thing
}
});
}
}
}
}, true);
Ajax.BegineForm() works with multipart form data and here's the working code example for the same:
View:
#using(Ajax.BeginForm("UploadFile","MyPOC",
new AjaxOptions {
HttpMethod = "POST"
},
new
{
enctype = "multipart/form-data"
}))
{
<input type="file" name="files" id="fileUploaderControl" />
<input type="submit" value="Upload" id="btnFileUpload" />
}
Controller Action Method:
public void UploadFile(IEnumerable<HttpPostedFileBase> files)
{
HttpPostedFileBase file = files.FirstOrDefault(); //Attach a debugger here and check whether you are getting your file on server side or null.
if (file != null && file.ContentLength > 0)
{
//Do other validations before saving the file
//Save File
file.SaveAs(path);
}
}
P.S. Make sure the "name" attribute of the file uploader control and the name of the parameter passed to Action method UploadFile() has to be same (i.e. "files" in this case).
From my little investigation. All the answers above seems to be correct depending on the problem one is having with the Ajax.BeginForm. However, I have just observe that the problem is with the ~/Scripts/jquery.unobtrusive-ajax.min.js javascript library in some case. So in my case I just removed it from the view model and sort of decided to use JQuery Form plugin for my required need along with the HTML Form instead. This has been suggested above.
You can use this code instead of eval
var body = "function(a){ " + form.dataset.ajaxSuccess + "(a) }";
var wrap = s => "{ return " + body + " };"
var func = new Function(wrap(body));
func.call(null).call(null, returnedData);

Resources