Hi
I am new to web programming and I have an mvc app which runs on azure. There is a functionality where users can export grid data to csv and one of the fields is a datetime field. When the user clicks on export I take whatever is in the grid, format it to csv and then return a FileContentResult. The problem I have is that since the construction of the csv is happenning on the server, the dateformat is formatted to be en-US since I guess thats the VMs setting. I need to however use the users datetimeformat. Is there a way I can achieve this
You can get client culture from the header. Take a look at HttpContext.Current.Request.Browser
Related
I have an asp.net webpage, with a jQuery datepicker on it.
I am in the UK, so when I enter 28/02/2010, I expect it to resolve to 28th Feb 2010.
This is working as expected on my local dev env - but not on our QA or prod-like envs - or one of the other dev machines. In these cases it seems to attempt to resolve it to American date format - and fails validation as it is out of range.
The jQuery seems to generate the correct date each time - which leads me to think it may be a database issue.
I am using SQL Server 2005, my collation is Latin1_General_CI_AS, my colleagues are using collation SQL_Latin1_General_CP1_CI_AS, and a Chinese one.
Given that we don't have control over the prod SQL Server installation (just our db), what is the best way to make this work in a standard way? Change the db settings, or the code that uses it?
Thanks in advance!
- L
[EDIT to add code info]
This is my view code to call the datepicker:
<%=Html.TextBox("DateOfBirth", Model.DateOfBirth.ToShortDateString(), new { #class = "datepicker" })%>
Here is the js for the datepicker:
DatePickerSettings = {
setup: function () {
$(".datepicker").datepicker({
dateFormat: 'dd/mm/yy',
changeMonth: true,
changeYear: true
});
}
};
And this is how I specify the date in the model:
[Required]
[DisplayName("Date of Birth")]
public virtual DateTime DateOfBirth { get; set; }
The date appears correct inthe controller and repository... until it hits the db.
Thanks :)
I was hoping to wait until you'd updated the question with some more information, but as I've seen some answers suggesting that you change the string format you use to talk to the database...
Don't send dates as raw text in SQL queries.
Use a parameterized query, which means you don't need to worry about formatting the value at all. Then you've just got to make sure that you can get the date format correct between the browser and ASP.NET.
Aside from anything else, if you're including user data in SQL queries directly, you'll generally be opening yourself up to SQL injection attacks. Always use parameterized queries (unless your web app is really a "run this SQL" test tool...)
If you're already using parameterized queries, then the problem is likely to be between the browser and ASP.NET, and the database part is irrelevant. Divide and conquer the problem: chase the data as it passes through different layers (browser, jQuery, ASP.NET etc) until you find out where it's gone wrong. Don't even think about a fix until you know where it's gone wrong.
Is your page Culture aware?
You can determine UI Cutlure information for different browsers(locales) and have your ASP.NET Culture constant.
The Culture value determines the results of culture-dependent functions, such as the date, number, and currency formatting, and so on. The UICulture value determines which resources are loaded for the page
Check out this MSDN link:
How to: Set the Culture and UI Culture for ASP.NET Web Page Globalization
http://msdn.microsoft.com/en-us/library/bz9tc508(v=VS.85).aspx
Use CONVERT to change the date format to a standard that is accepted across all environments.
CAST and CONVERT
I'd have to see the code that interprets the dates to know for sure, but a likely suspect is the Region and Language settings on the machines where the code is running. Make sure it is set appropriately for your region.
However, if you can't change settings on the servers, you should probably explicitly use CAST or CONVERT in SQL Server to force it to parse it in the region specific way you expect the data will be entered.
You also need to check your ASP.Net layer, and see what it is running in.
Check the machine configuration and check they are set to run in the same date/time/region.
Change your code to use yyyymmdd format.
As far as i know it works in all the DBs
Just to add another opinion here, I find dd/mmm/yyyy the best date format to send to databases as it's completely unambiguous across cultures.
I have a site that saves a date in my model to the database.
After launching my site I realised that the server has US regional settings so I had to make sure that all date's on the public site were formatted in the UK format.
However now when I go to my 'Create' page and choose a date and click save I get the error The value '22/11/2009' is not valid for the Date field. which must be coming from the default DataAnnotations on my model.
Is there something I can do to get it to accept UK formatted dates?
I managed to get it working by putting this into the web.config
<globalization culture="en-GB"/>
Have you tried this? If this site is only used in the UK, you can probably put this in the Global.asax Application_Init. If it is based on the user, you can put it in Application_BeginRequest. This will provide the default formatting and parsing for all dates and numbers in the application.
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-gb");
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-gb");
Do what SO does: persist all dates in UTC and render them as UCT with an appended "Z" for GMT/UTC/Zulu. It might not be ideal but sometimes the gain from simplicity outweighs the costs of the alternative. Think about that.
I was wondering what's the best practise for serving a generated big file in classic asp.
We have an application with "export to excel" function that produces 10MB files. The excels are created by just calling a .asp page that has the Response.ContentType set to excel and has an HTML table for the data.
This gives as problem that it takes 4 minutes before the user sees the "Save as..." dialog.
My current solution is to call an .asp page that creates the excel on the server with AJAX and lets the page return the URL of the generated document. Then I can use javascript to display the on the original page.
Is this easy to do with classic asp (creating files on server with some kind of stream) while keeping security in mind? (URL should make people be able to guess the location of other files)
How would I go about handling deleted the generated files overtime? They have to be deleted periodicly as the data changes in realtime.
Thanks.
edit: I realized now that creating the file on the server will probably also take 4 minutes...
I think you are selecting a complex route, when the solution is simple enough (Though I may be missing some requirements)
If you to generate an excel, just call an asp page that do the following:
Response.clear
Response.AddHeader "content-disposition", "attachment; filename=myexcel.xls"
Response.ContentType = "application/excel"
'//write the content of the file
Response.write "...."
Response.end
This will a start a download process in the browser without needing to generate a extra call, javascript or anything
See this question for more info on the format you will choose to generate the excel.
Edit
Since Thomas update the question and the real problem is that the file take 4 minutes to generate, the solution could be:
Offer the user the send the file by email (if this is a workable solution in you server or hosting).
Generate the file async, and let the user know when the file generation is done (with an ajax call, like SO does when other user have added an answer)
To generate the file on the server
'//You should change for a random name or something that makes sense
FileName = "C:\temp\myexcel.xls"
FileNumber = FreeFile
Open FileName For Append As #FileNumber
'//generate the content
TheRow = "...."
Print #FileNumber, TheRow
Close #FileNumber
To delete the temp files generated
I use Empty Temp Folders a freeware app that I run daily on the server to take care of temp files generated. (Again, it depends on you server or hosting)
About security
Generate the files using random numbers or GUIds for a light protection. If the data is sensitive, you will need to download the file from a ASP page, but I think that you will be in the same problem again...(waiting 4 minutes to download)
Read file using FSO.
Set headers for Excel file-type, name according to file read and for download (attachment)
Flush response after headers are set. The client should display "save as" dialogue.
Output FSO to response. Client will download file and see progress bar.
How do you plan to generate the Excel? I hope you don't plan to call Excel to do that, as it is unsupported, and generally won't work well.
You should check to see if there are COM components to generate Excel that you can call from Classic ASP. Alternatively, add one ASP.NET page for the purpose. I know for a fact that there are compoonents that can be called from ASP.NET pages to do this. Worse come to worst, there's an Excel exporter component from Infragistics that works with their UltraWebGrid control to export. The grid need not be visible in order to accomplish this, but styles in the grid translate to styles in the spreadsheet. They also allow you to manipulate the spreadsheet programmatically.
I need to create a service that will return XML containing data from the database. So I am thinking about using an ASHX that will accept things like date range and POST an XML file back. I have dealt with pages pulling data from SQL Server and populating into a datagrid for visual display but never into XML for delivery, what is the best way to do this? Also if an ASHX and POST isn't the best method for delivery let me know... thanks!
EDIT: These answers are great and pointing me in the right direction. I should have also mentioned that the XML format has already been decided so I can't use any automatically generated one.
Combining linq2sqlwith the XElement classes, something along the lines:
var xmlContacts =
new XElement("contacts",
(from c in context.Contacts
select new XElement("contact",
new XElement
{
new XElement("name", c.Name),
new XElement("phone", c.Phone),
new XElement("postal", c.Postal)
)
)
).ToArray()
)
);
Linq2sql will retrieve the data in a single call to the db, and the processing of the XML will be done at the business server. This splits the load better, since you don't have the sql server doing all the job.
Have you tried DataSet.WriteXml()?
You could have this be the output of a web service call.
Sql Server 2005 and above has a "FOR XML AUTO" command that will convert your recordset to XML for you. Then you just have to return a string from your ASHX.
Beginning with SQL Server 2000, you can return query results as XML. For absolute control of them, use the "FOR XML EXPLICIT" command. You can use any format you desire that way.
http://msdn.microsoft.com/en-us/library/ms189068.aspx
It's as easy as writing your result to the raw output then. For added points, you can return the result set to a XPathDocument, pass it through an XSL transformation, and send the results out in any format you choose (HTML vs XML at the click of a button perhaps).
you can obtained that to a datatable and then call myTable.WriteXML()
if you are populating classes with the your database results then add the serializable attribute to the header your classes, and use the XMLSerializer
Converting an automatically generated format into a specified one is a job for xslt. Just find a way to run the output from the tool through an xslt filter.
Oracle has a great product for doing exactly this job - the oracle XDK. But it's a java thing, not ASP as far as I know.
For an example, this XHTML
http://www.anbg.gov.au/abrs/online-resources/flora/stddisplay.xsql?pnid=2524
is generated automatically from this XML, which is generated by oracle
http://www.anbg.gov.au/abrs/online-resources/flora/stddisplay.xsql?pnid=2524&xml-stylesheet=none
Of course, you are not after XHTML, but some other XML format. But XSLT will do the job.
Is it possible to display local times to users without using Javascript when you store the values as UTC?
You would need serverside to be aware of the clients timezone. There isn't enough information in the typical request to make that determination, the closest you can get is the Accept_Language header which might give you a clue but is hardly useful enough (esp. if the client is in a country that has multiple timezones).
Hence you would need to user to tell you what their timezone is and then use a logon or cookie to store that info.
You could do the conversion on the serverside in vb.net, c# or whatever .net language your using. You are going to have to convert to the local time somewhere.
Your asking a very broad question with no detail so I can't recommend how to do this on the server.
Edit
Based on the comments I see the problem your having is that you want to figure out what the users timezone is without javascript. I always have the user tell me their timezone when they register.
One approach which won't be perfect would be would to be use a geo-ip lookup service that will tell you most likely where your user and give your better granularity then using the language settings.
Think this is the closest you can do:
using System.Globalization;
// get the first language from request (en, fr, ru)
var primaryLanguage = Request.UserLanguages.First().Split(";").First();
// find a culture by this language
var culture = new CultureInfo(primaryLanguage);
// if the culture is neutral, try to find the specific one
if (culture.IsNeutralCulture)
culture = CultureInfo.GetCultures(CultureTypes.SpecificCultures).FirstOrDefault(o => o.TwoLetterISOLanguageName == primaryLanguage);
// get the string from a datetime
var datetimeText = culture ? DateTime.Now.ToString(culture) : DateTime.Now.ToString();