Mark Smith

ASP.NET, SQL Server, HTML, CSS and other random thoughts!

October 2007 - Posts

Online storage with Windows Live

I've just come across the Windows Live SkyDrive beta which is basically an online storage facility that is driven by your Windows Live ID. Some of the features that is offers are:

  • 1 GB of free online storage.
  • Create personal, shared, and public folders -- you decide who has access to each folder.
  • Your personal folders are password-protected with your Windows Live ID, so only you have access.
  • When you create a shared folder, the friends you're sharing with need to sign in with their own Windows Live ID and password.
  • Shared folders make it easy to collaborate with coworkers or classmates.
  • You decide how much control each person has over each shared folder. Some can just read what's there: others can add and delete files.
  • With public folders, anyone on the Internet can view your files, but they can't change them.
  • Want to show your public files to others? Just send them a link! Each folder and file has its own web address.

I imagine this could come in quite useful, so click here to sign up.

SQL Server 2005 - Missing Ranges

I recently had a situation where I needed to highlight the ids in a given range which were out of sequence and not part of a range (i.e. 1,2,3,4,6, would show that 5 was missing). Fortunately, I found that this was quite easy to do with Common Table Expressions (CTE) in SQL Server 2005.

Firstly, to demonstrate this functionality, I'll create a table variable and populate it with some sample data. I can then use my CTE (along with an OVER clause to add a row number) to join the table to itself and highlight the "start" and "end" of the missing rows.

Here's the example I came up with for SQL Server 2005:

DECLARE @Temp TABLE (IDName int)

INSERT INTO @Temp VALUES(1);
INSERT INTO @Temp VALUES(2);

INSERT INTO @Temp VALUES(3);
INSERT INTO @Temp VALUES(6);
INSERT INTO @Temp VALUES(7);
INSERT INTO @Temp VALUES(9);
INSERT INTO @Temp VALUES(11);
INSERT INTO @Temp VALUES(12);
INSERT INTO @Temp VALUES(13);

WITH rangesCTE(rowNum, IDName) AS 
(
SELECT ROW_NUMBER() OVER(ORDER BY IDName)
AS RowNum, IDName FROM @Temp
)
SELECT a.IDName+1 AS MissingStart,
b.IDName-1
AS MissingEnd
FROM rangesCTE a INNER JOIN rangesCTE b
ON a.RowNum = b.RowNum - 1
WHERE a.IDName-(b.IDName-1) < 0

Which will then generate the following output:

MissingStart MissingEnd
4                  5
8                  8
10                10

I'd be interested to see if anyone has any other alternative methods to do this for both SQL Server 2005 and SQL Server 2000

 

Posted: Oct 22 2007, 02:09 PM by ca8msm | with 1 comment(s)
Filed under:
XHTML Strict Validation

I often use a XHTML Strict doctype on my websites and try to get them 100% valid every time (and I also put a link to the w3 validator service on each page). However, even though I do this the validator service often complains that my code isn't valid even though I know it is. The reason for this is that ASP.NET sees the request from w3 as coming from a "down-level" browser and as such sends different (and invalid for this doctype) XHMTL.

To get around this problem, I use a .browser file specifically for this service. To add it to your project you need to create an ASP.NET folder in your project called "App_Browsers". Then, inside that folder create a file named"w3cvalidator.browser" and add the following code:

 

<browsers> 
<!-- 
Browser capability file for the w3c validator 
sample UA: "W3C_Validator/1.305.2.148 libwww-perl/5.803" 
-->
 

    <browser id="w3cValidator" parentID="default"> 

        <identification> 
            <userAgent match="^W3C_Validator" /> 
        </identification> 
       
        <capture> 
            <userAgent match="^W3C_Validator/(?'version'(?'major'\d+)(?'minor'\.\d+)\w*).*" /> 
        </capture> 

        <capabilities> 
             <capability name="browser" value="w3cValidator" /> 
             <capability name="majorversion" value="${major}" /> 
             <capability name="minorversion" value="${minor}" /> 
             <capability name="version" value="${version}" /> 
             <capability name="w3cdomversion" value="1.0" /> 
             <capability name="xml" value="true" /> 
             <capability name="tagWriter" value="System.Web.UI.HtmlTextWriter" /> 
         </capabilities> 
    </browser> 

</browsers> 

 


Now, when the w3 service requests your page, it won't be treated as a low level browser and the correct HTML will be rendered so that your page will validate (assuming you haven't made any errors!).

Imports Alias

You know those things where you just think "How didn't I know that?!", well I got one today. I only just found out (laugh at me if you want!) that you can add an alias to an "Imports" statement. So, instead of typing:

Imports System.Data

I can type:

Imports d = System.Data

and refer to it as "d". Here's what it would look like in Visual Studio:

Alias 

Thanks to Christiaan Baes for the tip!
 

Redirecting the user when the session ends

I've noticed that a lot of banking websites redirect you back to their main page (or a page informing you what has happened) after a certain amount of inactivity. I think this is actually quite good for the user's experience as if I've left a site open for a while, usually I have to make another request before the site tells me that my session has ended and asks me to login again.

There's a few ways that this could be implemented in ASP.NET and some of the most common are probably accomplished by using a javascript redirect or adding a meta tag to the page. As I always use Master Pages in my applications, the approach I've started to use is to add a header to the response in the page load event so that any page that uses this Master Page will always have this header. It's quite simple to implement and looks to be quite efficient:

 

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not Page.IsPostBack Then
           
