I am using a generic handler to download csv/excel files. It was working fine until yesterday. Today suddenly it stopped working on deployment on IIS 7.5 (though he same code works well in visual studio debugging mode). Here is my code:
ASPX: This is a content page
<input type="button" class="btn-primary" id="btnDownload" title="Download" value="Download" onclick='return downloadReport(this);' data-toggle="modal" data-target="#myModal" navurl='<%: ResolveUrl("~/Handlers/DownloadData.ashx") %>' />
JS:
function downloadReport(btn) {
//I am using a kendoUI combo box and kendo js + also using bootstrap for design & modal popups & also i have applied bundling to kendo & bootstrap files. They seem to be working fine without any conflicts as all their api's are working.
var $mod = $("#masterModal");
$mod.modal('show');
//window.location = "Handlers/DownloadData.ashx?rtp=" + combobox.val();
window.location.href = $(btn).attr("navurl") + "?rtp=" + combobox.val();
setTimeout(function () {
$mod.modal("hide");
}, 2000);
return false;
}
Master Page:
I am including the js file containing the above method just before end of body tag.
<script src='<%: ResolveUrl("~/Scripts/DataUploader.js") %>'></script>
</body>
</html>
Handler: In handler Process Request Method
HttpResponse response = this._context.Response;
HRReportData hrData = new HRReportData(ConfigMaster.DbProvider, ConfigMaster.ConnectionString, ConfigMaster.DBSchemaName);
ReportDataManager rdm = null;
ExcelPackage xlPackage = null;
try
{
rdm = new ReportDataManager();
DataSet ds = rdm.GetReportData(hrData, report_Type);
if (ds != null && ds.Tables.Count > 0)
{
if (ds.Tables[0].Rows.Count > 0)
{
xlPackage = new ExcelPackage();
ExcelWorksheet worksheet = xlPackage.Workbook.Worksheets.Add(report_Type.ToString());
worksheet.Cells["A1"].LoadFromDataTable(ds.Tables[0], true, TableStyles.Light1);
response.ClearHeaders();
response.ClearContent();
response.Clear();
response.ContentType = "application/octet-stream";
response.AppendHeader("content-disposition", "attachment; filename=" + report_Type.ToString() + ".xlsx");
xlPackage.SaveAs(response.OutputStream);
response.Flush();
//response.Close();
//response.End();
}
}
}
catch (Exception ex)
{
//LogError.MethodLevelError(Convert.ToString(Session["Username"]), ex);
if (!(ex is System.Threading.ThreadAbortException))
{
//Other error handling code here
}
}
finally
{
if (xlPackage != null)
{
xlPackage.Dispose();
xlPackage.Dispose();
}
}
Bundle config:
bundles.Add(new ScriptBundle("~/Kendo/kendo").Include(
"~/Scripts/jquery-1.11.3.min.js",
"~/Kendo/js/kendo.all.min.js"
// "~/Scripts/DataUploader.js"
));
bundles.Add(new ScriptBundle("~/bootstrap/bootstrap").Include(
"~/bootstrap/js/holder.js",
"~/bootstrap/js/ie10-viewport-bug-workaround.js",
"~/bootstrap/js/ie-emulation-modes-warning.js",
"~/bootstrap/js/bootstrap.min.js"
));
All above code works well in debugging mode and was working well in deployment mode as well. Don't know what has changed that it suddenly stopped working and I am unable to find out any reasons :(
Behaviour on deployment: Instead of staying on same page and downloading file it navigates to Handler and a blank screen is displayed. No file is downloaded.
Behaviour in debuuging mode OR when run using vs2012 express: It stays on same page and downloads the file as expected.
Somebody please help me on this.
All the above code works 100% fine. There is absolutely no mistake in it. I found the reason that it was not working was that the web.config in the published folder was not updated/overwritten by someone and since the work is in beginning phase I have not yet added support for Exception handling/error logging hence the handler error (due to accessing keys used in config files) were not noted & in debug/dev environment the config file was correct hence the error never occurred.
Anyways the code can be useful to anyone who wish to download the files using generic handler. However kindly note that above code is in basic stage and needs to be updated for:
1) user request validation -parameter validation
2) user session validation
3) security implementations
4) exception handling
5) logging
Related
I am having an unusual issue when I deploy my code from VS2015 to IIS. In VS when I run the web code, either as debug or release, the image I select and load then convert to base64 is converted to a byte array and saved to the database without any problems. However, when I deploy to the web server the code fails to work and the image is never updated. I am not getting any error information. As long as I run it from VS it all works. Is there something on the IIS server that needs to be configured? Any help or comments will be greatly appreciated.
HTML CODE
<form class="input-group" id="img2b64">
<input id="inputFileToLoad" name="files" type="file"
onchange="encodeImageFileAsURL();" />
</form>
<!-- is used to display b64 code and hold the b64 for ajax call to controller -->
<textarea id="b64" class="form-control"></textarea>
JQUERY CODE
function encodeImageFileAsURL(cb) {
return function () {
var file = this.files[0];
var reader = new FileReader();
reader.onloadend = function () {
cb(reader.result);
}
reader.readAsDataURL(file);
}
}
$('#inputFileToLoad').change(encodeImageFileAsURL(function (base64Img) {
$('#act_Photo').attr('src', base64Img);
$('#b64').val(base64Img);
}));
IN THE CONTROLLER CODE
// model.ImageFile is the base64 string
if (!string.IsNullOrEmpty(model.ImageFile))
{
// strip out base64 header
int pos = model.ImageFile.LastIndexOf(',') + 1;
string data = model.ImageFile.Substring(pos);
// get byte array of base64 image
byte[] bytes = Convert.FromBase64String(data);
// convert and save as byte array to DB
var acctImg = new WebImage(bytes).Resize(220, 200, false, true);
// aRec.Photo is in DB record
aRec.Photo = acctImg.GetBytes();
}
Seems like all is well. I restarted the site in IIS. Seems to have been a caching issue causing all the grief. Sometimes I just hate caching.
I'm doing a file upload function in my ASP.NET MVC web system. The file upload function is working, so the next step I do is to validate the file size.
Please see the attached codes
Partial form GEDocumentInfoForm.ascx:
<input type="file" name = "Files" class = "multi" id = "myFile"/>
Main Form Create.aspx
<asp:Content ID="Content4" ContentPlaceHolderID="ContentCph" runat="server">
<script type="text/javascript">
$(document).on('click', '#btnCreateDocument', function () {
$('#btnCreateDocument').attr('disabled', 'disabled'); // prevent resubmit
Checksize()
document.body.style.cursor = 'wait';
});
function Checksize() {
alert(document.getElementById("myFile").tagName);
var k = document.getElementById("myFile").files[0].size;
alert("file size in KB " + k / 1024);
}
</script>
<% Using (Html.BeginForm("Create", "GEDocument", FormMethod.Post, New With {.enctype = "multipart/form-data", .id = "form"}))%>
<input type="submit" name="Save" value="<%= Detail.Save %>" id="btnCreateDocument" />
<div id="Div1">
<% Html.RenderPartial("GEDocumentInfoForm", Model) %>
</div>
<% End Using%>
</asp:Content>
The file size validation (not more than 2048B) was working fine in localhost. So, after that I published it and deploy in my development server. When I run it, somehow it can pass through my validation. After check in debug mode of web browser, it returns 0 for the file size.
var k = document.getElementById("myFile").files[0].size;
I've tried to search solutions to see if anyone hit the similar issue before. End up, I have to use server validation in my Controller.
Dim fileZs As HttpFileCollectionBase = Request.Files
For z As Integer = 0 To (fileZs.Count - 1)
Dim file As HttpPostedFileBase = fileZs(z)
If Not IsNothing(file) AndAlso (file.ContentLength / 1024) > 2048 Then
errors.Concat(New RuleViolation(Message.EmailMustHaveValue, "SelectedToEmails"))
End If
Next
Web.Config (added the configuration so that it can pass ActionFilterAttribute in Controller due to Maximum request too long)
<system.web>
<httpRuntime maxRequestLength="1048576" />
</system.web>
I think that server validation is not user-friendly. I wish there are some answers from the experts if anyone faced the issue like me in doing Client validation to check file size in file upload feature.
Why is it always return 0 after published to development server?
Is it related to server security? As I know we are getting FileName as C:\fakePath\myFileName. Could it be some relationship over here?
here a full working example, note Request.Files is an array, if you are sending only one file you need to pick first item.
the right property to check is ContentLength
also check if in your folder the uploaded file exists after upload, because you need to have write permission in the folder where you are uploading
[HttpPost]
public ActionResult Upload()
{
if (Request.Files.Count > 0)
{
var file = Request.Files[0];
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/Images/"), fileName);
file.SaveAs(path);
}
}
//............
}
I'm using EAFlashUpload component with ASP.NET 4.0 on my site to allow for multiple file uploads (select multiple files at a time).
The component works great and with no issues with IE (7, 8, 9), but with Firefox or Chrome, it gives an "unknown http error" after a file is uploaded (when it is trying to do postback to the server, I think).
I'm running this under IIS7 on Windows 2008 Server R2, but I don't think the version of IIS or Windows is the significant factor.
This is the client side Javascript to handle the component:
<script type="text/javascript">
var params = { BGcolor: "#ffffff", wmode: "window" };
var attributes = { id: "EAFlashUpload", name: "EAFlashUpload" };
var flashvars = new Object();
var uploadUrl = "Pages/SendAdvanced.aspx";
//if (!document.all) {
// uploadUrl = "../" + uploadUrl;
//}
flashvars["uploader.uploadUrl"] = uploadUrl;
flashvars["viewFile"] = "EAFUpload/TableView.swf";
flashvars["view.removeButton.visible"] = "false";
flashvars["view.clearButton.visible"] = "false";
flashvars["queue.filesCountLimit"] = "10";
flashvars["queue.fileSizeLimit"] = "2147483648"; // 2 gigabytes = 2147483648 bytes
swfobject.embedSWF("EAFUpload/EAFUpload.swf", "EAFlashUpload_holder", "650", "380", "10.0.0", "EAFUpload/expressInstall.swf", flashvars, params, attributes);
function EAFlashUpload_onMovieLoad(errors) { if (errors != "") alert(errors); }
</script>
EDIT:
I discovered after further testing that the Flash component is throwing error #2038, which is a generic catchall error for "cannot connect to the server". Not sure why this is an issue with Chrome and FF, but this warrants additional investigation...
I found the answer, and it is absolutely NOT what I was expecting.
This line of code was the issue:
var uploadUrl = "Pages/SendAdvanced.aspx";
That line is a relative path, set in client side Javascript and used by the Flash component to know where to post the content.
When I changed it to this, it worked:
var uploadUrl = "http://www.mysite.com/Pages/SendAdvanced.aspx";
What I would love for someone to tell me is WHY the first line of code EVER works? Why does it work in Internet Explorer? Is there something special it is able to do to track relative paths, that the other browsers (and the Mac) won't do?
I found this answer when I was experiencing similar issues with the flash uploader (the uploads would fail before even connecting to the server). Using the following example code:
var uploadUrl = location.href;
if (!document.all) {
uploadUrl = "../" + uploadUrl;
}
//alert(uploadUrl);
var flashvars = new Object();
flashvars["uploader.uploadUrl"] = uploadUrl;
...
Turns out the problem only occurred with URLs that had a & and/or # in them (the flash object was receiving these and not knowing what to do with them because they were not encoded). There are more characters than these to worry about, however, in my case, this ended up solving the issue
I simply replaced the ampersands with the encoded version that flash was expecting, and removed the hash pound and everything following it (because it is useless from a server's perspective).
uploadUrl = uploadUrl.replace(/\&/g, '%26');
uploadUrl = uploadUrl.replace(/#.*/g, '');
I have and ASP.NET 3.5 page where I need to debug some JavaScript code.
function checkAll(isChecked)
{
debugger;
var dataGridElements = document.getElementById('" + DataGridSearchResults.ClientID + #"').getElementsByTagName('input');
for (var i = 0; i < dataGridElements.length; i++)
{
var e = dataGridElements[i];
if ((e.type=='checkbox') && (!e.disabled))
{
e.checked = isChecked;
}
}
}
As you can see, I added a debugger statement in the first line. For some reason, when i execute the page, the javascript (which is in a string variable and registered with Page.ClientScript.RegisterClientScript statement) is in my source code twice! The second block doesn't have my debugger statement either! I checked the project, this block of Javascript is only listed once in the project.
Any ideas? (the client i am running on is IE8 if that makes a difference)
Figured it out. The base page that this control was on (the javascript was in an ASCX file) was a page that had a tab strip on it. One of the other tabs had the code copy and pasted with the exact same signature, just a grid name difference. Once i changed the signature on my set of code, it worked fine.
I have a site that runs on IIS7 ASP.NET 3.5
I implemented a http-handler that serverves pdf.
If I request a pdf-document (www.mysite.com/mypdf.ashx?id=doc1) in Firefox 3.0 I get the result in the browser.
I now have an iframe on my page. The src - attribute is set to www.mysite.com/mypdf.ashx?id=doc1.
The document is displayed in IE7 but in Firefox I only get scrambled text.
Is this posssible in Firefox?
I found this post PDF streaming in IFRAME not working in Firefox
Anybody tried this solution with modrewrite? The post is a couple of years old and there was no modrewrite for IIS7 then.
I do that in asp.net mvc and it works fine on IE6, IE7 and Firefox 3.5.3
Here is my code :
Html code :
<div id="ProductDetailsModal">
<iframe src="<%= Url.Content("~/GetPdf.axd?id=" + ViewData["ProductId"] + "&type=" + ViewData["ContentType"]) %>" width="100%" height="98%"></iframe>
</div>
And here the HttpHandler Code :
public void ProcessRequest(HttpContext context)
{
if (!String.IsNullOrEmpty(context.Request.Params["Id"]) && !String.IsNullOrEmpty(context.Request.Params["Type"]))
{
IProductBusiness productBusiness = new ProductBusiness();
var username = context.Session["Username"] as String;
var password = context.Session["Password"] as String;
var id = context.Request.Params["Id"].ToInt();
var type = context.Request.Params["Type"];
if (id != 0 && !String.IsNullOrEmpty(type))
{
var pc = productBusiness.GetProductContent(username, password, id, type, string.Empty);
if (!String.IsNullOrEmpty(pc.Name) && !String.IsNullOrEmpty(pc.Extension) && pc.Extension.ToLower() == "pdf")
{
var len = pc.File.Length;
byte[] output = Convert.FromBase64String(pc.File);
context.Response.Clear();
context.Response.ContentType = "application/pdf";
context.Response.AddHeader("Content-Disposition", String.Format("FileName=\"{0}\"", pc.Name));
context.Response.AddHeader("content-length", output.Length.ToString());
context.Response.Cache.SetCacheability(HttpCacheability.Private);
context.Response.Expires = -1;
context.Response.Buffer = true;
context.Response.BinaryWrite(output);
context.Response.End();
}
else
{
context.Response.Write("Erreur lors du chargement du fichier.");
}
context.Response.Clear();
}
}
}
Hope this helps.
There was no mod_rewrite for IIS 6 either. It is an Apache only process. There are alternatives like IIS 7 Rewriter Module or Managed Fusion URL Rewriter.
Are you setting the ContentType for the Response? IE is pretty good at guessing what a document is; firefox relies on being told.
You'll want to set the ContentType to "application/pdf"
Serving PDFs with an http handler is tricky business. There are so many different ways of loading and reading a pdf. Different versions of Adobe Acrobat Reader behave different as well.
Sometimes it tries to be clever and see if it can use partial requests (206). So you can see the first page before its finished downloading the entire document. You probably want to also set the correct cache headers, as that will save you a lot of bandwidth.
I have been using this http handler to successfully serve pdfs without any problems. It takes cares of most of the hassles for you.
http://code.google.com/p/talifun-web/wiki/StaticFileHandler