All.
(Using CodeFile for pages published to a webserver
Removing Namespace, as I get errors after adding CodeFile)
I created a video for everyone to see the issue live. This is creating a new web project and then demonstrating the issue.
Please click here to view the video.
I've run into a strange issue that I'm hoping someone will be able to assist with.
Below are identical codes, with only the CodeBehind and CodeFile, and the namespace removal changed.
The issue is this.
The below code will upload a single image that is renamed with the date.
<%# Page Language="vb" AutoEventWireup="false" CodeBehind="Test.aspx.vb" Inherits="ImageServer.Test" %>
This code will upload duplicates of the image renamed with a date.
<%# Page Language="vb" AutoEventWireup="false" CodeFile="Test.aspx.vb" Inherits="Test" %>
If you upload the file with its default name, it will only upload ONE file, regardless of the Inherits property.
So, this will upload single files either way.
Dim fileName As String = IO.Path.GetFileName(postedFile.FileName)
postedFile.SaveAs(Server.MapPath("~/Uploads/") & fileName)
This code will upload duplicates with CodeFile and no Namespace.
Dim getYear As String = (((((now.ToString("hh") & "") + now.ToString("mm") & "") + now.ToString("ss") & "") + now.ToString("mm") & "") + now.ToString("dd") & "") + now.ToString("yyyy") + now.ToString("fff") + ""
Dim testName As String = getYear + ext
postedFile.SaveAs(Server.MapPath("~/Uploads/") & testName)
Any idea what is going on here?
Text.aspx (Uncomment each Page header to test out code)
<%'# Page Language="vb" AutoEventWireup="false" CodeBehind="Test.aspx.vb" Inherits="ImageServer.Test" %> <!--Singles-->
<%# Page Language="vb" AutoEventWireup="false" CodeFile="Test.aspx.vb" Inherits="Test"%> <!--Duplicates-->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
$(function () {
$("[id*=fuUpload]").change(function () {
if (typeof (FileReader) !="undefined") {
var dvPreview = $("#dvPreview");
dvPreview.html("");
var regex = /^([a-zA-Z0-9\s_\\.\-:])+(.jpg|.jpeg|.gif|.png|.bmp)$/;
$($(this)[0].files).each(function () {
var file = $(this);
if (regex.test(file[0].name.toLowerCase())) {
var reader =new FileReader();
reader.onload = function (e) {
var img = $("<img />");
img.attr("style","height:100px;width: 100px");
img.attr("src", e.target.result);
dvPreview.append(img);
}
reader.readAsDataURL(file[0]);
}else {
alert(file[0].name +" is not a valid image file.");
dvPreview.html("");
return false;
}
});
}else {
alert("This browser does not support HTML5 FileReader.");
}
});
});
</script>
</head>
<body>
<form runat="server">
<asp:FileUpload ID="fuUpload" runat="server" multiple="multiple" />
<asp:Button ID="btnUpload" Text="Upload" runat="server" OnClick="Upload" />
<hr />
<div id="dvPreview">
</div>
</form>
</body>
</html>
Text.aspx.vb
Place the following code under your upload button.
For i As Integer = 0 To Request.Files.Count - 1
Dim postedFile As HttpPostedFile = Request.Files(i)
Dim ext As String = System.IO.Path.GetExtension(postedFile.FileName)
Dim now As DateTime = DateTime.Now
Dim getYear As String = (((((now.ToString("hh") & "") + now.ToString("mm") & "") + now.ToString("ss") & "") + now.ToString("mm") & "") + now.ToString("dd") & "") + now.ToString("yyyy") + now.ToString("fff") + ""
Dim testName As String = getYear + ext
If postedFile.ContentLength > 0 Then
Dim fileName As String = IO.Path.GetFileName(postedFile.FileName)
postedFile.SaveAs(Server.MapPath("~/Uploads/") & fileName) ' Single file either way
'postedFile.SaveAs(Server.MapPath("~/Uploads/") & testName) ' Duplicate file CodeFile and no Namespace
End If
Next
==Update==
OK, so it was the
Dim getYear As String
The last part of it was causing the issue.
now.ToString("fff")
Also happens with a GUID as well.
Guid.NewGuid().ToString()
I even tried a random file name for kicks, and it duplicated the files.
Path.GetRandomFileName()
Though it had nothing to do with the CodeFile, there is still the scratching of the head part of WHY does it duplicate the files with the milliseconds added to it?
If you use the example code I provided and test it, you will see that the Random getYear will work with CodeBehind but not with CodeFile.
So, something is going on with CodeFile that causes this bizarre behavior.
Thanks for any assistance on this issue.
Wayne
First of all, I VERY but VERY much doubt changing the use of codepage, and code file will effect the outcome here.
the issue is really quite simple:
You allow a user to up-load mutliple files. But, your 2nd code snip does NOT use the file name, and in fact uses a file name based on the time stamp.
You do realize that if user selects 5 files, then in 99% of cases, the file name (based just on time) will OFTEN and NEAR ALWAYS result in say all 5 files being given the same name.
Remember, when a user selects say 5 files, and then hits submit. The files are not really up-loaded separate, but ALL WILL be part of the submit button (the post-back).
So, AFTER ALL the files are up-loaded, then your code loop runs. and it is in most cases going to run VERY fast - less then 1 second. As a result, all 5 files will be given the same file name.
It is possible that you using a computer found in a dumpster, and it runs slow, so slow that somehow the time to run that loop to save (write) each file takes more then one second.
And remember, you as a general rule would not mess with using codefile vs codebehind.
But, without question, using codebehind probably will at least the first time run MUCH faster. If you use codefile, then the source code is saved and is part of the web page, and is compiled by IIS (internet server).
However, if you use cdebehind, then the code is pre-compiled. This thus suggests perhaps that on first page load when using codefile, the code runs VERY slow the first time - it has to be compiled on the fly, and this might buy you some extra time, enough that the additional file names increased by one second.
However, with codebehind, then this is NOT likly to occur (in other words, the code will run faster, and ALMOST FOR SURE, that if you up-loaded 5 files, they ALL WILL get the same name if you base the file name on JUST time, and don't for example add say the file name or some other part to distinguish the file names your code generates.
Obviously, your first code snip always works, since you using the file name from the up-load.
The 2nd example? If the computer runs fast, then you almost for sure wind up over writing the set of files with the same time - since that code will run rather fast.
And you should not mess with the codebehind vs codefile settings.
codebehind:
This assumes you are using an asp.net web application. This means that you compile the web site and code BEFORE deployment, and your source code files (code behind) are NOT up-loaded to the server.
CodeFile
This assumes you are NOT using a sp.net application, but are using what is called a asp.net web site. This means that you can deploy one simple page, and not have to re-deploy the whole site (like you do with web applications). This certainly can be easier to maintain a web site, but a web site application also has some advantages, and this is in the area of refencing other code libraries etc. You also tend to require MORE control over the web server, and a web site can easy be published as as sub site, where as in most cases the asp.net web applcation is going to be the root of your site, and the configuration applies to the whole server - not several sub sites.
Anyway, wondering off topic here.
It looks like using the time stamp for the file name is a bad idea, and that loop will surely OFTEN run in less then one second, and that will result in all files having the same file name. You either need to introduce the part of the file name, or even consider a file.Exists(strFile), and maybe then increment the time by 5 seconds or some such if the file already exists (for the file name to be used).
As noted, if you are using codefile, and it seemed to work, it likly due to the code running oh so much slower. However, if you run that page, or do the test multiple times, that page will when loaded, and compiled by IIS will start to run faster, and you then start to see the same file names generated based on using time.
For code behind, then it is pre-compiled, and thus the chance of the time changing from one file save to the next will increase, and once again, file based on time stamp will no doubt start to over write each other in that loop.
Edit: two examples web site, and web site application
Ok, so lets create two projects. We use the time stamp example in both.
so, lets create a web site (not a web site application).
So, this one:
so, to be 100% clear, we do NOT open this as a project.
Thus we ALWAYS will open this project with open web site option from VS.
so, to open + develop, we use open web site, and NOT open application.
Eg this:
And then this to open:
And of course, it ALWAYS dangerous to mess around with the code file and page settings (that first header in the markup).
So, we add a new page - MyTest (and we MOST certainly let VS create this page for us, right????).
So, we now cut + paste in your markup:
And we now have this:
<%# Page Language="VB" AutoEventWireup="false" CodeFile="MyTest.aspx.vb" Inherits="MyTest" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
$(function () {
$("[id*=fuUpload]").change(function () {
if (typeof (FileReader) !="undefined") {
var dvPreview = $("#dvPreview");
dvPreview.html("");
var regex = /^([a-zA-Z0-9\s_\\.\-:])+(.jpg|.jpeg|.gif|.png|.bmp)$/;
$($(this)[0].files).each(function () {
var file = $(this);
if (regex.test(file[0].name.toLowerCase())) {
var reader =new FileReader();
reader.onload = function (e) {
var img = $("<img />");
img.attr("style","height:100px;width: 100px");
img.attr("src", e.target.result);
dvPreview.append(img);
}
reader.readAsDataURL(file[0]);
}else {
alert(file[0].name +" is not a valid image file.");
dvPreview.html("");
return false;
}
});
}else {
alert("This browser does not support HTML5 FileReader.");
}
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:FileUpload ID="fuUpload" runat="server" multiple="multiple" />
<asp:Button ID="btnUpload" Text="Upload" runat="server" OnClick="Upload" />
<hr />
<div id="dvPreview">
</div>
</div>
</form>
</body>
</html>
So, I did not mess with the page directive, I pasted in your bits in parts.
And for code behind, we have this:
Partial Class MyTest
Inherits System.Web.UI.Page
Protected Sub Upload(sender As Object, e As EventArgs)
For i As Integer = 0 To Request.Files.Count - 1
Dim postedFile As HttpPostedFile = Request.Files(i)
Dim ext As String = System.IO.Path.GetExtension(postedFile.FileName)
Dim now As DateTime = DateTime.Now
Dim getYear As String = (((((now.ToString("hh") & "") + now.ToString("mm") & "") + now.ToString("ss") & "") + now.ToString("mm") & "") + now.ToString("dd") & "") + now.ToString("yyyy") + now.ToString("fff") + ""
Dim testName As String = getYear + ext
If postedFile.ContentLength > 0 Then
Dim fileName As String = IO.Path.GetFileName(postedFile.FileName)
'postedFile.SaveAs(Server.MapPath("~/Uploads/") & fileName) ' Single file either way
postedFile.SaveAs(Server.MapPath("~/Uploads/") & testName) ' Duplicate file CodeFile and no Namespace
End If
Next
End Sub
End Class
I added a folder to the project Uploads.
I only get one file. That web site saved as a zip file is here:
Now, if you want to mess around, and try changing CodeFile settings, then be my guest - but I would NOT risk doing as such, since a web site assumes that IIS will compile that code.
Ok, now lets do this with a asp.net web site project. This one:
And again, now we do NOT use open web site, but will use open project when you want to work on this application.
so, link to first example - zipped web site (not app), open as web site.
https://1drv.ms/u/s!Avrwal_LV4qxhpxvZPRHjzs6JES-LQ?e=HQvgp9
And link to 2nd example - zipped web site applcation. Open the project file.
(so you open with open project - choose the sln file).
https://1drv.ms/u/s!Avrwal_LV4qxhpxuJis0Pwwf4jwxxg?e=WUnx8m
Both of these work with the time stamp file example. Neither triggers two files.
Now, at this point, you are free as a bird to start mucking around with the page heading directive - but I been do this for LONG time, and have NEVER messed with that page directive header. I might have touch one when importing a web page from another project.
HOWEVER, you want to let asp.net and the designers create the page heading directive. And I VERY much doubt you can mess with a flip between CodeFile, and codebehind, since that setting is used for TWO VERY different types of projects and a different deployment model.
Edit4: the problem
Remember, I suggested this:
Try changing name of click event. Say test_click. Better yet, remove existing name and use ctrl- space to pop the choice to create new event. It will become ctrl name+ _click, and see if that prevents the double run the code. (Thus move code to new event name)stub
Note carefully in above - I said MOVE the code to a new event stub behind.
When you place a button on a form, you HAVE TWO choices here. You can EITHER double click on the button - and then code behind wires up a Handles event.
OR YOU CAN put the event name in the markup, and YOU WILL NOT be using, nor get a handles event.
In above suggestion, I stated to remove the default click you have, erase it, and then hit ctrl-space. You get this:
So, that will create a NEW event stub in code behind. And NOTE very, but very carefully I stated this:
Thus move code to new event name)stub
In other words, we remove the other stub.
So, the reason (of couse!!!) is that a static file name works, is that the code WAS running two times, but since the name is the same, you get one file - the same file.
If you use milliseconds, and HAVE TWO events wired up to the one button, then the code stub fires two times. (and you get two files as a result)
And HOW MANY times did I ask this:
quote:
when you say you get two files, is your sub being called two times? Or does the for/next loop run two times? Which is it?
and this:
quote:
but then you not answered the question. Does the code run two times? that code can't create two files unless it runs two time, or is called two times. If you put in a break-point, and debug the code when it runs, what happens? single step that code, and determine if the routine is called two times, or the loop runs two times
and this:
quote:
You did not try my break-point suggestion - you need to do that.
So, when I asked above multiple times - I assume you tested, checked, and REMOVED that from our list of things to check. Skipping a suggestion to test/check try during a trouble shooting session is a VERY bad thing to do. I take that out and off the list once I add that question + suggestion. I have to assume you double checked, and double tested that solution.
So, you did not follow up on my things to try - ignored them.
So, the issue was and is simple. There was two events attached to the button click, the code stub runs two times. And with milisecond file name, then you get two files. With a single file name, it ALSO was running two times, but you saving the file two times.
So, this issue I brough up was ignored.
So, either use the screen cap ctrl-space to create the event stub in markup, OR double click on the button and let the code behind have a handler. (but, you had both active at the same time). (aand of couse then remove the onclick in the markup - you can't have both active).
So, remove the onclick in markup (and remove the code beind stub). Now try the double click to crate the event.
You can add the event EITHER way as per above, but you can't have a handles event (in code behind) AND ALSO a onclick in the markup.
So, do one, or the rother - but not both. So you can have or add onclick in the markup (use ctrl-space) -- create new event, and REMOVE the (or any) old event with the "handles" directive.
Good luck!
For background, we are in the process of upgrading to Windows Server 2012 R2, and testing revealed that some date input textboxes on our ASP.NET site aren't working as intended. The textboxes have a CompareValidator defined for them to check if one date is later than the other.
<asp:CompareValidator ID="CompareValidator3" runat="server" ControlToCompare="txtStartDate"
ControlToValidate="txtEndDate" ErrorMessage="..." Operator="GreaterThan" Type="Date"
Display="Dynamic"></asp:CompareValidator>
This CompareValidator is failing all the time now, on Windows Server 2012, whereas the old site hosted on Windows Server 2008 did not have this problem. I have done some digging and I think the most likely culprit is the change in default date format for the Canada region in Windows Server 2012. In the generated code for the page, the DOM element for the validator has a property "dateorder" that's always being set to "ymd". This value is "dmy" on the old site.
...
cutoffyear: "2029"
dataset: DOMStringMap
dateorder: "ymd"
dir: ""
display: "Dynamic"
...
Because our inputs take date strings like "01/01/2015", the "ymd" pattern is not matched and the validator returns false. I have changed the date format settings everywhere that I can think of, and even tried changing the IIS site's .NET Globalization settings to use another culture (en-GB), and nothing has worked. I'm really curious as to where this "ymd" setting comes from, and how to change it. Any help is greatly appreciated. Thanks!
"dateorder" comes from BaseCompareValidator which essentially reads CultureInfo.CurrentCulture
DateTimeFormatInfo dateTimeFormat = CultureInfo.CurrentCulture.DateTimeFormat;
string pattern = dateTimeFormat.ShortDatePattern;
string dateorder = (pattern.StartsWith ("y", true, Helpers.InvariantCulture) ? "ymd" : (pattern.StartsWith ("m", true, Helpers.InvariantCulture) ? "mdy" : "dmy"));
Now the gotcha as pointed here, is that Regional Settings is per-user and you might want to check the account the Application Pool was running under.
Maybe somebody changed the date format in the Windows OS on the old computer? But how about trying to force it within your application...my idea is to do it in the Global.asax file (you may have to add that file to the root of the application if it is not already there). Then, something like this:
using System.Globalization;
using System.Threading;
protected void Application_BeginRequest(Object sender, EventArgs e)
{
CultureInfo myCulture = (CultureInfo) System.Threading.Thread.CurrentThread.CurrentCulture.Clone();
myCulture.DateTimeFormat.ShortDatePattern = "dd-MM-yyyy";
myCulture.DateTimeFormat.DateSeparator = "-";
Thread.CurrentThread.CurrentCulture = myCulture;
}
Have you try to change sort date from control panel regional setting. Dateorder and cutoffyear etc attribute are used by validation JavaScript generated by .net for validator control to function on browser. Value of these comes from server settings. IIS only picks as per server config and generats HTML.
I have an ASP.NET (.NET v4) web application running on IIS 7.5. I have a 3rd party which wants to pass information to my system. They support passing this information using HTTP POST, the information they provide is:
"This method simply calls a script on your server and passes each
field as a CGI variable. When you have received the data your server
should return a '1' on a line by itself to indicate success. Anything
else will generate an error on our server which will be investigated.
To set up this delivery method we need a URL to post to. We can use
HTTP or HTTPS."
My web application currently implements many WCF services but as I don't know what the variables passed in will be I cannot define a specific contract. Can I create a normal aspx page which they can post to and then read each of the parameters passed and do the appropriate processing.
If I do this how do I send back a line containing '1'?
Do I need to do anything else to make this HTTP POST compatible.
The last time I had to tackle a similar situation, i did it using a standard ASPX page, and it all worked quite well.
In my case the output was XML, so I had to make sure that I changed the output mime type to match "text/xml" in my case.. "text/plain" I would guess in yours..
Anyway, C# sharp code below, and make sure that your ASPX file has ONLY the very top line in, that is:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="register.aspx.cs" Inherits="myservices.register" ContentType="text/xml" %>
and nothing else, no carriage returns or anything.
Then do all your work in the code behind:
protected void Page_Load(object sender, EventArgs e)
{
Response.Clear();
Response.ContentType = "text/plain";
//Get your CGI variables here... you will have to get them to tell you what to expect
string myparam = (string)Request.QueryString["myparam"];
//do what ever you need here with your variables
Response.Write("1");
Response.End();
}// End page load handler
If you need to follow the one with a carriage return, then i believe you can use the carriage return property in the system.environment object, but I've not got doc's to hand to look it up. That should however get you started.
The MOST important thing to remember is to make sure NOTHING is output from the aspx, not even a carriage return.
I've previously written an article on my Blog about how to use this method for producing phone directories for Cisco-IP phones if you want to read it. You can find it here: http://shawtyds.wordpress.com/2009/09/26/cisco-ip-phone-directories-using-c/
I have a TextBox in an Asp.net form. there is a simple javascript witch separates each three digits in TextBox. it works fine when you enter data in TextBox. I used coma , for separating digits and used dot . as floating point character.
as I said every thing works fine when I am entering data in TextBox. but when the post-back occurs and saved data returns to client, every .(s) has been removed (for example 2.3 saved as 23 and digits in TextBox are separated by . instead of ,.
this problem occurs just in a specific server (windows server 2003 sp1) and works fine in other windows server 2003 (SP1)! I am experiencing this problem for first time!
But I think the problem is because of specific Regional & Language Options in the server. This server is joined to a domain controller. when I change the regional and language options to this set:
Decimal Symbol -> .
Digit Grouping Symbol -> ,
nothing changes.
when I check the following item after customizing settings :
Apply All Settings to the current user account and to the default user profile -> checked
when I restart the Server, It jumps out from domain and need to be re-joined to domain controller! and of-course nothing changes again!
Do you had this problem? any solution please!
I can not post code here, because the code is too complex and I am sure problem is not because of code because it is working every where unless the specified server.
EDIT
Also setting regional and language options for network service user may help to solve the problem. any body knows how can I do this ?
Have you tried using the globalization tag in your web.config? This prevents you from running into trouble when multiple servers are configured differently (ie. different languagepacks).
<configuration>
<system.web>
<globalization
culture="en-US"
uiCulture="en-US" />
</system.web>
</configuration>
After goofing around with a similar problem for WAY to long I did the following with the help of a number of clues (also found on StackOverFlow, StackOverFlow rocks by the way...)
The first thing I did was dump out what the server was actually thinking (Page_Load):
var dtInfo = System.Globalization.DateTimeFormatInfo.CurrentInfo;
DisplayDebugInfo(String.Format(
"Culture({0}/{1}), DateFormat(SD:{2},DS:{3})",
System.Globalization.CultureInfo.CurrentCulture.Name,
System.Globalization.CultureInfo.CurrentUICulture.Name,
dtInfo.ShortDatePattern, dtInfo.DateSeparator));
Also on Windows 2003, I tried fixing the regional setting via the regular control panel but with no success.
I also tried setting the globalization settings in the web.config as mentioned in the other solution but with little effect.
It seems that once you start messing with the regional setting you can quickly get to the point where things are messed up. I decided to avoid messing with the registry and go for a code solution because then I would not have to worry when my code was released to production.
I added the following code to the base class for my page so that it would fix it everywhere. You could also place it in the Page_Load.
using System.Globalization;
using System.Threading;
// Fix the cultural settings...
CultureInfo culture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
culture.DateTimeFormat.ShortDatePattern = "MM/dd/yyyy";
culture.DateTimeFormat.DateSeparator = "/";
Thread.CurrentThread.CurrentCulture = culture;
Problem solved. For me anyway.
I'm running into a case where an ASP.NET application using the built-in globalization facilities is crashing.
On an ASP.NET page with the Culture="auto" directive, a user with a neutral culture as their browser language (such as "zh-Hans") will produce the following exception:
Culture 'zh-Hans' is a neutral culture. It cannot be used in
formatting and parsing and therefore
cannot be set as the thread's current
culture.
at System.Globalization.CultureInfo.CheckNeutral(CultureInfo
culture)
at System.Threading.Thread.set_CurrentCulture(CultureInfo
value)
at System.Web.UI.Page.set_Culture(String
value)
at ASP.somePage_aspx.__BuildControlTree(somePage_aspx __ctrl)
at ASP.somePage_aspx.FrameworkInitialize()
Any ideas? Garbage fed into the Culture/UICulture parameters generally seem to be ignored, but this case is causing an unhandled exception.
I was having the same problem and after bonking my head against a wall for a while found the answer right under my nose.
The issue I had was in not understanding the difference between CurrentCulture and CurrentUICulture. The difference being CurrentCulture is used to format dates, numbers and perform sorting, CurrentUICulture is used to lookup culture specific strings from a resource.
I had some code that looked like
return input.ToString("C", System.Globalization.CultureInfo.CurrentUICulture);
when it should be been
return input.ToString("C", System.Globalization.CultureInfo.CurrentCulture);
When you start trying to format culture specific items with a non-specific culture you will get the System.NotSupportedException.
First off, you might consider setting UICulture="auto" as well as Culture="auto" in your <%# Page %> declaration.
Now, I am not seeing this repro on my .NET 4.0 (beta) install, so this might be a product bug in .NET 3.5.
Here's a great resource for learning about neutral cultures and the difference between UICulture and Culture: http://blogs.msdn.com/ddietric/archive/2008/02/05/yacvcp-yet-another-currentculture-vs-currentuiculture-post.aspx
Hope that's helpful.
Can't you set the culture on begin request? (Note: asp.net requests can jump between threads so you need to hook into the thread moving as well.)