Response.AppendHeader("Refresh", (Session.Timeout * 60) + 5 & "; Url=SessionEnded.aspx")
        End If
   
End Sub

You can decide whether to have a separate page that is responsible for showing a message to the user, or you could just redirect them back to the login page if you wanted.

CSS - Table design

I think I've used GridViews in pretty much every application I've built using ASP.NET, and as such they are something that I always end up styling via CSS. They render as a table which makes it easy to apply the same style right across your application to keep a consistent lok throughout your site.

I recently stumbled across a site at http://icant.co.uk/csstablegallery which has a list of ready made CSS designs for tables which you can freely download. There's some good designs on there and it's also a place where you can submit your own designs, so if you've got any CSS that you use add it to the list for others to see and use.

Posted: Oct 07 2007, 04:05 PM by ca8msm | with 5 comment(s)
Filed under: ,
Convert C# and VB.NET

If, like me, you post pieces of code for others to view, I imagine you'll often do so in the language of your choice (and more than likely it will be C# or VB.NET). However, for some beginners it's often quite hard to grasp these examples if they are written in a language you are not familiar with.

I had this scenario when one of the visitors to my site wanted to see an example in C#, but I had written the article using VB.BET. It wasn't too hard for me to convert it, but it did mean that I had to write the example twice. I looked around for an automatic converter that would help me do this, and by far the best one I found was the one from Carlos Aguilar Mares. His Code Translator allows you to enter some in code in either C# or VB.NET and it will output the code in the opposite langauge. The beauty of how he coded the translator is that it is done via an "ashx" handler. After speaking to Carlos, I decided that I'd try to implement this automatically on my site my calling his handler directly (you can see an example of it in action here).

To call his handler, I simply had to make a httpWebRequest, pass in the "from" and "to" language, let his handler do it's magic and then read the response by using httpWebResponse. I've broken the way I do it down into a simple function just for demonstration purposes (my site uses a few Regular Expressions in case I have more than one example on the page) but in it's basic form, this is how it can be done:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default1.aspx.vb" Inherits="Default1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<
head id="Head1" runat="server">
   
<title>Untitled Page</title>
</
head>
<
body>
    <form id="form1" runat="server">
   
<div>
       
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
   
</div>
   
</form>
</
body>
</
html>

 

Imports System.IO
Imports System.Net
Imports
System.Text

Partial Class Default1

    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Label1.Text = CarlosAGConvertVBNETToCSharp("Dim s As String")
    End Sub

 

    Public Function CarlosAGConvertVBNETToCSharp(ByVal Code As String) As String
       
Try

            Dim strURL As String = ""
           
Dim strPostData As New StringBuilder
            Dim strResult As String
           
Dim wbrqLogin As HttpWebRequest
            Dim wbrsLogin As HttpWebResponse
            Dim swLogin As StreamWriter
            Dim srLogin As StreamReader
 
            
' Set the URL to post to and the login info to post
            strURL = "http://www.carlosag.net/Tools/CodeTranslator/Translate.ashx"

            ' Create the string to send to the web service
            strPostData.Append("Code=")
            strPostData.Append(HttpContext.Current.Server.UrlEncode(Code))
            strPostData.Append("&Language=VB&DestinationLanguage=C#&Colorize=0")
 
           
' Create the web request
           
wbrqLogin = WebRequest.Create(strURL)
            wbrqLogin.Method = "POST"
           
wbrqLogin.ContentLength = strPostData.Length
            wbrqLogin.ContentType = "application/x-www-form-urlencoded"
           
wbrqLogin.CookieContainer = New CookieContainer
 
           
' Post the data
         
  swLogin = New StreamWriter(wbrqLogin.GetRequestStream)
            swLogin.Write(strPostData.ToString)
            swLogin.Close()
 
           
' Read the returned data
           
wbrsLogin = wbrqLogin.GetResponse
            srLogin = New StreamReader(wbrsLogin.GetResponseStream)
            strResult &= srLogin.ReadToEnd.Trim
            srLogin.Close()
 
            Return strResult
 
        Catch ex As Exception
            Return "Sorry, an error occurred. You can try manually converting your code by going to <a href=""http://www.carlosag.net/Tools/CodeTranslator/Default.aspx"">http://www.carlosag.net</a>."

         End Try

     End Function

End Class

Posted: Oct 06 2007, 12:12 PM by ca8msm | with 3 comment(s)
Filed under: , , ,
Welcome to my blog!

Hi,

My name is Mark Smith, and I'm an ASP.NET developer from the North East of England. I'm the author and creator of the site http://aspnetlibrary.com, an online resource for professional ASP.NET developers. I also post in the Tek-Tips ASP.NET Forums, the ASP.NET Forums and occasionally the ASP.NET Newsgroups and I use the username ca8msm so some of you may have already bumped into me.

After a kind invite from Joe Stagner, I'm up and running with this blog so hopefully I'll be seeing some of you here in the future. Please leave me a comment if you want to say hello, and feel free to point out your own blogs so I can have a read of what you've written recently.

Mark

Posted: Oct 03 2007, 02:45 PM by ca8msm | with 2 comment(s)
Filed under:
More Posts