Stop Execution of HTTPPOST ActionMethod in MVC - c#

I have webApplication in MVC Framework..
i have situation where i have to provide user to export some data to csv file
for that i have written following code ..
[HttpPost]
public ActionResult ExportReportToFile(ReportCriteriaViewModels posdata, string name)
{
string strQuery = GetReportQuery(posdata, name);
IEnumerable<REP_MM_DEMOGRAPHIC_CC> lstDemographics = ReportDataAccess.GetReportData<REP_MM_DEMOGRAPHIC_CC>(strQuery);
if (lstDemographics.Count() > 0)
return new CsvActionResult<REP_MM_DEMOGRAPHIC_CC>(lstDemographics.ToList(), "LISDataExport.csv");
else
return view(posdata);
}
Above code works fine... if in listResult Count is Greater than zero then i returns File to download.. but if i dont get any records in lstDemographics then i returns view..
My problem is when i dont get any result in lstDemographics, i dont want to return view coz it refreshes whole view.. so is there any way where we can stop execution of Action Method and browser doesn't refresh the view and stay as it is..
Thanks..

You will have to make an AJAX call to stop page refresh.
To achieve file export, we actually broke the process in two AJAX calls. First call sends a request to server, server prepare a file and store it in temp table. Server return the file name to AJAX call if there is data. If no data or error, it return a JSON result to indicate a failure.
On success, view make another AJAX request to download the file passing file name.
Something like this:
[Audit(ActionName = "ExportDriverFile")]
public ActionResult ExportDriverFile(int searchId, string exportType, string exportFormat)
{
var user = GetUser();
var driverSearchCriteria = driverSearchCriteriaService.GetDriverSearchCriteria(searchId);
var fileName = exportType + "_" + driverSearchCriteria.SearchType + "_" + User.Identity.Name.Split('#')[0] + "." + exportFormat;
//TempData["ExportBytes_" + fileName] = null;
_searchService.DeleteTempStore(searchId);
var exportBytes = exportService.ExportDriverFileStream(driverSearchCriteria, searchId, exportType, exportFormat, user.DownloadCode, user.OrganizationId);
if (exportBytes != null)
{
var tempStore = new TempStore
{
SearchId = searchId,
FileName = fileName,
ExportFormat = exportFormat,
ExportType = exportType,
DataAsBlob = exportBytes
};
var obj = _searchService.AddTempStore(tempStore);
return Json(fileName);
}
else
{
return Json("failed");
}
}
[HttpGet]
public ActionResult DownloadStream(string fileName, int searchId)
{
var tempStore = _searchService.GetTempStore(searchId);
var bytes = tempStore.DataAsBlob;
if (bytes != null)
{
var stream = new MemoryStream(bytes);
// TempData["ExportBytes_" + fileName] = null;
_searchService.DeleteTempStore(searchId);
return File(stream, "application/vnd.ms-excel", fileName);
}
_logger.Log("Export/DownloadStream request failed", LogCategory.Error);
return Json("Failed");
}
At client side, we do something like:
function ExportData(exportType, exportFormat) {
var searchId = document.getElementById('hfSelectedDriverId').value;
var model = { searchId: searchId, exportType: exportType, exportFormat: exportFormat };
//$('div[class=ajax_overlay]').remove();
//alert("The file will be downloaded in few minutes..");
$.ajax({
url: '#Url.Action("ExportDriverFile", "Export")',
contentType: 'application/json; charset=utf-8',
type: 'POST',
dataType: 'html',
data: JSON.stringify(model)
})
.success(function (result) {
result = result.toString().replace(/"/gi, "");
if (result == "" || result == "failed")
{
alert("File download failed. Please try again!");
}
else
{
window.location = '/Export/DownloadStream?fileName=' + result+"&searchId="+searchId;
}
})
.error(function (xhr, status) {
//
//alert(status);
});
//$('div[class=ajax_overlay]').remove();
}

You should create javascript function with $.getJSON method.
On controller side you just have to check, if you get data from database then return file path else return message.
Your JS code should be something like this:
$.getJSON(url)
.done(function (data) {
if (data.filePath) // If get data, fill filePath
window.location = data.filePath;
else
alert(data.msg);
});
And from controller you can create a HTTPGET Action method that return JSON data like:
return Json(new { msg = "No data found" }, JsonRequestBehavior.AllowGet);
Based on condition you can simple change msg with filePath.

Related

Passing potential huge files in chunks to Web API

I have to pass potential huge files from an ASP.NET Core middle Server to an ASP.NET backend.
I can’t use the ASP.NET backend web API directly, I have to go over a MVC Controller.
Currently my middle Server gets the file in Chunks (and does some verification), saves it to disk and after it completes it rereads it in chunks to pass it forward.
Is there an easy way to pass the chunks without buffering the file?
I currently got this:
MVC Controler:
[HttpPost]
public ActionResult UploadChunk(IFormFile fileChunk, string chunkMetadata)
{
if (!string.IsNullOrEmpty(chunkMetadata))
{
var metaDataObject = JsonConvert.DeserializeObject<ChunkMetadata>(chunkMetadata);
...
AppendContentToFile(tempFilePath, fileChunk); //writes file with FileMode.Append,
}
}
my upload to back end [Edit]:
public IHttpActionResult FileUpload(string fileUri)
{
try
{
if (Request.Content.IsMimeMultipartContent())
{
var configProvider = Resolve<IApplicationConfigurationProvider>();
var uploadRootDir = configProvider.TemporaryFileUploadPath;
var streamProvider = new MultipartStreamProvider(uploadRootDir);
// If the file is huge and is not split into chunks, the 'ReadAsMultipartAsync' call
// takes as long as full file has been copied
var readResult = Request.Content.ReadAsMultipartAsync(streamProvider).Result;
var fileSvc = Resolve<IFileService>();
string targetFilePath = string.Empty;
foreach (MultipartFileData fileData in streamProvider.FileData)
{
ContentDispositionHeaderValue contentDisposition = fileData.Headers.ContentDisposition;
string fileName = contentDisposition.FileName;
if (!GetFileName(fileName, out var targetFileName))
{
return BadRequest($"ContentDisposition.FileName must match 'file' of URI-query! Actual: {targetFileName}");
}
var rawSourceFileInfo = new FileInfo(targetFileName);
if (contentDisposition.Size.HasValue && contentDisposition.Size.Value > 0)
{
if (!fileSvc.CreateNewFilePath(fileUri, new PathOptions(true), out var validFileFullPath))
{
return BadRequest($"Unable to create physical-path from fileId='{fileUri}'");
}
targetFilePath = validFileFullPath.FullName;
fileSvc.AddChunk(validFileFullPath.FullName, contentDisposition.Size.Value, fileData.LocalFileName);
}
else
{
return BadRequest("File upload must set a valid file-length in ContentDisposition");
}
}
return Ok(targetFilePath);
}
else
{
return BadRequest("File upload must be a 'IsMimeMultipartContent'");
}
}
catch (Exception error)
{
LogError(error, "FileUpload");
return InternalServerError(error);
}
}
Thanks in advance for any help!
[Edit]
my not working call from client to back end:
<script>
$(document).ready(function (e) {
$("#uploadImage").on('change', (function (e) {
// append file input to form data
var fileInput = document.getElementById('uploadImage');
var file = fileInput.files[0];
var formData = new FormData();
formData.append('uploadImage', file);
$.ajax({
url: "http://localhost/service/filestore/v1/upload?fileUri=someText",
type: "POST",
data: formData,
contentType: false,
cache: false,
processData: false,
success: function (data) {
if (data == 'invalid') {
// invalid file format.
$("#err").html("Invalid File !").fadeIn();
}
else {
// view uploaded file.
$("#preview").html(data).fadeIn();
$("#form")[0].reset();
}
},
error: function (e) {
$("#err").html(e).fadeIn();
}
});
}));
});
</script>

How to pass docx file from Controller into View using AJAX?

Hi Stack Overflow community, first post, work your magic!
The problem I'm having is that I can generate my docx file, but when I try to return it the data is coming back in a format that I've never seen before? Does anyone know what this is?
Screenshot of unidentifiable code - it looks like Wingdings
Starting with the razor view
//Start action
$('#returnDeductionSheets').click(function () {
//Retrieve date options for user to select
$.ajax({
async: true,
type: 'POST',
url: 'ReturnDeductionsSheetList',
success: function (data) {
if (data != null) {
var options = data;
//Format JSON dates into read-able date time format
function formatDate(options) {
var dateString = options.substring(6);
var currentTime = new Date(parseInt(dateString));
var month = currentTime.getMonth() + 1;
var day = currentTime.getDate();
var year = currentTime.getFullYear();
var date = day + "/" + month + "/" + year;
return date;
};
//Check if I have more than one date, then return the options via a Bootbox view
if (options.length > 1) {
bootbox.prompt({
title: "Select the Deductions Sheet you would like to print.",
inputType: 'checkbox',
inputOptions: [
{
text: 'Deductions commenced on ' + formatDate(options[3]),
value: options[2],
},
{
text: 'Deductions commenced on ' + formatDate(options[1]),
value: options[0],
}
],
callback: function (result) {
//Pass the selected option into another AJAX method to generate the document else return to the view
if (result != null) {
$.ajax({
type: 'POST',
url: '#Url.Action("DeductionsSheet", "Home")?result=' + result,
contentType: 'application/json; charset=utf-8',
success: function (data) {
if (data.fileName != "") {
//window.location = "#Url.RouteUrl(new { Controller = "Home", Action = "Download" })/?file=" + data.fileName;
window.location = '/Home/ContractSpecificDocuments?file=' + data.fileName;
}
}
});
} else {
return;
};
}
});
}
else {
I'm happy that the Bootbox code works and the value that is passed into the DeductionsSheet ActionResult in the controller so I will jump to this code.
DeductionsSheet method (top of the method)
The value comes into the method as an array which I get through the [0] index.
public ActionResult DeductionsSheet(List<object> result)
{
//BOILER PLATE CODE
/////////////////////////////////////////
XceedDeploymentLicense.SetLicense();
var dateStamp = DateTime.Now.ToString("yyyy-dd-M--HH-mm-ss");
_replacePatterns = new Dictionary<string, string>();
int contractNumber = Convert.ToInt32(Request.Cookies["ContractNumber"].Value);
int contractContibutionHistoryId = Convert.ToInt32(result[0]);
The document is generated
DeductionsSheet method (bottom of the method)
document.SaveAs(DocumentOutputDirectory + #"\RMContributions_" + dateStamp + #".docx");
}
string fileName = "RMContributions_" + dateStamp + #".docx";
return File(new FileStream(DocumentOutputDirectory + #"\RMContributions_" + dateStamp + #".docx", FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.DeleteOnClose), "application/vnd.openxmlformats-officedocument.wordprocessingml.document", fileName);
The ActionResult finishes and returns back to the AJAX method, shown below here (same code as in Razor View block above).
success: function (data) {
if (data.fileName != "") {
//window.location = "#Url.RouteUrl(new { Controller = "Home", Action = "Download" })/?file=" + data.fileName;
window.location = '/Home/ContractSpecificDocuments?file=' + data.fileName;
}
}
I'm not sure if it's a data-type parse problem, or if something needs serializing, I'm open to all suggestions.
Now I'm not committed to this approach so if anyone can suggest an alternative as long as it works I'm happy. Ideally I would call the AJAX method and pass the data into the controller and then not return to the AJAX method, but I've not found a way of doing this.
I did try a simpler alternative whereby in the Bootbox callback I trigger the DeductionsSheet ActionResult using a jQuery trigger event but with this approach I couldn't get the data to pass into the controller.
Alternative approach using trigger event
callback: function (result) {
//Pass the selected option into another AJAX method to generate the document else return to the view
if (result != null) {
$('#deductionsSheet').trigger('click', [result]);
} else {
return;
};
}
Thanks for your help.

Error "Requested JSON parse failed" in downloading excel file

I have an action method which returns an excel file in return. I am calling that action method using ajax. I am getting Requested JSON parse failed.
$.ajax({
url: importUrl,
data: {
X: "12",
Y: "12",
Z: "12"
},
success: function (data) {
alert("S: "+data);
},
error: function (jqXHR, exception) {
var msg = '';
if (jqXHR.status === 0) {
msg = 'Not connect.\n Verify Network.';
} else if (jqXHR.status == 404) {
msg = 'Requested page not found. [404]';
} else if (jqXHR.status == 500) {
msg = 'Internal Server Error [500].';
} else if (exception === 'parsererror') {
msg = 'Requested JSON parse failed.';
} else if (exception === 'timeout') {
msg = 'Time out error.';
} else if (exception === 'abort') {
msg = 'Ajax request aborted.';
} else {
msg = 'Uncaught Error.\n' + jqXHR.responseText;
}
console.log(msg);
}
});
public ActionResult ExportReportToExcel(string X, string Y, string Z)
{
if (HttpContext.Request.UrlReferrer == null)
TempData["PDFPrevUrl"] = Url.RouteUrl("PageNotFound");
else if (TempData["PDFPrevUrl"] == null)
TempData["PDFPrevUrl"] = HttpContext.Request.UrlReferrer.PathAndQuery;
var customer = _authenticationService.CurrentCustomer;
if (customer == null)
return new LmsHttpUnauthorizedResult();
string filename = "Report";
try
{
XLWorkbook wb = new XLWorkbook(Server.MapPath(#"~/Content/CumulativePerformanceReportTemplate.xlsx"));
XElement userprogress = XElement.Load(Server.MapPath(#"~/Content/Export.xml")).Element("cumulativeperformancereport");
int datarow = int.Parse(userprogress.Element("T").Attribute("row").Value.Trim());
int datacol = int.Parse(userprogress.Element("T").Attribute("col").Value.Trim());
IXLWorksheet WS = wb.Worksheet(1);
WS.Cell(datarow, datacol).Value = customer.Name;
datarow = int.Parse(userprogress.Element("X").Attribute("row").Value.Trim());
datacol = int.Parse(userprogress.Element("X").Attribute("col").Value.Trim());
WS.Cell(datarow, datacol).Value = X;
datarow = int.Parse(userprogress.Element("Y").Attribute("row").Value.Trim());
datacol = int.Parse(userprogress.Element("Y").Attribute("col").Value.Trim());
WS.Cell(datarow, datacol).Value = Y;
datarow = int.Parse(userprogress.Element("Z").Attribute("row").Value.Trim());
datacol = int.Parse(userprogress.Element("Z").Attribute("col").Value.Trim());
WS.Cell(datarow, datacol).Value = Z;
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment;filename=" + filename + "_Summary.xlsx");
using (MemoryStream MyMemoryStream = new MemoryStream())
{
wb.SaveAs(MyMemoryStream);
MyMemoryStream.WriteTo(Response.OutputStream);
Response.Flush();
Response.End();
}
return null;
}
catch (Exception ex)
{
return Redirect(TempData["PDFPrevUrl"].ToString());
}
}
Why am I getting this error?
"Requested JSON parse failed" indicating that AJAX call expects to get JSON data as returned value, but the controller action method returns other data type than JSON object.
By reviewing controller flow and omitting some non-relevant code, you will get this:
public ActionResult ExportReportToExcel(string X, string Y, string Z)
{
// other stuff
var customer = _authenticationService.CurrentCustomer;
if (customer == null)
return new LmsHttpUnauthorizedResult();
try
{
// other stuff
return null; // this returns null value instead of expected JSON
}
catch (Exception ex)
{
return Redirect(TempData["PDFPrevUrl"].ToString());
}
}
By default jQuery tries to infer dataType argument based on the MIME type of the response (xml, json, script or html, most recent default is JSON). Hence, you need to return a JSON object through these methods below:
// ContentResult
return Content("message_text", "application/json");
// JsonResult
return Json("message_text", JsonRequestBehavior.AllowGet);
If you want returning file by AJAX to download, you can use window.location or window.location.href to redirect:
$.ajax({
url: importUrl, // this should be refer to JsonResult action
data: {
X: "12",
Y: "12",
Z: "12"
},
success: function (data) {
// deal with data response here
window.location = downloadUrl; // redirect to FileResult action
},
error: function (jqXHR, exception) {
// other stuff
}
}
// example controller to return Excel binary file
public FileResult DownloadFile(string fileName)
{
// other stuff
byte[] content = TempData["something"] as byte[];
return File(content, "application/vnd.ms-excel", fileName);
}
NB: The explanations above are mostly trivial, your current implementation may differ from given examples.
Similar issues:
Download Excel file via AJAX MVC
jQuery returning "parsererror" for ajax request
Why use Backend for something like creating an excel file & then downloading it.... its overkill & downloading part is difficut
use something light weight like Javascript on the client side... it will create excel from XML & will download it using the download
property...
var data_type = 'data:application/vnd.ms-excel';
var table_div = document.getElementById('table_wrapper');
var table_html = table_div.outerHTML.replace(/ /g, '%20');
Here is Solution
It could be a server side error in sending the file.
Have you tried changing the response Content Type to application/vnd.ms-excel ?
I show you a minimal working example
// Server side
public ActionResult GimmeFile()
{
var bytes = System.IO.File.ReadAllBytes(#"path_to_your_file.xlsx");
return File(bytes, "application/vnd.ms-excel", "Myfile.xls");
}
Client side with your Ajax call
$.ajax({
method: 'POST',
url: '/Home/GimmeFile',
success: function (data) {
alert("S: " + data)
},
error: function (jqXHR, ex) {
console.log(ex)
}
})
Anyway, I don't know what you need to do with the excel file after ajax call,
but if your need is to save it to local then you should use the HTML5 < a download> instead

open file from ajax responce in mvc c#

I want to open file from Ajax response. here is the code. Here Ajax call response contain PDF file.
I want to open file in new tab of browser.here i am using mvc framework.
function ViewPDF(key){
$.ajax({
url: '#Url.Action("OpenDocument", "DocumentApproveUser")',
type: "POST",
data: { "key": key},
async: true,
cache: false,
success: function (data, status, xhr) {
alert(data);
window.open(data);
if (xhr.getResponseHeader("Forcefullylogin") == "true") {
var url = "/Login/Login";
window.location.href = url;
}
else {
}
},
error: function (error) {
$("#divLoading").hide();
if (error.getResponseHeader("Forcefullylogin") == true") {
var url = '#Url.Action("Login", "Login")';
window.location.href = url;
}
else {
alert('Something went wrong in system.Please try again later!or contact to system administrator.');
}
}
});
}
Server Code :
see below is code of my controller. this code return pdf file as ajax response.
I want to open that response in my browser.
[HttpPost]
public ActionResult OpenDocument(string key)
{
try
{
int Id = 0;
try
{
byte[] data = Convert.FromBase64String(key);
string decodedString = System.Text.Encoding.UTF8.GetString(data);
if (!(String.IsNullOrEmpty(decodedString)))
Id = Convert.ToInt32(decodedString);
}
catch (Exception ex)
{
ViewBag.ErrorName = "An error occured while opening document.";
base.ErrorLogger.Error("***OpenDocument***", ex);
return null;
}
DocumentApproveViewModel vm = new DocumentApproveViewModel();
vm.DocumentsApprovalModel = DocumentApproveViewModel.GetDocTransactionModelList(_repo.GetAll());
DocumentApprovalModel lst;
lst = (from x in vm.DocumentsApprovalModel where x.Id.Equals(Id) select x).FirstOrDefault();
base.Logger.InfoFormat("User : '{0}' going to access pdf document at {1} ", SessionFactory.CurrentUser.Name, System.DateTime.Now);
/////////////////////////////////////////////////////////////////////
ICollection<PasswordManagementViewModel> passwordList = null;
PasswordManagementViewModel password = null;
passwordList = PasswordManagementViewModel.GetSystemEncryptionKeyList(_encryption.GetAll());
password = passwordList.OrderByDescending(x => x.CreatedDateTime).FirstOrDefault();
string decryptPassword = Base64EncodeDecode.Decrypt(password.EncryptionKey, true);
/////////////////////////////////////////////////////////////////////
// Inhariting Logic from PDFSharpUtil Class.
byte[] PdfFileByte = _docSecurity.OpenPdfFile(lst.File, decryptPassword, SessionFactory.CurrentUser.EncryptionKey, SessionFactory.CurrentUser.Name, lst.DocumentTransactionName, false, SessionFactory.PdfViewCount);
/// Added logic for adding data into Document History ///
DocumentHistory objDocumentHistory = new DocumentHistory();
objDocumentHistory.SentTo = null;
objDocumentHistory.Timestamp = DateTime.UtcNow;
objDocumentHistory.ActionPerformedBy = SessionFactory.CurrentUser.Id;
objDocumentHistory.Action = EDocumentAction.View;
objDocumentHistory.DocumentId = Id;
_docHistoryRepo.Add(objDocumentHistory);
//Increment view count not to ask password from second attempt to open PDF file
SessionFactory.PdfViewCount++;
return File(PdfFileByte, "application/pdf");
}
catch (Exception ex)
{
ViewBag.ErrorName = "An error occured while opening Document";
base.ErrorLogger.Error("***OpenDocument :: DocumentView***", ex);
}
return null;
}
Do not try to use ajax to download file. Just open the url in a new browser tab. Based on your browser settings, it will either open in the tab or ask whether you want to save it.
You can set the new url to window.location.href
function ViewPDF(key)
{
var url= '#Url.Action("OpenDocument", "DocumentApproveUser")?key='+key,
window.location.href = url;
}
Based on the browser setting, the above 2 approaches will either ask user whether he wishes to download or open the file or simply download/open the file. If you prefer to show the file content directly in the browser, you may send a filestream to the browser.
Here is a quick example, which reads the pdf from a disk in the Contents/Downloads directory in app root and return the file stream.
public ActionResult View(int id)
{
var pathToTheFile=Server.MapPath("~/Content/Downloads/sampleFile.pdf");
var fileStream = new FileStream(pathToTheFile,
FileMode.Open,
FileAccess.Read
);
return new FileStreamResult(fileStream, "application/pdf");
}

When invoked with a jQuery $.ajax, what to return from the Action Method if things go ok?

Here's my code:
[HttpPost]
public ActionResult VoteChampionStrongAgainst(string championStrong, string againstChampion)
{
int champStrongId = int.Parse(championStrong);
int againstChampId = int.Parse(againstChampion);
string ip = System.Web.HttpContext.Current.Request.UserHostAddress;
using (EfCounterPickRepository counterPickRepository = new EfCounterPickRepository())
{
var existingCounterPick = counterPickRepository.FindAll()
.SingleOrDefault(x => x.ChampionStrong == champStrongId && x.AgainstChampion == againstChampId);
//Does this counterpick combination already exist?
if (existingCounterPick != null)
{
//Has this user already voted?
var existingVote = counterPickRepository.FindVoteForUser(ip, existingCounterPick.CounterPickVoteId);
//He hasn't voted, add his vote history.
if (existingVote == null)
{
StrongCounterHistory history = new StrongCounterHistory();
history.IPAddress = ip;
history.VoteType = true;
history.StrongCounterPickVoteId = existingCounterPick.CounterPickVoteId;
counterPickRepository.AddStrongPickHistory(history);
counterPickRepository.SaveChanges();
//Add a total vote the pick.
existingCounterPick.TotalVotes++;
counterPickRepository.SaveChanges();
}
else
{
//Will use this to display an error message.
//How to return an "error" that jquery understands?
}
}
else //This combination doesn't exist. Create it.
{
//Create it....
StrongCounterPickVote newCounterPick = new StrongCounterPickVote();
newCounterPick.ChampionStrong = champStrongId;
newCounterPick.AgainstChampion = againstChampId;
newCounterPick.TotalVotes = 1;
counterPickRepository.CreateNewCounterPick(newCounterPick);
counterPickRepository.SaveChanges();
//Assign a vote history for that user.
StrongCounterHistory history = new StrongCounterHistory();
history.IPAddress = ip;
history.VoteType = true;
history.StrongCounterPickVoteId = newCounterPick.CounterPickVoteId;
counterPickRepository.AddStrongPickHistory(history);
counterPickRepository.SaveChanges();
}
return View();
}
}
Here's my jQuery code:
$(".pick .data .actions .btn-success").click(function () {
var champStrongId = $(this).data("champstrongid");
var againstChampId = $(this).data("againstchampid");
$.ajax({
type: 'POST',
url: "/Counterpicks/VoteChampionStrongAgainst",
data: { championStrong: champStrongId, againstChampion: againstChampId },
success: function () {
alert("Great success!");
},
error: function (e) {
alert("Something bad happened!");
console.log(e);
}
});
});
What do I need to return from my ActionMethod so the code execution enters success: if things went OK, or error: if things go wrong (for example, he already voted on this particular counter pick?
Servlet should answer a "200 OK" HTTP response.
Don't know about your 'View' api, but HttpServletResponse.setStatus(200) would do on the Java side. Don't forget, you can request the AJAX url manually in your browser to see what it is returning..
Here's some things I'd do...
public JsonResult VoteChampionStrongAgainst(string championStrong, string againstChampion) {
var success = true;
// Do all of your data stuff
return Json(new { success = success, error = 'Some error message'});
}
The JsonResult is a special ActionResult for returning Json. It automatically sets the correct headers for the browser. The Json() will use ASP.NET's built in serializer to serialize an anonymous object to return to the client.
Then with your jQuery code...
$.ajax({
type: 'POST',
url: "/Counterpicks/VoteChampionStrongAgainst",
data: { championStrong: champStrongId, againstChampion: againstChampId },
success: function (json) {
if (json.success) {
alert("Great success!");
}
else if(json.error && json.error.length) {
alert(json.error);
}
},
// This error is only for responses with codes other than a
// 200 back from the server.
error: function (e) {
alert("Something bad happened!");
console.log(e);
}
});
In order to have the error fire you'd have to return a different response code with Response.StatusCode = (int)HttpStatusCode.BadRequest;
You can return 500 internal server error if there are any errors on your server something like
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
Response.ContentType = "text/plain";
return Json(new { "internal error message"});

Categories