Doing DateTime work with different TimeZones? Having a pain converting to UTC, dealing with Daylight Saving Time (DST) etc?
Check the TimeZoneInfo class in .Net 3.5 +.
DaddyCode Team Blog
C# , ASP.NET, MVC, SQL, Sharepoint, JQuery and nowt else from a Web Developer in Leeds
5 May 2011
8 Apr 2011
Localization of jQuery UI DatePicker with ASP.NET
Hello folks! Do you want to make your jQuery DatePicker play nicely with your ASP.NET localization settings?
When you set up your DatePicker inputs on the page, try this:
When you set up your DatePicker inputs on the page, try this:
$('.DatePicker').datepicker({
dayNamesMin: ['<%= string.Join("', '", System.Globalization.DateTimeFormatInfo.CurrentInfo.ShortestDayNames) %>'],
monthNames: ['<%= string.Join("', '", System.Globalization.DateTimeFormatInfo.CurrentInfo.MonthNames) %>'],
monthNamesShort: ['<%= string.Join("', '", System.Globalization.DateTimeFormatInfo.CurrentInfo.AbbreviatedMonthNames) %>']
});
6 Apr 2011
DevExpress ASP.NET Chart : Trial message problem
Well this was annoying and wasted half a day!
We have a registered copy of DevExpress which we use on a site for charting.
We deployed our ASP.NET site to the live server.
We deployed the registered DevExpress DLLs to the site bin folder.
(Find them in C:\Program Files (x86)\DevExpress 2010.1\Components\Sources\DevExpress.DLL - Don't copy the *.design.dll files though)
The web chart pages worked but displayed a message about using the TRIAL version of DevExpress.
Turns out that VS2010 was creating a licenses.licx file in the root of the project which was screwing it up. Annoyingly, the licx file didn't show in the Solution Explorer until you click the little "Show All Files" icon.
Solution: We had to delete the licenses.licx file, then rebuild the project, then redeploy.
More info: http://community.devexpress.com/blogs/ctodx/archive/2009/03/06/licenses-licx-file-woes.aspx
We have a registered copy of DevExpress which we use on a site for charting.
We deployed our ASP.NET site to the live server.
We deployed the registered DevExpress DLLs to the site bin folder.
(Find them in C:\Program Files (x86)\DevExpress 2010.1\Components\Sources\DevExpress.DLL - Don't copy the *.design.dll files though)
The web chart pages worked but displayed a message about using the TRIAL version of DevExpress.
Turns out that VS2010 was creating a licenses.licx file in the root of the project which was screwing it up. Annoyingly, the licx file didn't show in the Solution Explorer until you click the little "Show All Files" icon.
Solution: We had to delete the licenses.licx file, then rebuild the project, then redeploy.
More info: http://community.devexpress.com/blogs/ctodx/archive/2009/03/06/licenses-licx-file-woes.aspx
18 Feb 2011
Free Reflector Alternative
RedGate! Bah, and humbug. Their DB products have often come in useful for me, but they are also pretty slow and I can't help thinking that they could be a lot better. But now they've riled me! Raaargh!
Reflector's forced-update feature was a bit annoying even back in the days of Lutz Roeder, but at least there was a fair idea behind it - to ensure everyone had the latest and greatest free version. Now they've revealed that the forced update from the free V6 version is going to install the paid-for V7 version with an evaluation period before lock-down.
Well, this sucks. Why can't they release a final free V6 version with no forced update? Oh yeah, $$$.
Good job SharpDevelop have released their own free alternative to Reflector. I've had a play and even in Beta it does everything I need. So wooyay to them!
Reflector's forced-update feature was a bit annoying even back in the days of Lutz Roeder, but at least there was a fair idea behind it - to ensure everyone had the latest and greatest free version. Now they've revealed that the forced update from the free V6 version is going to install the paid-for V7 version with an evaluation period before lock-down.
Well, this sucks. Why can't they release a final free V6 version with no forced update? Oh yeah, $$$.
Good job SharpDevelop have released their own free alternative to Reflector. I've had a play and even in Beta it does everything I need. So wooyay to them!
24 Dec 2010
ASP.NET MVC 2 Freelance Contractor in Leeds, Yorkshire
I'm a Freelance C# / ASP.NET web application developer based in Leeds, Yorkshire, UK. I've years of experience and have just finished a funky AJAX-heavy MVC contract with oodles of Entity Framework fun, and my usual attention to User Experience. Do you want to hire me? In January I'll be free to do another contract so please get in touch if you think I could help!
17 Dec 2010
Lenovo T410 2-finger scroll edge problem
I love my new Lenovo T410, but the 2-finger scrolling didn't seem to be working right. The area of the touchpad in which the scroll would be detected seemed too narrow. Turns out that "gesture filtering" was enabled and needed to be turned off.
Go to mouse properties / ultranav / touchpad / settings / Smart Check Settings / Gesture Filtering
15 Dec 2010
Castle ActiveRecord / NHibernate Update Event Interceptor to Log Dirty Property Changes
Man I love the Castle Project documentation. Or at least, I would if I was a robot with a brain the size of a planet and an unlimited amount of time on my hands. Sadly I'm a human and find the whole thing impenetrable.
All I wanted to do was to intercept the NHibernate entity update event so that I could log the changes made. With kudos to this dude and this dude, here's how I did it:
1. In my project create a new class:
Note it uses a struct called EntityPropertyUpdate and a collection called RuntimeManager.EntityPropertyUpdates to keep a log of the changes. You'll have to roll your own if you want to do what I'm doing here, otherwise just modify the code as you see fit.
The other key thing is the ActiveRecordStarter.Initialize() call, which had to be changed to include the assembly containing the AuditUpdateListener class, which happened to be the main executing assembly. I was doing my AR Initialisation in global.asax so it now looks like this:
That's all!
Incidentally though, if you want to use an ambient AR SessionScope like I do, add this to global.asax:
All I wanted to do was to intercept the NHibernate entity update event so that I could log the changes made. With kudos to this dude and this dude, here's how I did it:
1. In my project create a new class:
using Castle;
using Castle.ActiveRecord;
using Castle.ActiveRecord.Attributes;
using NHibernate;
using NHibernate.Event;
Note it uses a struct called EntityPropertyUpdate and a collection called RuntimeManager.EntityPropertyUpdates to keep a log of the changes. You'll have to roll your own if you want to do what I'm doing here, otherwise just modify the code as you see fit.
[EventListener()]
public class AuditUpdateListener : IPostUpdateEventListener
{
private const string _noValueString = "EMPTY";
private static string getStringValueFromStateArray(object[] stateArray, int position)
{
var value = stateArray[position];
return value == null || value.ToString() == string.Empty
? _noValueString
: value.ToString();
}
public void OnPostUpdate(PostUpdateEvent evt)
{
if (!(evt.Entity is Log_G))
{
var dirtyFieldIndexes = evt.Persister.FindDirty(evt.State, evt.OldState, evt.Entity, evt.Session);
foreach (var dirtyFieldIndex in dirtyFieldIndexes)
{
var oldValue = getStringValueFromStateArray(evt.OldState, dirtyFieldIndex);
var newValue = getStringValueFromStateArray(evt.State, dirtyFieldIndex);
if (oldValue != newValue)
RuntimeManager.EntityPropertyUpdates.Add(new RuntimeManager.EntityPropertyUpdate { EntityName = evt.Entity.GetType().Name, PropertyName = evt.Persister.PropertyNames[dirtyFieldIndex], PropertyFrom = oldValue, PropertyTo = newValue });
}
}
}
}
The other key thing is the ActiveRecordStarter.Initialize() call, which had to be changed to include the assembly containing the AuditUpdateListener class, which happened to be the main executing assembly. I was doing my AR Initialisation in global.asax so it now looks like this:
protected void Application_Start()
{
// ActiveRecord Setup
IConfigurationSource source = ActiveRecordSectionHandler.Instance;
Assembly asm = Assembly.Load("MyApp.DataLayer");
ActiveRecordStarter.Initialize(new Assembly[] {asm, Assembly.GetExecutingAssembly()}, source, new Type[] { });
}
That's all!
Incidentally though, if you want to use an ambient AR SessionScope like I do, add this to global.asax:
protected void Application_BeginRequest(Object sender, EventArgs e)
{
// Create a SessionScope for ActiveRecord
HttpContext.Current.Items.Add("ar.sessionscope", new SessionScope(FlushAction.Never));
}
protected void Application_EndRequest(object sender, EventArgs e)
{
// Close the SessionScope for ActiveRecord
try
{
SessionScope scope = HttpContext.Current.Items["ar.sessionscope"] as SessionScope;
if (scope != null)
scope.Dispose();
}
catch (Exception ex)
{
HttpContext.Current.Trace.Warn("Error", "EndRequest: " + ex.Message, ex);
}
}
6 Dec 2010
MVC File Upload - Using Uploadify with ASP.NET MVC 2 / 3
NOTE 23 Oct 2012
I no longer recommend the use of Uploadify with MVC. I've found benefit using javascript-only solutions such as DropZone : http://www.dropzonejs.com/
or Valum's File Uploader : https://github.com/Valums-File-Uploader/file-uploader
or Valum's File Uploader : https://github.com/Valums-File-Uploader/file-uploader
Uploadify is ace for performing file upload and image upload, but ASP.NET MVC docs were lacking, so I hope this helps someone. Critical points addressed here include:
- Uploadify flash upload button is ugly so we use CSS to make it invisible and fake an HTML button under it.
- The Uploadify flash upload doesn't pass the ASP.NET session and authentication cookies naturally, which we want for recognition and authorization, so we handle that.
Put all Uploadify files in a project folder called ClientScript/uploadify
SCRIPT
Put this code on the regular View page that performs the upload.
<script type="text/javascript" src="<%= Url.Content("~/ClientScript/jquery-1.4.2.min.js") %>"></script>
<script type="text/javascript" src="<%= Url.Content("~/ClientScript/uploadify/swfobject.js") %>"></script>
<script type="text/javascript" src="<%= Url.Content("~/ClientScript/uploadify/jquery.uploadify.v2.1.4.min.js") %>"></script>
<script type="text/javascript">
$(function () {
// Uploadify File Upload System
// SessionSync data is sent in scriptData for security reasons, see UploadifySessionSync() in global.asax
var UploadifyAuthCookie = '<% = Request.Cookies[FormsAuthentication.FormsCookieName] == null ? string.Empty : Request.Cookies[FormsAuthentication.FormsCookieName].Value %>';
var UploadifySessionId = '<%= Session.SessionID %>';
$("#fuFileUploader").uploadify({
'hideButton' : true, // We use a trick below to overlay a fake html upload button with this hidden flash button
'wmode' : 'transparent',
'uploader': '<%= Url.Content("~/ClientScript/uploadify/uploadify.swf") %>',
'cancelImg': '<%= Url.Content("~/ClientScript/uploadify/cancel.png") %>',
'buttonText': 'Upload File',
'script': '<%= Url.Action("FileUpload", "Media") %>',
'multi': true,
'auto': true,
'scriptData' : { RequireUploadifySessionSync: true, SecurityToken: UploadifyAuthCookie, SessionId: UploadifySessionId },
'onComplete' : function (event, ID, fileObj, response, data)
{
response = $.parseJSON(response);
if (response.Status == 'OK')
{
// Put your own handler code here instead of the following...
alert('File Uploaded OK!');
}
}
});
});
</script>
HTML
Put this HTML on the same View as the script above.
<div style="position: relative;">
<input type="button" id="btnUpload" value="Upload File" />
<div style="position: absolute; top: 4px; left: 3px;">
<input id="fuFileUploader" name="file_upload" type="file" />
</div>
</div>
GLOBAL.ASAX
Add the following bits.
protected void Application_BeginRequest(Object sender, EventArgs e)
{
if (HttpContext.Current.Request["RequireUploadifySessionSync"] != null)
UploadifySessionSync();
}
/// <summary>
/// Uploadify uses a Flash object to upload files. This method retrieves and hydrates Auth and Session objects when the Uploadify Flash is calling.
/// </summary>
/// <remarks>
/// Kudos: http://geekswithblogs.net/apopovsky/archive/2009/05/06/working-around-flash-cookie-bug-in-asp.net-mvc.aspx
/// More kudos: http://stackoverflow.com/questions/1729179/uploadify-session-and-authentication-with-asp-net-mvc
/// </remarks>
protected void UploadifySessionSync()
{
try
{
string session_param_name = "SessionId";
string session_cookie_name = "ASP.NET_SessionId";
if (HttpContext.Current.Request[session_param_name] != null)
UploadifyUpdateCookie(session_cookie_name, HttpContext.Current.Request.Form[session_param_name]);
}
catch {}
try
{
string auth_param_name = "SecurityToken";
string auth_cookie_name = FormsAuthentication.FormsCookieName;
if (HttpContext.Current.Request[auth_param_name] != null)
UploadifyUpdateCookie(auth_cookie_name, HttpContext.Current.Request.Form[auth_param_name]);
}
catch {}
}
private void UploadifyUpdateCookie(string cookie_name, string cookie_value)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookie_name);
if (cookie == null)
cookie = new HttpCookie(cookie_name);
cookie.Value = cookie_value;
HttpContext.Current.Request.Cookies.Set(cookie);
}
Models/MediaAssetUploadModel.cs
public class MediaAssetUploadModel
{
public HttpPostedFileBase fileData { get; set; }
public string SecurityToken { get; set; }
public string Filename { get; set; }
}
Controllers/MediaController.cs
[Authorize]
public ActionResult FileUpload(MediaAssetUploadModel uploadedFileMeta)
{
string fullFilePath = SaveUploadedFile(uploadedFileMeta);
//TODO: Error handling
return Json(new { Status = "OK" });
}
//TODO: move this into a manager/repository class
private string SaveUploadedFile(MediaAssetUploadModel uploadedFileMeta)
{
string fileName = Guid.NewGuid() + System.IO.Path.GetExtension(uploadedFileMeta.Filename);
string fullSavePath = Path.Combine(ConfigurationManager.AppSettings["MediaAssetFolder"], fileName);
uploadedFileMeta.fileData.SaveAs(fullSavePath);
return fullSavePath;
}
Web.config
Make following changes to upload files to c:\temp , with a max file size of 100Mb.
Change these to suit yourself - c:\temp will get automatically cleared so you have been warned.
If you create your own upload folder, remember you will need to give write perms to the ASP.NET process.
<configuration> <appSettings> <add key="MediaAssetFolder" value="c:\temp"/> </appSettings> <system.web> <httpRuntime maxRequestLength="100000" /> </system.web> </configuration>
26 Nov 2010
Simple Jquery Lightbox
Wrote some code that I didn't end up using, but it's a shame to bin it :)
Simple lightbox using Jquery UI dialog widget:
Simple lightbox using Jquery UI dialog widget:
function LightBox(imgSrc, imgTitle)
{
var img = $('<img />');
$('body').append(img);
img.attr('src', imgSrc);
img.load(function()
{
var lightBox = $('<div></div>');
lightBox.dialog({ autoOpen: false, height: img.height() + 50, width: img.width() + 50, modal: true, title : imgTitle });
lightBox.html('').append(img);
lightBox.dialog('open');
});
};
12 Nov 2010
Duffs Lodge
We stayed at Duff's Lodge, Beaufort Estate nr. Beauly, Inverness-shire. Nice.
Would just like to say that the Priory Hotel in Beauly makes the worst sunday roast in the known world.
On the plus side, food and drink at The Cawdor Tavern is bloody lovely.
Apart from that, the road to Skye from Inverness is gobsmacking, and Glen Affric is beautiful.
That is all! Back to the C# shenanigans.
Would just like to say that the Priory Hotel in Beauly makes the worst sunday roast in the known world.
On the plus side, food and drink at The Cawdor Tavern is bloody lovely.
Apart from that, the road to Skye from Inverness is gobsmacking, and Glen Affric is beautiful.
That is all! Back to the C# shenanigans.
Subscribe to:
Posts (Atom)
If I helped you out today, you can buy me a beer below. Cheers!