Get FileSize in Server is always zero - asp.net

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);
}
}
//............
}

Related

ASP.NET Deployment issue saving image to database

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.

Unable to dowload file using generic handler

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

Reading CSV File in hosted application

I have created an MVC ASP.Net application and hosted in within IIS. Part of my app allows for users to upload a csv file. The data then needs to be read out of the csv and into an object to be used elsewhere.
The problem I have is when hosted in IIS the file can not be read. Here is my code:
using (StreamReader CsvReader = new StreamReader(filePath))
{
MessageHandler.NewNote("Opened CSV Reader");
string inputLine = "";
int lineNumber = 0;
while ((inputLine = CsvReader.ReadLine()) != null && !string.IsNullOrEmpty(inputLine))
{
//Do something here
}
}
Can someone please advise how I get this working. The filepath is generated using the following upload form:
<div id="UploadForm">
<% using (Html.BeginForm("FileUpload", "ImportExport", Model,
FormMethod.Post, new { enctype = "multipart/form-data" }))
{%>
<input name="uploadFile" type="file" accept=".csv" style="width:70%;" />
<input type="submit" value="Upload File" />
<%} %>
</div>
The filePath is coming from the client, there should be no file existing on the server at the given file path.
You need to read the data from the Stream coming from the upload form instead of the file path.
Please refer to the following link
http://msdn.microsoft.com/en-us/library/system.web.httprequest.inputstream.aspx

asp.net fileupload control time-out on big files

Getting ERR_CONNECTION_RESET after more or less 2 minutes of uploading a rather big file (90 MB) through asp.net fileupload control.
Testing this on a shared host environment so I don't know exactly what policies are enforced on me.
web.config settings are sufficient I think:
<httpRuntime requestValidationMode="2.0" maxRequestLength="1000000" executionTimeout="45000" />
Should I be looking at other async file-upload controls? Am I missing a web.config setting? Is the upload control simply not sufficient for large files on slow connections?
There can be a number of reasons why the connection is reset and upping the max request length works to a point but you are right about looking into async file uploaders. The most important part is using one which "chunks" the files into smaller pieces and so avoids request limits etc. I have had the best experience with plupload:
http://www.plupload.com/
Here is some code for receiving the files (this is MVC but you can refactor to use a handler in .NET classic):
[HttpPost]
public ActionResult UploadImage(int? chunk, int? chunks, string name)
{
var fileData = Request.Files[0];
if (fileData != null && fileData.ContentLength > 0)
{
var path = GetTempImagePath(name);
fileSystem.EnsureDirectoryExistsForFile(path);
// Create or append the current chunk of file.
using (var fs = new FileStream(path, chunk == 0 ? FileMode.Create : FileMode.Append))
{
var buffer = new byte[fileData.InputStream.Length];
fileData.InputStream.Read(buffer, 0, buffer.Length);
fs.Write(buffer, 0, buffer.Length);
}
}
return Content("Chunk uploaded", "text/plain");
}

validate asp fileupload control client side

i have a asp fileupload control on my page. how to validate the selected file on client side.
validation rules:
1. file must be jpeg,png,bmp or gif.
2. file size must be within 25 kb and 2 mb.
please help.
thanks.
I Have Tried The Following Code to validate the extension
<asp:FileUpload ID="FileUpload2" runat="server"/>
<asp:CustomValidator ID="CustomValidator1" runat="server" ClientValidationFunction="ValidateFileUpload" ErrorMessage="Invalid file type. Only .gif, .jpg, .png, .bmp and .jpeg are allowed." ControlToValidate="FileUpload2" ValidationGroup="update"> </asp:CustomValidator>
<script language="javascript" type="text/javascript">
function ValidateFileUpload(Source, args) {
var fuData = document.getElementById('<%= fuData.ClientID %>');
var FileUploadPath = fuData.value;
if (FileUploadPath == '') {
// There is no file selected
args.IsValid = false;
}
else {
var Extension = FileUploadPath.substring(FileUploadPath.lastIndexOf('.') + 1).toLowerCase();
if (Extension == "jpg" || Extension == "jpeg" || Extension == "png" || Extension == "gif" || Extension == "bmp") {
args.IsValid = true; // Valid file type
}
else {
args.IsValid = false; // Not valid file type
}
}
}
</script>
You cannot determine the size of the file selected in the file input element via client side script. In order to determine the size of the file, one must have read access to the file. As you may imagine, allowing JavaScript to read files on your computer would be a "really bad idea."™
I often see this type of question, and believe that there is some confusion about what the file input element actually does. When the user selects a file, the file bytes aren't "loaded" into this element such that they are available for reading. Rather, the input specifies a reference to the file location so that the browser knows - when the form is posted - to encode the file and send it with the POST. This process is internal to the browser, and isn't exposed to the client in a manner that it can be leveraged by script.
If you need to do file size verification, you should do it on the server where you have access to the actual file bytes. If you are concerned with people "flooding" your site with very large files, you can specify the maximum allowable POST size by configuring your IIS instance.
You can try out ajax control tool kit. It has its own control for file upload. Its much more cool
In most browsers used nowadays, you can do client-side validation on file size:
https://stackoverflow.com/a/1832497/2705769

Resources