update s set s.thisField = d.thatField, s.anotherField = d.andAnotherField from Table1 s, Table2 d where s.id = d.table1Id
Thursday, 23 December 2010
Updating fields in one table with fields in another
Tuesday, 9 November 2010
"the file attached is invalid" error using asyncfileupload
I recently dabbled with the neat control AsyncFileUpload from the Ajax Control ToolKit which facilitates the asynchronous upload of files via the browser to the server without affecting the rest of the parent page and without causing a full postback.
I did however get an error "the file attached is invalid" when first trying it out.
Eventually fixed by adding the following to the design code:
I did however get an error "the file attached is invalid" when first trying it out.
Eventually fixed by adding the following to the design code:
ClientIDMode="AutoID"
Monday, 25 October 2010
BULK INSERT csv data into a SQL Server table
BULK INSERT tblDespatchBySize FROM 'D:\path\myFile.csv' WITH ( FIELDTERMINATOR = ',', ROWTERMINATOR = '\n' ) GO
Thursday, 7 October 2010
Ajax tab controls, SEO, page titles and meta tags
The .Net tab control can be an SEO nightmare. Ajax-driven content like this is un-navigable by search engine spiders, and so we have to provide a way for search engines to reach this content. I've seen rather confused implementations of this - one in particular springs to mind that was using javascript to update the page title and SEO meta tags depending on what tab was being viewed. Entirely pointless.
The best way to get search engines indexing your tab content is this:
1. Implement a way of detecting if your visitor has javascript enabled (most human users) or not (a search engine spider).
This is simple. By using the code below we're saying that if javascript is enabled then navigate from this tab link normally using the js code and return false (thereby cancelling the href). If javascript isn't enabled then the onClick event will be ignored entirely and the browser will navigate to the href:
Where x is a value indicating which tab you want. And the function SetHidValue looks like this:
It sets a hidden field
2. Provide direct URLs (preferably vanity URLs) that navigate to each of the tabbed pages.
For instance http://www.widgets.com/widgets/yellow/specification might be re-written into something like this http://www.widgets.com/widgets.aspx?name=yellow&tab=specification
For URL rewriting I tend to use the tools from Intelligencia.
3. Ensure each page has it's own title, description, keywords and canonical tag matching the vanity URL.
Canoncial tags ensure that the search engines index your page as you want it to be indexed, eliminating unfriendly URLs and duplicate entries, thereby improving ranking.
For instance, your canonincal tag for http://www.widgets.com/widgets.aspx?name=yellow&tab=specification would match its vanity URL thus:
The best way to get search engines indexing your tab content is this:
1. Implement a way of detecting if your visitor has javascript enabled (most human users) or not (a search engine spider).
This is simple. By using the code below we're saying that if javascript is enabled then navigate from this tab link normally using the js code and return false (thereby cancelling the href). If javascript isn't enabled then the onClick event will be ignored entirely and the browser will navigate to the href:
Where x is a value indicating which tab you want. And the function SetHidValue looks like this:
function SetHidValue(value) { document.getElementById("<%=hidValue.ClientID %>").value = value; document.getElementById("<%=btnSubmit.ClientID %>").click(); }
It sets a hidden field
<asp:HiddenField ID="hidValue" runat="server" Value="1" />and clicks a submit button
<asp:Button ID="btnSubmit" runat="server" />in the tab control.
2. Provide direct URLs (preferably vanity URLs) that navigate to each of the tabbed pages.
For instance http://www.widgets.com/widgets/yellow/specification might be re-written into something like this http://www.widgets.com/widgets.aspx?name=yellow&tab=specification
For URL rewriting I tend to use the tools from Intelligencia.
3. Ensure each page has it's own title, description, keywords and canonical tag matching the vanity URL.
Canoncial tags ensure that the search engines index your page as you want it to be indexed, eliminating unfriendly URLs and duplicate entries, thereby improving ranking.
For instance, your canonincal tag for http://www.widgets.com/widgets.aspx?name=yellow&tab=specification would match its vanity URL thus:
<link rel="canonical" href="http://www.widgets.com/widgets/yellow/specification" />
Thursday, 30 September 2010
Reorder list and remove items using LINQ lambda query
Re-ordering items in a list:
listPeople = listPeople.OrderBy(x => x.Surname).ToList();Removing items from a list:
listPeople.RemoveAll(x => x.Age < 16);
Thursday, 26 August 2010
Randomly sort a list using LINQ
This is far neater than the loop and temporary list I had in mind. Two lines of code!
Random rnd = new Random(); myList = myList.OrderBy(x => rnd.Next()).ToList();Or, to take n random elements from a list:
Random rnd = new Random(); myList = myList.OrderBy(x => rnd.Next()).Take(n).ToList();
Wednesday, 25 August 2010
Looking for freelance .net web developers?
Due to the wonders of SEO I get quite a few emails from employers and agencies looking for freelance .net developers. If you're looking for .net developers, asp.net developers, .net web developers, you should try these:
- ask me if I'm available :)
- ask me if I know anyone available.
- advertise on Monster for £99 . This really is very cheap, and will elicit lots of responses. You just need the time to sort through all the cv's you receive. Be sure to state 'no agencies' and stipulate that you need a valid work permit, otherwise you'll get a whole heap of hopefuls who don't yet have the right to work in your country.
- if you're in Bristol, check out the Bristol Media Talent Retention Scheme . If you're not in Bristol, then look for similar industry-community groups in your area.
Tuesday, 24 August 2010
Run code only in debug mode
I always forget the syntax for this!
#if DEBUG //do this in debug #else //do something else in release #endif
Thursday, 19 August 2010
Binding a dropdown list to an XML file of countries
using System.Xml; protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) Bind_ddlCountries(); } private void Bind_ddlCountries() { XmlDocument doc = new XmlDocument(); doc.Load(Server.MapPath("countries.xml")); foreach (XmlNode node in doc.SelectNodes("//country")) { ddlCountries.Items.Add(new ListItem(node.InnerText, node.InnerText)); } }and the source xml country list should look like this:
<countries> <country>Algeria</country> <country>Brazil</country> <country>Colombia</country> </countries>You can get the full list of countries I most recently used here.
Wednesday, 18 August 2010
Empty title tag added when adding an HtmlTitle into a placeholder
I just spent too much time trying to work out why the HEAD tag of a site I was given contained two TITLE entries, and therefore wasn't validating. The head of the masterpage contained a user control that consisted of a single placeholder, to which was being dynamically added a title control like so:
where the variable Title is a string value sent up from specific content page.
It turned out that because the master page's HEAD markup didn't contain any TITLE tags, ASP.NET was surreptitously adding one for me despite me adding one programmatically during the page's build. Stepping through the code when the page was loading didn't show this. It just kind of did it.
I found this hack to put a top to this strange behaviour. I put this in the HEAD tag on the master page. I'm adding the tags to keep it happy, but setting it to visible="false" so we don't see it:
HtmlTitle title = new HtmlTitle(); title.Text = Title; PlaceHolder1.Controls.Add(title);
where the variable Title is a string value sent up from specific content page.
It turned out that because the master page's HEAD markup didn't contain any TITLE tags, ASP.NET was surreptitously adding one for me despite me adding one programmatically during the page's build. Stepping through the code when the page was loading didn't show this. It just kind of did it.
I found this hack to put a top to this strange behaviour. I put this in the HEAD tag on the master page. I'm adding the tags to keep it happy, but setting it to visible="false" so we don't see it:
<title id="Title1" visible="false" runat="server"><%-- hack to turn the auto title off --%></title>Dirty but effective.
Monday, 16 August 2010
Get physical path of file in EpiServer from unfied file path
UnifiedFile file = HostingEnvironment.VirtualPathProvider.GetFile(path) as UnifiedFile; string filePath = file.LocalPath;
Wednesday, 4 August 2010
Getting parameters from RawUrl
Most of the sites I'm working on use URL re-writing (URLRW for short), or "vanity/friendly URLs" as some SEO bods call them. Also, most of the sites I'm working on have affiliate schemes and PPC schemes sending traffic to the sites.
The URLRW rules turn the provided Url into one with appended parameters to identify specfic content. For example:
Vanity Url displayed in browser:
Things get a bit more complex when parameters need to be appended to the vanity Url and recognised by your code. PPC traffic to your yellow widgets might be sent to:
The URLRW rules turn the provided Url into one with appended parameters to identify specfic content. For example:
Vanity Url displayed in browser:
http://www.mywidgets.com/yellow-widgetsUrl after rewriting:
http://www.mywidgets.com/widgets.aspx?product=yellow-widgetsPicking up the parameters in .Net is easy:
HttpContext.Current.Request.QueryString["product"]
Things get a bit more complex when parameters need to be appended to the vanity Url and recognised by your code. PPC traffic to your yellow widgets might be sent to:
http://www.mywidgets.com/yellow-widgets?utm_source=google&utm_medium=ppc&utm_campaign=yellowwidgetsThis Url is re-written by your URLRW rules, and so you can't grab the utm_x parameters using Request.QueryString["utm_x"]. We can however access the 'unfriendly' Url using
HttpContext.Current.Request.RawUrlwhich using the above example will give us the string
"/yellow-widgets?utm_source=google&utm_medium=ppc&utm_campaign=yellowwidgets"but grabbing the parameter values with ease doesn't seem quite so obvious. We could write some kind of bespoke method to parse through the string to find our params and value. The good news is we don't have to. Using the following code you can take the 'real' or 'unfriendly' Url string, and grab the parameter values with ease:
Uri theRealURL = new Uri(HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.RawUrl); string utm_source = HttpUtility.ParseQueryString(theRealURL.Query).Get("utm_source"); string utm_medium = HttpUtility.ParseQueryString(theRealURL.Query).Get("utm_medium"); string utm_campaign = HttpUtility.ParseQueryString(theRealURL.Query).Get("utm_campaign");
Friday, 23 July 2010
Thursday, 15 July 2010
Directing all visits to the www subdomain using IIS7
Your SEO champion will no doubt be banging his fists on his desk if you've built a site that allows users to view the same content on http://mysite.com as well as http://www.mysite.com
What he or she will be demanding is that one of them permanently redirects the user (with a 301 status) to the other. So how do you do this? Well, there might be several ways but this is the way I do it. For this example I'm going to be sending visitors from mysite.com to www.mysite.com.
Remove the 'mysite.com' entry from the bindings of your website but keep the 'www.mysite.com' entry. Create a new website and call it 'mysite.com redirect' or something similar. Add a binding to this for 'mysite.com'. This will then accept incoming visits to 'mysite.com'. Now click on the 'HTTP Redirect' icon:
and configure the site to redirect to 'http://www.mysite.com' with a Permanent(301) setting like below:
This will also honour any deep links to your site. For example if a user goes to http://mysite.com/whatever.aspx?whateverParam=whateverValue they will be redirected to http://www.mysite.com/whatever.aspx?whateverParam=whateverValue
UPDATE: on some machines you may not see the 'http redirect' icon. If this is the case go to the IIS section in 'Server Manager' and you'll probably see the role service isn't installed. You can install it easily from here.
What he or she will be demanding is that one of them permanently redirects the user (with a 301 status) to the other. So how do you do this? Well, there might be several ways but this is the way I do it. For this example I'm going to be sending visitors from mysite.com to www.mysite.com.
Remove the 'mysite.com' entry from the bindings of your website but keep the 'www.mysite.com' entry. Create a new website and call it 'mysite.com redirect' or something similar. Add a binding to this for 'mysite.com'. This will then accept incoming visits to 'mysite.com'. Now click on the 'HTTP Redirect' icon:
and configure the site to redirect to 'http://www.mysite.com' with a Permanent(301) setting like below:
This will also honour any deep links to your site. For example if a user goes to http://mysite.com/whatever.aspx?whateverParam=whateverValue they will be redirected to http://www.mysite.com/whatever.aspx?whateverParam=whateverValue
UPDATE: on some machines you may not see the 'http redirect' icon. If this is the case go to the IIS section in 'Server Manager' and you'll probably see the role service isn't installed. You can install it easily from here.
Wednesday, 14 July 2010
Solving an updatepanel cacheing problem with SetCacheability
I had an issue today with the contents of an update panel appearing to be cached when they should have displayed a more recent listview of search results. Frustratingly this problem was only happening on the server copy of my site rather than locally.
I resolved the problem with the following code in the page load event:
I resolved the problem with the following code in the page load event:
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
UPDATE: ah, so it never worked for Firefox...I went for a solution using a session object instead!
Friday, 2 July 2010
Submitting a sitemap for your Blogger/Blogspot blog
I found this very helpful post on how to submit sitemaps for a blogger blog.
In summary, you need to do the following:
If you have under 500 posts:
http://YOURSITE.blogspot.com/atom.xml?redirect=false&start-index=1&max-results=500
If you have under 1000 posts:
http://YOURSITE.blogspot.com/atom.xml?redirect=false&start-index=1&max-results=500
http://YOURSITE.blogspot.com/atom.xml?redirect=false&start-index=501&max-results=1000
If you have under 1500 posts:
http://YOURSITE.blogspot.com/atom.xml?redirect=false&start-index=1&max-results=500
http://YOURSITE.blogspot.com/atom.xml?redirect=false&start-index=501&max-results=1000
http://YOURSITE.blogspot.com/atom.xml?redirect=false&start-index=1001&max-results=1500
In summary, you need to do the following:
If you have under 500 posts:
http://YOURSITE.blogspot.com/atom.xml?redirect=false&start-index=1&max-results=500
If you have under 1000 posts:
http://YOURSITE.blogspot.com/atom.xml?redirect=false&start-index=1&max-results=500
http://YOURSITE.blogspot.com/atom.xml?redirect=false&start-index=501&max-results=1000
If you have under 1500 posts:
http://YOURSITE.blogspot.com/atom.xml?redirect=false&start-index=1&max-results=500
http://YOURSITE.blogspot.com/atom.xml?redirect=false&start-index=501&max-results=1000
http://YOURSITE.blogspot.com/atom.xml?redirect=false&start-index=1001&max-results=1500
Wednesday, 2 June 2010
Self signing an SSL certificate with selfSSL
I use self signing for internal and development sites quite frequently, but just as frequently I forget how to do it. Now I shalt never forget.
Here's a most excellent post about how to do it in IIS7.
C:\Program Files\IIS Resources\SelfSSL>selfssl /N:CN=mydomain.com /S:150311073 /V:365where S is the site ID and V is the validity in days. Be sure to be running command prompt as Admin.
Here's a most excellent post about how to do it in IIS7.
Thursday, 20 May 2010
Reliably reference a .NET control in javascript using jQuery
The clientside id of a .NET control should never be hardcoded into javascript as it's so unpredictable, and is liable to change. There is one predictable thing about it though, and that is that the rendered id will end in '_myOriginalId'.
You can take advantage of this predictability by using this syntax with jQuery, which will reliably find your control.
You can take advantage of this predictability by using this syntax with jQuery, which will reliably find your control.
$("[id$='_myOriginalId']")
Tuesday, 4 May 2010
Check your server result codes / show HTTP server headers
Here's a neat little tool to check what status code your site is returning, if you don't have Firebug at hand.
It's easy to forget when you set up a bespoke 404 page that you also need to make it return the right code. If you do nothing it will return a '200 OK' status, which isn't good for SEO.
In your .NET code behind you need the following:
It's easy to forget when you set up a bespoke 404 page that you also need to make it return the right code. If you do nothing it will return a '200 OK' status, which isn't good for SEO.
In your .NET code behind you need the following:
protected void Page_Load(object sender, EventArgs e) { Response.Status = "404 Not Found"; }
Monday, 26 April 2010
Disabling File Change Notification (FCN) to avoid AppDomain restarting when adding a directory
I found this code here, and it works a treat. Drop it into your Global.asax (Application_Start) and it will prevent your AppDomain restarting when a subdirectory is modified/added/deleted.
This problem reared its ugly for me recently when logged-in users were losing their sessions because of activities elsewhere on the same system that were creating directories. Problem solved!
This problem reared its ugly for me recently when logged-in users were losing their sessions because of activities elsewhere on the same system that were creating directories. Problem solved!
//FIX disable AppDomain restart when deleting subdirectory //This code will turn off monitoring from the root website directory. //Monitoring of Bin, App_Themes and other folders will still be operational, so updated DLLs will still auto deploy. System.Reflection.PropertyInfo p = typeof(System.Web.HttpRuntime).GetProperty("FileChangesMonitor", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); object o = p.GetValue(null, null); System.Reflection.FieldInfo f = o.GetType().GetField("_dirMonSubdirs", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.IgnoreCase); object monitor = f.GetValue(o); System.Reflection.MethodInfo m = monitor.GetType().GetMethod("StopMonitoring", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); m.Invoke(monitor, new object[] { });
Using SharpZibLib over HTTPS SSL
I've been using SharpZipLib to zip up content and stream it to the user for some time now, and it's proved very reliable, robust and easy to use.
I did however recently have a problem that turned out to be IE-specific, and only when streaming to an SSL encrypted stream. Instead of a downloaded file, users would see the this error.
"Internet Explorer cannot download download from xxxxxxxxx
Internet Explorer was not able to open this Internet site. The requested site is either unavailable or cannot be found. Please try again later."
The solution turned out to be simple. Prior to setting other properties (such as AddHeader) you need to clear the Response object like so:
And so now my zip and download routine looks like this:
I did however recently have a problem that turned out to be IE-specific, and only when streaming to an SSL encrypted stream. Instead of a downloaded file, users would see the this error.
"Internet Explorer cannot download download from xxxxxxxxx
Internet Explorer was not able to open this Internet site. The requested site is either unavailable or cannot be found. Please try again later."
The solution turned out to be simple. Prior to setting other properties (such as AddHeader) you need to clear the Response object like so:
Response.Clear() Response.ClearHeaders()
And so now my zip and download routine looks like this:
'''''' zips up any file you send it and initiates a download ''' Public Sub ZipAndDownload(ByVal strPath As String, ByVal strFileName As String) Response.Clear() Response.ClearHeaders() Response.ContentType = "application/zip" Response.AddHeader("Content-Disposition", "inline; filename=" & strFileName & ".zip") ' FastZip - zip all the file and folders ' and stream it through the Response OutputStream Dim fz As New ICSharpCode.SharpZipLib.Zip.FastZip() fz.CreateZip(HttpContext.Current.Response.OutputStream, strPath, True, Nothing, Nothing) End Sub
Wednesday, 21 April 2010
Redirect all visits to HTTPS
Today I implemented HTTPS for a site after it had already been running for some time over normal HTTP. I had to redirect all incoming traffic to its HTTPS equivalent, honouring the full path and parameters. For instance, an incoming visit to http://www.myshop.com/products.aspx?widget=1234 needed to seamlessly become https://www.myshop.com/products.apsx?widget=1234 .
I added this to the masterpage and all seems sweet:
I also more recently had to do this in C# for a site using URL rewriting. This is how it looks:
I added this to the masterpage and all seems sweet:
Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender If Request.IsSecureConnection = False And _ Not Request.Url.Host.Contains("localhost") Then Response.Redirect(Request.Url.AbsoluteUri.Replace("http://", "https://")) End If End Sub
I also more recently had to do this in C# for a site using URL rewriting. This is how it looks:
Response.Redirect(Request.Url.Scheme.Replace("http", "https") + "://" + Request.Url.Authority + Request.RawUrl);
Monday, 12 April 2010
Evaluating the speed of your site
Here are some free tools that you can use to evaluate the speed of your site:
- Page Speed, an open source Firefox/Firebug add-on that evaluates the performance of web pages and gives suggestions for improvement.
- YSlow, a free tool from Yahoo! that suggests ways to improve website speed.
- WebPagetest shows a waterfall view of your pages' load performance plus an optimization checklist.
- In Webmaster Tools, Labs > Site Performance shows the speed of your website as experienced by users around the world.
Friday, 9 April 2010
Form submission and URL rewriting
If you're using URL rewriting you need to prevent the real URL from displaying in the browser when a form is submitted. To do this you need to tell the form what it should be doing by placing this in your page load event, or better still in your masterpage page load event.
if ( !String.IsNullOrEmpty(HttpContext.Current.Request.RawUrl )) { form1.Action = HttpContext.Current.Request.RawUrl; }
Wednesday, 31 March 2010
One way to trigger a restart of your ASP.NET web application
Last week I built some code that dynamically published new URL rewrite rules into a file included into the web.config file of a .NET web app/site. It was done using classic ASP as it was part of a client's in-house CMS, and this part of the CMS enabled their end user to add their own friendly URLs to the site.
It became apparent early on that editing this included file automatically restarted the whole app, which was an undesirable situation given that customer sessions would be lost. My solution was to make use of the restartOnExternalChanges attribute of the section element in the web.config file that referred to the Intelligencia UrlRewriter:
With the right permissions set, the ASP CMS could make a simple edit to this new include and automatically trigger a restart.
Of course, we could have just edited the web.config directly to trigger a restart, but relaxing the permissions to achieve this just didn't seem right.
It became apparent early on that editing this included file automatically restarted the whole app, which was an undesirable situation given that customer sessions would be lost. My solution was to make use of the restartOnExternalChanges attribute of the section element in the web.config file that referred to the Intelligencia UrlRewriter:
<section name="rewriter" requirepermission="false" restartonexternalchanges="false" type="Intelligencia.UrlRewriter.Configuration.RewriterConfigurationSectionHandler, Intelligencia.UrlRewriter">This meant that any edits to the included file wouldn't trigger a restart. But they also wouldn't be recognised until a restart. So then I had to give the user a way of restarting the app when they wanted to. So this time I used a similar entry in the web.config but with a contrary restartOnExternalChanges attribute setting:
<section name="rewriterRestarter" requirepermission="false" restartonexternalchanges="true" type="XmlConfigurator.XmlConfigurator, XmlConfigurator">And later in the file:
<rewriterRestarter configsource="Config\urlrewriterRestarter.config">
With the right permissions set, the ASP CMS could make a simple edit to this new include and automatically trigger a restart.
Of course, we could have just edited the web.config directly to trigger a restart, but relaxing the permissions to achieve this just didn't seem right.
Tuesday, 23 March 2010
Automatic stored procedure generation using Visual Studio
I was recently working in classic ASP using a client's in-house content management system. I had worked on this before and recalled the production of the stored procedures to be one of the most laborious parts unless some third-party tools like Code Author were used.
I wondered if there was a way of generating stored procedures using Visual Studio, and sure enough there is....
Under Add new item select Dataset, and name it whatever you want. A new .xsd window will appear. Right click in this and choose Add > TableAdapter. In the next window point to your database.
And then there's the important bit:
I wondered if there was a way of generating stored procedures using Visual Studio, and sure enough there is....
Under Add new item select Dataset, and name it whatever you want. A new .xsd window will appear. Right click in this and choose Add > TableAdapter. In the next window point to your database.
And then there's the important bit:
Select Create new stored procedures. In the next window insert a 'SELECT * FROM MyTable' statement and click Next. Then you can name the Select, Insert, Update and Delete sprocs. At this point I chose Preview SQL Script which allowed me to cut and paste the generation code into SQL Server Management Studio. You could of course continue with the process and allow VS to do the generation for you.
At the end, delete the .xsd file as you don't need it.
Friday, 5 March 2010
Intelligencia URL rewriter with IIS6 - enable wildcard mapping
This is one thing I always forget to do, and then forget how to do. Well not any more, coz it's blogged!
To get the Intelligencia URL rewriter to work on your site you need to enable wildcard mapping for the site in IIS6. In IIS Manager go to your website, right click on Properties, go to the Home Directory tab, and then the 'Configuration' button near the bottom. In the bottom box of the next window insert the aspnet_isapi.dll file, which normally for me is found here:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll
And for some reason, in the Add/Edit window I always need to uncheck 'Verify that file exists' to make it work. That's it then. Simples :)
To get the Intelligencia URL rewriter to work on your site you need to enable wildcard mapping for the site in IIS6. In IIS Manager go to your website, right click on Properties, go to the Home Directory tab, and then the 'Configuration' button near the bottom. In the bottom box of the next window insert the aspnet_isapi.dll file, which normally for me is found here:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll
And for some reason, in the Add/Edit window I always need to uncheck 'Verify that file exists' to make it work. That's it then. Simples :)

Tuesday, 23 February 2010
Programmatically log in a user, or emulate a user logging in
If you need to log a user on programmatically, that is with no input of password, you can do the following just using their user name:
FormsAuthentication.SetAuthCookie(UserName, True) Response.Redirect("/somewhere_suitable")I recently used this to allow a system administrator to login to any user's account as that user by clicking on a button from a list of users. This must be a pretty common thing to do so here's the whole bit of code for the button event:
Protected Sub UsersList_ButtonPress(ByVal sender As Object, ByVal e As ListViewCommandEventArgs) Handles UsersList.ItemCommand If e.CommandName = "Login" Then Dim userID As Guid = New Guid(e.CommandArgument.ToString) Dim user As MembershipUser = Membership.GetUser(userID) FormsAuthentication.SetAuthCookie(user.UserName, True) Response.Redirect("/somewhere_suitable") End If End SubAnd here's the designer code for the button in the itemtemplate of the listview:
<td> <asp:Button ID="LoginButton" runat="server" CommandArgument='<%# Eval("UserID")%>' CommandName="Login" Text="Login" OnClientClick="return confirm('Are you sure you want to login as this user?');" /> </td>You could of course just send the username as an argument directly from the list, but I didn't do this as the userID just suited some other stuff I've got going on there too!
Thursday, 18 February 2010
SQL convert datetime to string
I found this posted on another site. It's Really Useful, so I though I'd replicate it here for next time.
0 | Feb 22 2006 4:26PM | CONVERT(CHAR(19), CURRENT_TIMESTAMP, 0) |
1 | 02/22/06 | CONVERT(CHAR(8), CURRENT_TIMESTAMP, 1) |
2 | 06.02.22 | CONVERT(CHAR(8), CURRENT_TIMESTAMP, 2) |
3 | 22/02/06 | CONVERT(CHAR(8), CURRENT_TIMESTAMP, 3) |
4 | 22.02.06 | CONVERT(CHAR(8), CURRENT_TIMESTAMP, 4) |
5 | 22-02-06 | CONVERT(CHAR(8), CURRENT_TIMESTAMP, 5) |
6 | 22 Feb 06 | CONVERT(CHAR(9), CURRENT_TIMESTAMP, 6) |
7 | Feb 22, 06 | CONVERT(CHAR(10), CURRENT_TIMESTAMP, 7) |
8 | 16:26:08 | CONVERT(CHAR(8), CURRENT_TIMESTAMP, 8) |
9 | Feb 22 2006 4:26:08:020PM | CONVERT(CHAR(26), CURRENT_TIMESTAMP, 9) |
10 | 02-22-06 | CONVERT(CHAR(8), CURRENT_TIMESTAMP, 10) |
11 | 06/02/22 | CONVERT(CHAR(8), CURRENT_TIMESTAMP, 11) |
12 | 060222 | CONVERT(CHAR(6), CURRENT_TIMESTAMP, 12) |
13 | 22 Feb 2006 16:26:08:020 | CONVERT(CHAR(24), CURRENT_TIMESTAMP, 13) |
14 | 16:26:08:037 | CONVERT(CHAR(12), CURRENT_TIMESTAMP, 14) |
20 | 2006-02-22 16:26:08 | CONVERT(CHAR(19), CURRENT_TIMESTAMP, 20) |
21 | 2006-02-22 16:26:08.037 | CONVERT(CHAR(23), CURRENT_TIMESTAMP, 21) |
22 | 02/22/06 4:26:08 PM | CONVERT(CHAR(20), CURRENT_TIMESTAMP, 22) |
23 | 2006-02-22 | CONVERT(CHAR(10), CURRENT_TIMESTAMP, 23) |
24 | 16:26:08 | CONVERT(CHAR(8), CURRENT_TIMESTAMP, 24) |
25 | 2006-02-22 16:26:08.037 | CONVERT(CHAR(23), CURRENT_TIMESTAMP, 25) |
100 | Feb 22 2006 4:26PM | CONVERT(CHAR(19), CURRENT_TIMESTAMP, 100) |
101 | 02/22/2006 | CONVERT(CHAR(10), CURRENT_TIMESTAMP, 101) |
102 | 2006.02.22 | CONVERT(CHAR(10), CURRENT_TIMESTAMP, 102) |
103 | 22/02/2006 | CONVERT(CHAR(10), CURRENT_TIMESTAMP, 103) |
104 | 22.02.2006 | CONVERT(CHAR(10), CURRENT_TIMESTAMP, 104) |
105 | 22-02-2006 | CONVERT(CHAR(10), CURRENT_TIMESTAMP, 105) |
106 | 22 Feb 2006 | CONVERT(CHAR(11), CURRENT_TIMESTAMP, 106) |
107 | Feb 22, 2006 | CONVERT(CHAR(12), CURRENT_TIMESTAMP, 107) |
108 | 16:26:08 | CONVERT(CHAR(8), CURRENT_TIMESTAMP, 108) |
109 | Feb 22 2006 4:26:08:067PM | CONVERT(CHAR(26), CURRENT_TIMESTAMP, 109) |
110 | 02-22-2006 | CONVERT(CHAR(10), CURRENT_TIMESTAMP, 110) |
111 | 2006/02/22 | CONVERT(CHAR(10), CURRENT_TIMESTAMP, 111) |
112 | 20060222 | CONVERT(CHAR(8), CURRENT_TIMESTAMP, 112) |
113 | 22 Feb 2006 16:26:08:067 | CONVERT(CHAR(24), CURRENT_TIMESTAMP, 113) |
114 | 16:26:08:067 | CONVERT(CHAR(12), CURRENT_TIMESTAMP, 114) |
120 | 2006-02-22 16:26:08 | CONVERT(CHAR(19), CURRENT_TIMESTAMP, 120) |
121 | 2006-02-22 16:26:08.080 | CONVERT(CHAR(23), CURRENT_TIMESTAMP, 121) |
126 | 2006-02-22T16:26:08.080 | CONVERT(CHAR(23), CURRENT_TIMESTAMP, 126) |
127 | 2006-02-22T16:26:08.080 | CONVERT(CHAR(23), CURRENT_TIMESTAMP, 127) |
130 | 24 ???? 1427 4:26:08:080PM | CONVERT(CHAR(32), CURRENT_TIMESTAMP, 130) |
131 | 24/01/1427 4:26:08:080PM | CONVERT(CHAR(25), CURRENT_TIMESTAMP, 131) |
Friday, 12 February 2010
Programmatically add a stylesheet reference
HtmlLink newStyleSheet = new HtmlLink(); newStyleSheet.Href = "css/your.css"; newStyleSheet.Attributes.Add("type", "text/css"); newStyleSheet.Attributes.Add("rel", "stylesheet"); Page.Header.Controls.Add(newStyleSheet);
Wednesday, 10 February 2010
Large .suo file causing Visual Studio to hang
Just when I needed it least Visual Studio decided to hang. I restarted it and sat for 10 minutes while it opened my project again. So I restarted the machine, and it did it again.
After a bit of investigation I found that my .suo file was 8.5MB (which is tiny compared to some reports), and renaming this (the safe equivalent of deleting) solved my problems. I lost a few preferences (I haven't fully established what yet, but I run pretty vanilla so there shouldn't be much) but it all works WAY faster than I've become accustomed to.
Perhaps there's a more official way of cleansing the .suo?
After a bit of investigation I found that my .suo file was 8.5MB (which is tiny compared to some reports), and renaming this (the safe equivalent of deleting) solved my problems. I lost a few preferences (I haven't fully established what yet, but I run pretty vanilla so there shouldn't be much) but it all works WAY faster than I've become accustomed to.
Perhaps there's a more official way of cleansing the .suo?
Tuesday, 9 February 2010
Installing ELMAH to log unhandled exceptions in asp.net application
ELMAH logs all your uncaptured errors. It's remarkably easy to implement - I followed the simple instructions on these posts here and here. The latter link has more detail but has a couple of typos in the web.config additions which will become obvious if you use it.
Having functionality like this at your fingertips is very reassuring!
Having functionality like this at your fingertips is very reassuring!
Tuesday, 2 February 2010
Using one stored procedure in another
Today I had to call a SPROC from another SPROC by sending it a parameter, storing the results in a temporary table, and then looping through the temp table. After some googling and tweaking I came up with this which seems to work a treat. I'm no SQL expert though!
--create temp table create table #temp ( idx int identity(1,1), field1 int, field2 int) -- put data into temp table using other SP insert into #temp (field1, field2) exec myOtherSproc @paramaterToSend -- loop through temp table declare @counter int set @counter = 1 while @counter < (select max(idx) from #temp) begin --do whatever you want here set @counter = @counter + 1 end DROP TABLE #temp
Tuesday, 26 January 2010
Formatting for currency
This will turn 20000 into £20,000.00:
String.Format("{0:C}", myValue)'myvalue' must be numeric. If it's a string, use Convert.ToDouble first.
Friday, 22 January 2010
"Object doesn't support this property or method" with theform.submit
In a recent post I described how easy it was to maintain scroll position for a user during a postback, by adding this to the page directive:
It took me a while to resolve. I found that I had a user control on the page with a button that had the property name="submit". Removing this resolved the problem.
MaintainScrollPositionOnPostback="true"This did cause me problem with one page where I implemented it. Only in Internet Explorer (other browsers seemed ok) did I get this javascript error:
Microsoft JScript runtime error: Object doesn't support this property or methodAnd it was referring "theform.submit"
It took me a while to resolve. I found that I had a user control on the page with a button that had the property name="submit". Removing this resolved the problem.
Monday, 18 January 2010
URL rewriting and multiple parameters
I'm using the Intelligencia URL rewriter and I needed to handle more than one parameter. This is my rewrite instruction in the web.config file:
SIFR flash replacement with AJAX update panel
If you have an ajax update panel only partially updating your page you'll find that the standard SIFR implementation doesn't work on any items in the update panel. To overcome this, you need to wrap the whole contents of sifr-config.js in a function. I called it callSIFR.
Then you need to write the call to this function to the client at the PreRender event from your master page.
Then you need to write the call to this function to the client at the PreRender event from your master page.
protected void Page_PreRender(object sender, EventArgs e) { ScriptManager.RegisterStartupScript(this, typeof(Page), "SIFRcall", "callSIFR();", true); }
Sunday, 17 January 2010
Maintaining user scroll position on postback
When your user is scrolled down on a 'tall' page and does something that evokes a postback, like submitting some form data, we often want to return to their scroll position after postback. This is a particularly common requirement when reporting validation failures to the user on a form submitted when we're using server-side validation rather than javascript.
ASP.net makes this incredibly easy for us. It's as simple as adding this to your page directive:
ASP.net makes this incredibly easy for us. It's as simple as adding this to your page directive:
MaintainScrollPositionOnPostback="true"Don't you just love it?
Wednesday, 13 January 2010
Passing a parameter/value from a host page to a user control
This goes in your control:
private String _ValueID; public String ValueID { get { return _ValueID; } set { _ValueID = value; } }And you can set the value in your host page either like this:
<uc2:SubNav ID="SubNav1" runat="server" ValueID="whatever" />or in your host code-behind like this:
SubNav1.ValueID = "whatever";
Thursday, 7 January 2010
Flushing the DNS cache
I've had one or two run-ins with unforeseen DNS caching. Today it reared its ugly head again when I moved a site I'm building to a new URL.
To clear the DNS cache on a windows machine, run this from the command prompt:
To clear the DNS cache on a windows machine, run this from the command prompt:
ipconfig /flushdnsOn Vista, you'll have to launch the command prompt by right-clicking and selecting 'Run as Administrator'.
Tuesday, 5 January 2010
Configuring SMTP in web.config
<system.net> <mailSettings> <smtp from="fromuser@fromaddress.net"> <network host="smtp.myhost.com" password="abracadabra" userName="myusername"/> </smtp> </mailSettings> </system.net>
Directory.Delete results in Session_End
I spent ages trying to work out why I was being logged out the web app I was building. Well it turns out that it was happening at the point where I was deleting a directory no longer needed for user uploads.
At this point it seems that a recompile is triggered, and therefore the session is lost. Now there's one to look out for!
At this point it seems that a recompile is triggered, and therefore the session is lost. Now there's one to look out for!
Sunday, 3 January 2010
Pagination - rounding up my number of pages
I had to manually code a bit of pagination in C# today. To work out how many pages there are in total I started to look into testing for an integer when dividing the results by the results-per-page. Instead I used this simple bit of maths:
numberOfPages = (totalResults + resultsPerPage - 1)/resultsPerPage;And, if you're interested, here's the complicated way of doing it:
pageCount = int.Parse(Math.Ceiling(Decimal.Divide(TotalCount, PageSize))); if (pageCount == 0) pageCount = 1;
Subscribe to:
Posts (Atom)