# Wednesday, 21 January 2015

Likely somewhere this year ASP.NET 5, or vNext as it’s been called in the past, will launch. From all we hear each time it’s going to be a major shift again, likely as big as the shift from classic ASP to ASP.NET back in 2002. To get to know what’s going to change the people from the ASP.NET team made a series of screencasts available for us. You can watch them at your convenience at Microsoft Virtual Academy.

Go sit in your comfy chair and take some time to watch it at http://www.microsoftvirtualacademy.com/training-courses/what-s-new-with-asp-net-5.

Grz, Kris.

Wednesday, 21 January 2015 17:12:00 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, 04 April 2013
# Wednesday, 27 March 2013

I got word the ASP.NET MVC hands on labs are available online also. So if you want to get to know more or just want to get your hands dirty for the first time with this great technology stack simply navigate to http://www.asp.net/mvc/tutorials/hands-on-labs.

Grz, Kris.

Wednesday, 27 March 2013 10:13:22 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Sunday, 01 July 2012

Today is a bit of a special day for me. I started exactly 10 years ago on a professional level with ASP.NET. I has given me quite an interesting journey and quite a lot of interesting projects to work on with other dedicated people with whom I could exchange views and insights.

Another mark is that I started the same day, thanks to the mentioning of a consultant who told me about its existence, I started on the ASP.NET forums. In the beginning only either lurking for information or simply to ask questions when I got stuck with something. I remember that after a while I was looking through some posts and noticed I knew the answer to one of them. I replied and a got a huge thank you!! back from the person who started the thread. Since then I’ve been trying to answer more and more question with the end result being that after 10 years I’m the number one recognition points holder: http://www.asp.net/community/recognition/hall-of-fame.

It’s been quite a remarkable and exciting time during those years and I loved it! The coming years will I not only continue to invest in ASP.NET, the forums, the (Belgian) community but also in something that inspires me and in which I believe: cloud computing, so be sure to see more blog posts about that topic as well around here.

Grz, Kris.

Sunday, 01 July 2012 19:50:05 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, 02 April 2012

I just noticed that the ASP.NET website has gotten a small but very interesting upgrade. Until recently it was somewhat hard to find the information about Web API and Single Page Applications (SPA). As the menu was already pretty crowded the site now has an extra menu called Solutions. From there on one can easily find all the major technology stacks with references to tutorials, videos, samples, …

ASPNETSiteSolutions

If you want direct access, go ahead:

FRAMEWORKS

Grz, Kris.

Monday, 02 April 2012 19:44:51 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
# Sunday, 08 January 2012

If you provide a way for your user to make an appointment it’s always a good idea to provide a reminder mechanism for him or her. A nice way to do this is to send a mail. But a mail alone is sometimes not enough and Microsoft Outlook users for example would rather love to see a .ics appointment attached.

The System.Net.Mail namespace provides the needed functionality to get this recipe cooking in no time and will taste great afterwards.

First part of the recipe are the helper classes which hold the functionality for making up the ics content and sending a mail depending on provided input.

The Mailing class:

using System.Net.Mail;
using System.Web.Configuration;

namespace IcsAsMailAttachment.Controllers
{
    public class Mailing
    {
        public void SendMail(string from, string to, string subject, string body, Attachment attachment)
        {
            using (MailMessage mailClient = new MailMessage(from, to, subject, body))
            {
                mailClient.Attachments.Add(attachment);
                mailClient.IsBodyHtml = true;

                SmtpClient smtp = new SmtpClient(WebConfigurationManager.AppSettings["mailserver"]);

                smtp.Send(mailClient);
            }
        }
    }
}

This class does the actual sending. The mailserver, on line 15, is retrieved from the web.config file appSettings section. This makes it easy for the site admin to change the mail server without having to adjust and redeploy the code (saving time and money).

The Appointment class:

using System;
using System.Text;

namespace IcsAsMailAttachment.Controllers
{
    public class Appointment
    {
        private string GetFormatedDate(DateTime date)
        {
             return string.Format("{0:00}{1:00}{2:00}", date.Year, date.Month, date.Day);
        }

        private string GetFormattedTime(DateTime dateTime)
        {
            return string.Format("T{0:00}{1:00}{2:00}", dateTime.Hour, dateTime.Minute, dateTime.Second);
        }

        public string CreateIcs(string subject, string location, DateTime startDate, DateTime endDate)
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("BEGIN:VCALENDAR");
            sb.AppendLine("VERSION:2.0");
            sb.AppendLine("PRODID:-//hacksw/handcal//NONSGML v1.0//EN");
            sb.AppendLine("BEGIN:VEVENT");

            string startDay = string.Format("VALUE=DATE:{0}{1}",
                GetFormatedDate(startDate), GetFormattedTime(startDate));

            string endDay = string.Format("VALUE=DATE:{0}{1}", 
                GetFormatedDate(endDate), GetFormattedTime(endDate));

            sb.AppendLine("DTSTART;" + startDay);
            sb.AppendLine("DTEND;" + endDay);
            sb.AppendLine("SUMMARY:" + subject);
            sb.AppendLine("LOCATION:" + location);
            sb.AppendLine("END:VEVENT");
            sb.AppendLine("END:VCALENDAR");

            return sb.ToString();
        }
    }
}

The Appointment class does the heavy lifting of generating the string needed for the ics markup. Two helper methods are put in place to get a nicely formatted Date and Time string.

The SendMailController class:

using System;
using System.IO;
using System.Net.Mail;
using System.Text;
using System.Web.Mvc;

namespace IcsAsMailAttachment.Controllers
{
    public class SendMailController : Controller
    {
        //
        // GET: /SendMail/

        public ActionResult Index()
        {
            string ics = new Appointment().CreateIcs("A great meeting to attend!", "In the cloud",
                new DateTime(2012, 2, 3, 18, 0, 0), new DateTime(2012, 2, 3, 22, 15, 0));

            MemoryStream ms = new MemoryStream();
            UTF8Encoding enc = new UTF8Encoding();
            byte[] arrBytData = enc.GetBytes(ics);
            ms.Write(arrBytData, 0, arrBytData.Length);
            ms.Position = 0;

            // Be sure to give the name a .ics extension here, otherwise it will not work.
            Attachment attachment = new Attachment(ms, "Appointment.ics");

            new Mailing().SendMail("from@contoso.com", "to@ymca.com", 
                "The subject", "<strong>Welcome to the cloud!</strong>", attachment);

            return View();
        }
    }
}

The SendMailController class, I tested this in an ASP.NET MVC 3 web application, creates a new ICS appointment on line 16. For being able to send the attachment without first having to save it to disk we create a MemoryStream instance on line 19 and transform our ics to a byte array so that we can pass it along in the constructor of the Attachment class on line 26. The highlight is on line 26 as you will need to provide the .ics extension in the name there.

When testing this you might want to send it directly via a mail server. However this might get the sys admin at your company upset or perhaps gets the sender email address that you use blacklisted. For this purpose you can tell ASP.NET to drop the generated mail on disk instead. Just be sure to turn that off when you are deploying to a live production as otherwise nobody will receive your emails!

Email settings in web.config:

<?xml version="1.0"?>

<configuration>
  <system.net>
    <mailSettings>
      <smtp deliveryMethod="SpecifiedPickupDirectory">
        <specifiedPickupDirectory pickupDirectoryLocation="C:\temp\mails" />
      </smtp>
    </mailSettings>
  </system.net>

 

The results:

Once the mail has been sent, it will appear in the designated pickup directory location as specified in the web.config.

Pickup folder for ASP.NET mails

Double clicking on the .eml file opens it up in in the associated application, for me that is Outlook.

The email that was sent

There you see the Appointment.ics file. Remember the name we gave on line 26 in the SendMailController? Yes, that is exactly the name, and correct extension, that was provided. Double click the ics file and you can see the appointment.

The ICS file opened ready for adding it to the agenda in Outlook

The date and times come from the parameters passed in the SendMailController class on line 16 and 17.

As you can see, it is quite easy to set this up with just a bit of code. Providing the opportunity to add an appointment directly to the agenda of the interested user is a great benefit. They don’t have to create one themselves, enter in the dates and hours, possibly making mistakes when doing so, … Make it easy for your customers to keep their agenda up to date in a quick and easy way and they’ll love it.

Grz, Kris.

Sunday, 08 January 2012 14:51:10 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Thursday, 18 August 2011

results in increasing my post count on the ASP.NET forums a lot it seems:

last30days

Yep, that’s me on top Smile.

Grz, Kris.

Thursday, 18 August 2011 19:55:20 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, 04 March 2011

Last year the ASP.NET team released a Sprite and Image Optimization Toolkit which allows ASP.NET web sites to be optimized for higher performance where applicable by merging images together and lowering the number of request the browser must make to serve a page. Microsoft just released a new version of the toolkit today with many enhancements including support for MVC 3 and Web Pages 1. Here is a short list of the updates:

  • Updated to support Web Pages 1 and MVC 3 (still support Web Forms as well)
  • No module registration required for machines with Web Pages 1 / MVC 3 installed, dropping assembly in BIN just works
  • Automatic namespace registration in Web Pages, dropping in BIN automatically registers the namespace
  • Fully updated documentation
  • Common helper between Web Pages and MVC 3
  • Many improvements and bug fixes since the last release

You can grab the new release via:

NuGet: http://www.nuget.org/Packages/Search?packageType=Packages&searchCategory=All+Categories&searchTerm=sprite

CodePlex: http://aspnet.codeplex.com/releases/view/61896

Grz, Kris.

Friday, 04 March 2011 00:48:00 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, 20 November 2010

ASP.NET provides developers with some very handy controls like a Treeview or a Menu control for displaying data coming from a sitemap file. Though a very common scenario sometimes these are simply too heavy weight to be used and on the ASP.NET forums I simply suggest an alternative by using a simple DataList control. For future reference to point out on the forums I decided to write this little code snippet:

The sitemap file:

<?xml version="1.0" encoding="utf-8" ?>
<
siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0"
>
    <
siteMapNode url="" title=""  description=""
>
        <
siteMapNode url="http://www.microsoft.com" title="Microsoft"  description=""
/>
        <
siteMapNode url="http://blog.krisvandermast.com" title="Kris' blog"  description=""
/>
    </
siteMapNode
>
</
siteMap
>

The markup of a simple ASP.NET webform:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %>

<!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 runat="server">
    <title></title>
    <style type="text/css">
   
    li {
        border-left:2px solid #000;
        list-style:none;
        margin-right:10px;
        padding-left:10px;
        float:left;
    }
   
    </style
>
</
head
>
<
body>
    <form id="form1" runat="server">
    <div>
        <asp:SiteMapDataSource runat="server" ID="smd" ShowStartingNode="false" />
        <asp:DataList runat="server" ID="menu" DataSourceID="smd" RepeatDirection="Horizontal" RepeatLayout="Flow">
            <HeaderTemplate>
                <ul>
            </HeaderTemplate>
            <ItemTemplate>
                <li>
                    <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# Eval("Url") %>' 
                        Text='<%# Eval("Title") %>'></asp:HyperLink>
                </li>
            </ItemTemplate>
            <FooterTemplate>
                </ul>
            </FooterTemplate>
        </asp:DataList>
    </div>
    </form
>
</
body
>
</
html
>

The output:

datalist_sitemap_menu

The benefits of using the DataList control is that it’s versatile, lightweight, easy to program but also that it supports item selection. That Could be quite an asset when a page wants to set the SelectedIndex from codebehind to have selection in the menu itself. Note the extra added SelectedItemTemplate and the added class=”selected” in the <li> element. This will, thanks to the css class, make the background color look red and as such a selected menu item.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %>

<%@ Register Assembly="WebApplication1" Namespace="WebApplication1" TagPrefix="cc1" %>
<!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 runat="server">
    <title></title>
    <style type="text/css">
        li {
            border-left: 2px solid #000;
            list-style: none;
            padding-right: 10px;
            padding-left: 10px;
            float: left;
        }
       
        .selected {
            background-color:Red;
        }
    </style
>
</
head
>
<
body>
    <form id="form1" runat="server">
    <div>
        <asp:SiteMapDataSource runat="server" ID="smd" ShowStartingNode="false" />
        <asp:DataList runat="server" ID="menu" DataSourceID="smd" RepeatDirection="Horizontal"
            RepeatLayout="Flow">
            <HeaderTemplate>
                <ul>
            </HeaderTemplate>
            <ItemTemplate>
                <li>
                    <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# Eval("Url") %>' 
                        Text='<%# Eval("Title") %>'></asp:HyperLink>
                </li>
            </ItemTemplate>
            <SelectedItemTemplate>
               <li class="selected">
                    <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# Eval("Url") %>' 
                        Text='<%# Eval("Title") %>'></asp:HyperLink>
                </li>
            </SelectedItemTemplate>
            <FooterTemplate>
                </ul>
            </FooterTemplate>
        </asp:DataList>
    </div>
    </form
>
</
body
>
</
html
>

And in the Page_Load event:

protected void Page_Load(object sender, EventArgs e)
{
    menu.SelectedIndex = 1;
}

This outputs the following:

datalist_sitemap_menu2

Another option, which generates less span elements would be to use a Repeater control instead:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %>

<%@ Register assembly="WebApplication1" namespace="WebApplication1" tagprefix="cc1" %>

<!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 runat="server">
    <title></title>
    <style type="text/css">
   
    li {
        border-left:2px solid #000;
        list-style:none;
        margin-right:10px;
        padding-left:10px;
        float:left;
    }
   
    </style
>
</
head
>
<
body>
    <form id="form1" runat="server">
    <div>
        <asp:SiteMapDataSource runat="server" ID="smd" ShowStartingNode="false" />
        <div id="menu">
            <asp:Repeater runat="server" ID="rpt" DataSourceID="smd">
                <HeaderTemplate>
                    <ul>
                </HeaderTemplate>
                <ItemTemplate>
                    <li>
                        <asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%# Eval("Url") %>' 
                            Text='<%# Eval("Title") %>'></asp:HyperLink>
                    </li>
                </ItemTemplate>
                <FooterTemplate>
                    </ul>
                </FooterTemplate>
            </asp:Repeater>
        </div>
    </div>
    </form
>
</
body
>
</
html
>

Grz, Kris.

ASP.NET | CSS | Datalist | Sitemap
Saturday, 20 November 2010 20:20:25 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, 18 September 2010

A couple of days ago I became aware of the following article: Security Hack Exposes Forms Authentication in ASP.NET. That never sounds good and Microsoft swiftly crafted a workaround to mitigate the attack. It simply consists of changing your web.config and adding a file with some piece of code in it.

For ASP.NET 1.0 to 3.5 use this adjustment:

<configuration>        
   <system.web>
      <customErrors mode="On" defaultRedirect="~/error.html" />
   </system.web>       
</configuration>

For ASP.NET 3.5SP1 and 4.0 use this adjustment:

<configuration>
   <system.web>
     <customErrors mode="On" redirectMode="ResponseRewrite" defaultRedirect="~/error.aspx" />
   </system.web>
</configuration>

You’ll also need to put that error.aspx page on your server with the following content:

VB version:

<%@ Page Language="VB" AutoEventWireup="true" %>
<%@ Import Namespace="System.Security.Cryptography" %>
<%@ Import Namespace="System.Threading" %>

<script runat="server">
    Sub Page_Load()
        Dim delay As Byte() = New Byte(0) {}
        Dim prng As RandomNumberGenerator = New RNGCryptoServiceProvider()
       
        prng.GetBytes(delay)
        Thread.Sleep(CType(delay(0), Integer))
       
        Dim disposable As IDisposable = TryCast(prng, IDisposable)
        If Not disposable Is Nothing Then
            disposable.Dispose()
        End If
    End Sub
</script>

<html>
<head runat="server">
    <title>Error</title>
</head>
<body>
    <div>
        Sorry - an error occured
    </div>
</body>
</html>

C version:

<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Import Namespace="System.Security.Cryptography" %>
<%@ Import Namespace="System.Threading" %>

<script runat="server">
   void Page_Load() {
      byte[] delay = new byte[1];
      RandomNumberGenerator prng = new RNGCryptoServiceProvider();

      prng.GetBytes(delay);
      Thread.Sleep((int)delay[0]);
       
      IDisposable disposable = prng as IDisposable;
      if (disposable != null) { disposable.Dispose(); }
    }
</script>

<html>
<head runat="server">
    <title>Error</title>
</head>
<body>
    <div>
        An error occurred while processing your request.
    </div>
</body>
</html>

Grz, Kris.

Saturday, 18 September 2010 13:49:57 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [15]  | 
# Wednesday, 02 December 2009

With a lot of ajax, sometimes too much, being used in modern web applications it usually means that also calculations or data is being kept on the client. That’s all great but sometimes one has to perform a postback to the server. When the browser unloads and all form data’s passed to the server the javascript variables that were living happily in the browser are lost. A possible solution is to use a hidden field to send it back and forth. Some source code explains this scenario better:

Markup:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="passjsdataviahiddenfield.aspx.cs" Inherits="betslap.passjsdataviahiddenfield" %>

<!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 runat="server">
    <title></title>
    <script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.3.2.js" type="text/javascript"></script>
    <script type="text/javascript">

        $(document).ready(function () {
        
            $('#<%= btnGo.ClientID %>').click(function () {
                var txtValue = 'Hello ' + $('#<%= txtInput.ClientID %>').val();
                $('#<%= hidden1.ClientID %>').val(txtValue);
            });
        });
     
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:HiddenField runat="server" ID="hidden1" />
        Fill in your name please: <asp:TextBox runat="server" ID="txtInput" />
        <br />
        <asp:Button runat="server" ID="btnGo" Text="Go!" OnClick="btnGo_Click" />
        <br />
        <asp:Literal ID="Literal1" runat="server"></asp:Literal>
    </div>
    </form>
</body>
</html>

Codebehind:

using System;

namespace betslap
{
    public partial class passjsdataviahiddenfield : System.Web.UI.Page
    {
        protected void btnGo_Click(object sender, EventArgs e)
        {
            Literal1.Text = hidden1.Value;
        }
    }
}

In the markup I make use of the new CDN (Content Delivery Network) from Microsoft. In the piece of javascript that follows a click event is wired and to the button control. The value of the textbox prefixed with the string Hello is put in a local variable txtValue. Then that variable’s used to fill up the hidden field value attribute. Once the button gets clicked this value passing to the hidden field gets processed and then the postback occurs. There we set in the Click eventhandler, on the server, the text of the literal control to the text of the hidden field, in which we passed our javascript variable. The page gets processed, html is rendered and sent back to the browser. Both the value of the hidden field and the text of the literal are the same right now. This demonstrates the working.

Something else that I touched is this syntax:

<%= btnGo.ClientID %>

Since ASP.NET generates the ids of the html that gets rendered it can be sometimes something else than you expect. Especially when using master pages and javascript a lot of people get surprised with the, in their eyes, unpredictable behavior as it also generates a lot of prefixes. ASP.NET exposes the ClientID property on server controls which provides us with the rendered id on the client. With this line we inject that ClientID directly into the code of javascript, which gets rendered to the browser and there the correct id is always available.

To learn more about Microsoft CDN take a look at this page: http://www.asp.net/ajaxlibrary/CDN.ashx.

Grz, Kris.

ASP.NET | CDN | jQuery
Wednesday, 02 December 2009 20:46:59 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, 19 November 2009

A lot of cool stuff's coming out soon and there are already beta bits available. With beta bits there are also already videos available to look at and get familiar with what will be available.

Enjoy watching them.

Grz, Kris.

Thursday, 19 November 2009 17:23:00 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, 18 November 2009

I found this question on the ASP.NET forums. The member asking this question already knew that the collections were Cookies, Form, Servervariables and Querystring but wanted to know the exact order. Well I got curious but instead of making a dedicated test project I opened up Reflector. Looking up the HttpRequest class’ indexer gave me this code:

public string this[string key]
{
    get
    {
        string str = this.QueryString[key];
        if (str != null)
        {
            return str;
        }
        str = this.Form[key];
        if (str != null)
        {
            return str;
        }
        HttpCookie cookie = this.Cookies[key];
        if (cookie != null)
        {
            return cookie.Value;
        }
        str = this.ServerVariables[key];
        if (str != null)
        {
            return str;
        }
        return null;
    }
}

 

It’s on the other hand always better to directly call the most specific collection directly. This avoids getting strange things in your code like expecting a key in the Form collection and getting the same key from the QueryString collection which could have a different, or none at all, value than what you expect. Fun debugging sessions follow after that…

Grz, Kris.

Wednesday, 18 November 2009 05:02:00 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, 17 March 2009

Just noticed that there are several new videos under the learn section at "_blank">www.asp.net. This time about IIS for ASP.NET. Be sure to check them out. At the moment there are 8 tutorials already.

Developing and Deploying In a Shared Hosting

Install Silverlight

Working with IIS7 Deligated Admin

Install Silverlight

Feature Specific Delegated Management

Install Silverlight

Troubleshooting Production ASP.NET Apps

Install Silverlight

Creating a Site with IIS7 Manager

Install Silverlight

Installing FTP7

Install Silverlight

Bit Rate Throttling

Install Silverlight

IIS7 Playlists

Install Silverlight

Grz, Kris.

ASP.NET | IIS | Learn | Tutorial
Tuesday, 17 March 2009 11:44:05 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, 24 September 2008
Just noticed that I just wrote my 10.000th post on the ASP.NET forums. Cool! Well I hope many people enjoyed my replies and possible answers during those years.



Grz,  Kris.
ASP.NET | Forums | MVP
Wednesday, 24 September 2008 12:43:22 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Wednesday, 05 March 2008

It's MIX and that always means great stuff coming to web developers. This year it's the ASP.NET MVC Preview 2 and Silverlight 2. Great times are ahead of us.

Grz, Kris.

Wednesday, 05 March 2008 20:31:17 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, 08 February 2008

Just launched on the ASP.NET website: the ASP.NET wiki. Take a look at it and see if you can contribute. Also take a look at the publishing guidelines.

Grz, Kris.

Friday, 08 February 2008 21:54:21 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, 07 February 2008
Just read that Scott Mitchel has started another series on ASP.NET articles. This time he'll be covering security in ASP.NET. Be sure to check it out: Security tutorials.

Grz, Kris.
Thursday, 07 February 2008 09:47:35 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, 19 November 2007

on

Lots to learn, not enough free time unfortunately.

Grz, Kris.

Monday, 19 November 2007 20:18:22 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Sunday, 09 September 2007

Standard out of the box ASP.NET 2.0 uses SQL Server Express for the Application Services (Membership, Roles, ...). However sometimes you don't want it to be like that because you don't want to pay extra for SQL Server to your hosting company. In the past you practically had to rewrite your application or at least the Data Access Layer to be able to use an alternative database. Thanks to the Provider model that's being used by ASP.NET 2.0 it's possible to develop an application while another team could create an alternative provider and afterwards use some configuration to let your application make use of this new provider.

So, when you're reading this, it means you're interested in changing your default SQL Server based applications services to Access. First of all make sure that you download the Sample Access Providers provided by Microsoft.
This is a .vsi file and you could run it to get installed. But rather then doing that, you simply rename the extension from vsi to zip. That's right, you simply rename it and use a zip utitlity, like the built in zip functionality of Windows to extract the files.

accessproviders01 
Figure 1: the unpacked Sample Access Providers

These are the files I got after extracting the .zip file. You see there's already a full blown ASPNetDB.mdb file in it that has the needed tables and queries to be able to support  the Application Services. Figure 2 shows what's already available. As you can see

accessproviders03
Figure 2: Overview of the available tables and queries in the accompanied Access database file.

After extracting the files we still need to compile the source code in order to be able to integrate the providers into our web application. If you have Visual Studio or Visual C# Express installed you open your IDE of choice. You navigate to the menu and click File, Open, Project/Solution. Once the dialog opens you navigate to where you extracted the contents of the zip file. Select the Access.csproj, see Figure 1, and click the Open button.

Once opened you can see the following in the solution (Figure 3). Now you just have to build the solution, preferably in Release mode.

accessproviders04
Figure 3: solution

Ok, the output of building the solution provides us with an assembly named SampleAccessProviders.dll. To find it back you just need to open a windows explorer and navigate to the place where you extracted the zip file to. There you should see a newly created subfolder called bin and in that one that's called Release. In the Release folder you'll find the built assembly.

Now that we have created the assembly it's time to actually use it. Open your Visual Studio or Visual Web Developer Express and create a new website. In the project you create a new subfolder called bin. After creation right click on it and choose Add existing item... from the context menu that appears. Navigate to the place where the built assembly is. Add it to the bin folder of the website project. After that repeat the same thing with the access database (ASPNetDB.mdb) file but this time put it in the dedicated folder App_Data which is one of the predefined ASP.NET 2.0 subfolders.

Open the web.config file of the website project. You'll need to make some adjustments here in order to be able to use it Access provider. When you take a look at figure 1 you'll see that the extracted zip file also contains a web.config. It already contains the needed parts so the only thing required is just to copy paste the needed configuration parts.
First of all the connectionstring to the access database:

    <connectionStrings>
        <add name="AccessFileName" connectionString="~/App_Data/ASPNetDB.mdb" providerName="System.Data.OleDb"/>
    </connectionStrings>

 Also be sure to change the authentication mode which defaults to Windows. Make it use Forms instead like this:

<authentication mode="Forms">
  <forms loginUrl="mylogin.aspx" defaultUrl="Login.aspx"/>
</authentication>

After that you can simply copy in the providers that you need. In this tutorial I'll only copy in the Membership provider part:

<membership defaultProvider="AccessMembershipProvider">
    <providers>
        <clear/>
        <add name="AccessMembershipProvider" 
                type="Samples.AccessProviders.AccessMembershipProvider, SampleAccessProviders" 
            connectionStringName="AccessFileName" 
            enablePasswordRetrieval="false" 
            enablePasswordReset="false" 
            requiresUniqueEmail="false" 
            requiresQuestionAndAnswer="false" 
            minRequiredPasswordLength="1" 
            minRequiredNonalphanumericCharacters="0" 
            applicationName="SampleSite" 
            hashAlgorithmType="SHA1" 
            passwordFormat="Hashed"/>
    </providers>
</membership>

Other provider parts, like the Roles and Profile, are just as easily copied.

Just to see if things are working is quite easy. Just open the ASP.NET Configuration Tool. You do that by navigating to the menu and click Website, ASP.NET Configuration. A browser opens with the tool in place. Click the fourth tab (Provider). Select the second link ("Select a different provider for each feature (advanced)). There you'll see that the access provider is selected (figure 4)

accessproviders05
Figure 4: Provider tab in the ASP.NET Configuration Tool

In the membership configuration you notice the <clear/> tag. This clears all previous settings from a hierarchical higher configuration. If you remove that particlar line you'll see that you get another radiobutton option that lists the default AspNetSqlMembershipProvider. If you would select that option SQL Server's used again. 

Grz, Kris.

Sunday, 09 September 2007 21:25:12 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Friday, 27 July 2007

A site that I visit frequently just got a repaint job. It looks nice I must say. Be sure to check it out at http://www.asp.net/. If you should have any suggestions or remarks you can leave them in the Feedback forum.

Grz, Kris.

ASP.NET | Links | Forums
Friday, 27 July 2007 09:22:49 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, 15 June 2007

Hi,

just found out about this sample application: .NET StockTrader Sample Application.

This application is an end-to-end sample application for .NET Enterprise Application Server technologies. It is a service-oriented application based on Windows Communication Foundation (.NET 3.0) and ASP.NET, and illustrates many of the .NET enterprise development technologies for building highly scalable, rich "enterprise-connected" applications. It is designed as a benchmark kit to illustrate alternative technologies within .NET and their relative performance. The application offers full interoperability with J2EE and IBM WebSphere's Trade 6.1 sample application. As such, the application offers an excellent opportunity for developers to learn about .NET and building interoperable, service-oriented applications.

Since the weather in Belgium isn't that great at the moment I think I know what I'll be checking out the next week.

Grz, Kris.

Friday, 15 June 2007 07:22:59 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, 09 June 2007

I see that question appearing on the ASP.NET forums over and over again so I decided to dedicate a post on the subject. There are, depending on the .NET framework properties available that can help one out:

Grz, Kris.

Saturday, 09 June 2007 19:02:12 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, 28 May 2007

Normally you have the possibility to choose Enable Selection in the Smart tag of a GridView control. This results in an extra column in front of the GridView with the text Select. But what if you don't want it like that but want to be able to use an image for example to select that row?

Well, a neat solution's to add a TemplateField and in the ItemTemplate place an ImageButton control. Why this one? Because it has a CommandName property available you can use. All you have to do is to set it to the predefined word Select.

Here's a small example to show what I mean:

<%@ Page Language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>Untitled Page</title> </head> <body> <form id="form1" runat="server"> <div> <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataSourceID="SqlDataSource1"> <Columns> <asp:CommandField ShowSelectButton="True" /> <asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" /> <asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" /> <asp:BoundField DataField="Title" HeaderText="Title" SortExpression="Title" /> <asp:TemplateField> <ItemTemplate> <asp:ImageButton ID="ImageButton1" CommandName="Select" runat="server"
ImageUrl="../App_Themes/Black/Images/bullet-1.gif" /> </ItemTemplate> </asp:TemplateField> </Columns> <SelectedRowStyle BackColor="Red" /> </asp:GridView> <asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" SelectCommand="SELECT [LastName], [FirstName], [Title] FROM [Employees]"></asp:SqlDataSource> </div> </form> </body> </html>

Grz, Kris.

Monday, 28 May 2007 15:46:12 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Sunday, 27 May 2007

When you start creating a new ASP.NET 2.0 site with Visual Studio 2005 or Visual Web Developer Express (VWD) and want to start using it you'll notice that a new file in the App_Data folder gets created besides your own database, namely the aspnetdb.mdf file. This extra database holds all the tables and stored procedures to let Membership, Roles, Profile etc run smoothly.

However a problem arises when you don't want to use that dedicated new database when you want to deploy to your live webserver, certainly not when you use a host that only offers one database and charges you extra for another database. Luckely you can control things more when using the dedicated aspnet_regsql tool that ships with the .NET 2.0 framework.

What I'm about to describe in this article is how to use that tool to generate a SQL script that you can use to run on your other database with a tool like SQL Server Management Studio (SSMS). In this example I'll be using the installed Northwind database on my localhost developer machine.

Just start up a new DOS box by going to Start | Run and type in cmd followed by enter. In Windows Vista you push the blue windows logo button and in the field with the text Start Search you type in cmd followed by ctrl + shift + enter. The reason for that combination is that you must run it under Admin privileges or else the to be generated file doesn't get writed to disk.
A new DOS box will appear and you just navigate to the following directory/folder:

Windows\Microsoft.NET\Framework\v2.0.50727\

If you're not used to using DOS you can navigate to it by typing this in the DOS box: cd \windows\Microsoft.net\framework\v2.0.50727 followed by enter.

Then you type in this line: aspnet_regsql.exe -E -S localhost -d Northwind -A all -sqlexportonly c:\membership.sql again followed by enter. At the location c:\ a new file gets generated: membership.sql.

The Northwind name in the parameter list is later on used to set the db name in the generated sql file: SET @dbname = N'Northwind'

Once generated you can use/tweak this file to be used in SSMS to get executed and to install everything needed in the database.

Ok, up untill now we focussed on getting everything ready on the database side but we also have to let our ASP.NET 2.0 application know that we're pointing out to another database than the default one. The solution for this is to override the default settings for the LocalSqlServer connectionstring which can be found in the machine.config file.

<add name="LocalSqlServer"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;
AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"

providerName="System.Data.SqlClient" />

To override that you open the web.config file in your application which can be normally found in the root of the application. Go to the <connectionStrings> element.

<connectionStrings>
    <remove name="LocalSqlServer"/>
    <add name="LocalSqlServer" connectionString="The connection string to your
                         (new) database"
providerName="System.Data.SqlClient" />
</connectionStrings>

Notice the second line where you call the remove statement. This is needed in order to be able to override the LocalSqlServer connection string!

If you're in need of a little help to get your connection string right there's a dedicated site: http://www.connectionstrings.com/.

If you're interested in creating one dedicated database for multiple applications you can also check out Scott Guthrie's post: Configuring ASP.NET 2.0 Application Services to use SQL Server 2000 or SQL Server 2005.

Grz, Kris.

Sunday, 27 May 2007 09:46:38 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, 30 April 2007

If you're an ASP.NET developer like me you're going to love this one: Dynamic Datacontrols.

Take a look at the video and be amazed. I can't help to think that it resembles BLINQ a lot although still quite different because that was generated by a tool. This time it depends on the name of the folder and page that you give so that the dynamic controls are able to put together whole pages by themselves. I can't really explain it as well as I would love to but just check out the video. It's cool.

Grz, Kris.

Monday, 30 April 2007 23:10:24 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
# Sunday, 01 April 2007

Hi,

most ASP.NET developers probably already know that there's a wealth of information to be found under the Learn tab of the ASP.NET website. There's video material covering these subjects:

“How Do I?” with ASP.NET AJAX
“How Do I?” with ASP.NET
SQL Server 2005 Express for Beginners
Videos for ASP.NET 2.0 Beginners
“First Look” Videos
Videos on Visual Studio 2005 Add-ins
Videos on Migrating to ASP.NET

Also I found out that there's also some other interesting video material out there: http://blogs.interfacett.com/dan-wahlins-blog/. It has several nice videos on creating and calling web services, C# delegates & events, creating a webservice with WCF, ... Be sure to check it out.

Grz, Kris.

Technorati tags: , ,

kick it on DotNetKicks.com

ASP.NET | WCF
Sunday, 01 April 2007 08:50:40 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, 03 March 2007

Microsoft provides since recently a new learning center for the beginning developer. Totally dedicated to the freely available Expression editions of Visual Studio 2005 people who are interested in beginning to learn to program can take advantage of.

You can find the Learning Center here.

Another interesting piece of information are the SQL Server 2005 Express For Beginners screencasts.

Grz, Kris.

kick it on DotNetKicks.com

 

Saturday, 03 March 2007 09:50:15 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, 15 January 2007

Hi,

last saturday I already wrote about the new anti XSS library and I just found out there's a dedicated forum for all your question available. Take a look here: Anti-Cross Site Scripting Library.

Grz, Kris.

Monday, 15 January 2007 08:19:48 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Saturday, 13 January 2007

Microsoft recently release the new version of their Anti-Cross Site Scripting (XSS) Library, currently at version 1.5. You can download and find more information about it here. If you're concerned about security in ASP.NET give this library a try.

Grz, Kris.

kick it on DotNetKicks.com

Saturday, 13 January 2007 11:08:37 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, 04 January 2007

Hi,

I always like to recommend these tutorials to people who are taking their first steps with ASP.NET 2.0. Since I have a couple days off I thought, why not take the lessons myself? The first tutorial shows how to use TableAdapters, which was something I never used before, so it also turned out to be very interesting for me too.

You can find the data tutorials here.

The next weekend and weeks I hope to spend some time on ASP.NET AJAX as well.

Grz, Kris.

Thursday, 04 January 2007 13:25:38 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Sunday, 29 October 2006

The freely available tool WebMatrix, which I used on my old pc to develop ASP.NET pages several years ago, came with a built in webserver, code named Cassini, so a developer could test his/her pages on the localhost.

With the .NET 2.0 framework this localhost only webserver's shipped and if you don't have Visual Studio 2005, or the free Visual Web Developer Express Edition tool (which is the follow up of WebMatrix), you can still execute your pages and view the outcome in a browser.

Here's a little guide on how to proceed:

Create a folder on your hard drive. In this example I created c:\MyASPNETPages\ where my testpage will reside. The testpage itself contains this code:

    1 <%@ Page Language="C#" %>

    2 

    3 <script runat="server">

    4 

    5     protected void Page_Load(object sender, EventArgs e)

    6     {

    7         Label1.Text = DateTime.Now.ToShortDateString();

    8     }

    9 

   10 </script>

   11 

   12 <html>

   13 <head runat="server">

   14     <title>Test Page</title>

   15 </head>

   16 <body>

   17     <form id="form1" runat="server">

   18     <div>

   19         <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>

   20     </div>

   21     </form>

   22 </body>

   23 </html>

Now start up a DOS box (Start | Run, type in cmd followed by enter). Navigate to the folder C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727

If you don't know how to do this you can type in the following in the opened DOS box:
cd \windows\microsoft.net\framework\v2.0.50727

After that you can type in the text in bold:

C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727>webdev.webserver /port:8088 /path:
"c:\MyASPNETPages" /vpath:"/Test"

Ok what does this mean?

webdev.webserver is the executable itself with the following arguments: port, path and vpath. Port and vpath are optional parameters. After typing the previous lines in bold in and pressing enter a webserver starts up (Figure 1):


Figure 1: Started up webserver

From Figure 1 we can also see what our url will look like (http://localhost:8088/Test).
This demonstrates the purpose of the port and vpath arguments. Port is the port number on which the server will listen. The default is 80 but if you have IIS running, like me, it's better to use another number or they will conflict.

 

After starting the webserver I can easily navigate to my webpage by typing in the url in the address bar of my browser: http://localhost:8088/Test/

As you would've expected I get to see the current date displayed in my page.

If I ommit the vpath argument it would default to "/", meaning that I can navigate to my pages by just typing in this in the address bar: http://localhost:8088/test.aspx

Grz, Kris.

Sunday, 29 October 2006 13:05:19 (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, 23 October 2006

Setting the Width property of a control in ASP.NET is mostly done in the properties pane or by declaratively setting it in the markup. However sometimes you want to set it in code. This can be done by using the Unit structure.

I crafted some small example that you can run to play around with the different UnitType enumerations. Possible choises are:

Cm Measurement is in centimeters. 
Em Measurement is relative to the height of the parent element's font. 
Ex Measurement is relative to the height of the lowercase letter x of the parent element's font. 
Inch Measurement is in inches. 
Mm Measurement is in millimeters. 
Percentage Measurement is a percentage relative to the parent element. 
Pica Measurement is in picas. A pica represents 12 points. 
Pixel Measurement is in pixels. 
Point Measurement is in points. A point represents 1/72 of an inch. 

The sample provided here loops over the possible unit types and fills up the dropdownlist. The second textbox is used to fill in an amount to set the Width of the first textbox control to. If you don't fill in an amount it automatically defaults to 30.

    1 <%@ Page Language="C#" %>

    2 

    3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    4 

    5 <script runat="server">

    6 

    7     protected void Page_Load(object sender, EventArgs e)

    8     {

    9         if (!Page.IsPostBack)

   10         {

   11             // Set the original width to 300 pixels

   12             TextBox1.Width = new Unit(300);

   13 

   14             // Loop over the possible unit types

   15             foreach (string s in Enum.GetNames(typeof(UnitType)))

   16                 DropDownListSelectUnitType.Items.Add(Enum.Format(typeof(UnitType), Enum.Parse(typeof(UnitType), s), "G"));

   17         }

   18     }

   19 

   20     protected void Button1_Click(object sender, EventArgs e)

   21     {

   22         // Obtain the chosen width, if it's not filled it default to 30

   23         int width = !String.IsNullOrEmpty(TextBoxSetWidth.Text) ? Convert.ToInt32(TextBoxSetWidth.Text) : 30;

   24 

   25         // Obtain the chosen unit type

   26         UnitType type = (UnitType)Enum.Parse(typeof(UnitType), DropDownListSelectUnitType.SelectedItem.Text, true);

   27 

   28         // Use the Unit structure to set the width of the textbox

   29         TextBox1.Width = new Unit(width, type);

   30     }

   31 </script>

   32 

   33 <html xmlns="http://www.w3.org/1999/xhtml" >

   34 <head runat="server">

   35     <title>Untitled Page</title>

   36 </head>

   37 <body>

   38     <form id="form1" runat="server">

   39     <div>

   40         <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox><br />

   41         <br />

   42         <br />

   43         Width: <asp:TextBox ID="TextBoxSetWidth" runat="server" Width="40px"></asp:TextBox><br />

   44         Type: <asp:DropDownList ID="DropDownListSelectUnitType" runat="server">

   45         </asp:DropDownList><br />

   46         <asp:Button ID="Button1" runat="server" Text="Set Textboxes width" OnClick="Button1_Click" />

   47     </div>

   48     </form>

   49 </body>

   50 </html>

Grz, Kris.

Monday, 23 October 2006 11:05:53 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, 29 September 2006

Hmm, I hope the marketing guys of Microsoft aren't going to keep renaming Atlas. I already found it hard enough to not speak about Atlas anymore but of Microsoft AJAX. Seems it's renamed again. Read my former post about the renaming of Atlas.

Here's the new naming for the moment:

  • Microsoft AJAX Library:  The client-side Javascript library (i.e., all the .js files) that works with any browser and also supports any server-side framework, not just ASP.NET.
  • ASP.NET 2.0 AJAX Extensions: The server-side functionality that seamlessly integrates with ASP.NET and uses the same programming model familiar to existing ASP.NET developers.
  • ASP.NET AJAX Control Toolkit: The set of free, shared source controls and components that currently form the "Atlas" Control Toolkit community project hosted on CodePlex.
  • ASP.NET AJAX = Microsoft AJAX Library + ASP.NET 2.0 AJAX Extensions.

    Grz, Kris.

  • Friday, 29 September 2006 07:09:46 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
    # Saturday, 09 September 2006
    # Tuesday, 29 August 2006

    People that use ASP.NET know that it's very easy to use the Properties pane in visual studio to quickly set some properties on a server control. By default already a lot of such properties are made available but sometimes you just want something that just doesn't come out of the box. Luckely the WebControl class also provides the Attributes property which is of type AttributeCollection. You can use the Add method to add new attributes to your control.

    To make it more clear I created a small demo page that I used to answer a question on the ASP.NET forums.

        1 <%@ Page Language="C#" %>

        2 

        3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

        4 

        5 <script runat="server">

        6 

        7     protected void Page_Load(object sender, EventArgs e)

        8     {

        9         ListBox1.Attributes.Add("ondblclick", "GetValue();");

       10     }

       11 </script>

       12 

       13 <html xmlns="http://www.w3.org/1999/xhtml" >

       14 <head runat="server">

       15     <title>Untitled Page</title>

       16     <script type="text/ecmascript">

       17     function GetValue()

       18     {

       19         box = document.getElementById('ListBox1');

       20         x = box.options[box.selectedIndex].value;

       21 

       22         if(document.all)

       23             document.getElementById('Label1').innerText = x;

       24         else // FireFox doesn't implement the innerText property.

       25             document.getElementById('Label1').textContent = x; 

       26     }

       27     </script>

       28 </head>

       29 <body>

       30     <form id="form1" runat="server">

       31     <div>

       32         <asp:ListBox ID="ListBox1" runat="server">

       33             <asp:ListItem>One</asp:ListItem>

       34             <asp:ListItem>Two</asp:ListItem>

       35             <asp:ListItem>Three</asp:ListItem>

       36         </asp:ListBox></div>

       37         <asp:Label runat="server" ID="Label1" />

       38     </form>

       39 </body>

       40 </html>

    On line 9 you can see that I add an attribute. In this case the ondblClick javascript event. This results, once rendered in a browser to have the ability to double click on an item and have the selected value set as being the text of the label control. The javascript function that accomplishes this task is on line 19 - 25.

    Tuesday, 29 August 2006 19:21:02 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
    # Friday, 28 July 2006

    Learning new technologies is always some part fun, some excitement but also can cause some frustration when something doesn't work like you would expect it. For the first part there are a huge amount of books available but Microsoft is also being busy creating videos for their ASP.NET technology and since recently also for the upcoming Atlas technology. You can find the videos here.

    Of course, when things get frustrating and need help you can always visit the ASP.NET forums.

    Grz, Kris.

    Friday, 28 July 2006 18:30:02 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
    # Friday, 21 July 2006

    Most people that have even limited experience with ASP.NET know that you can set the properties of a server control quite easily in the Properties pane of vs.net. Once done this gets set declaratively in the attributes collection of the control. You can see this quite easily when you take a look at the markup of your webform. 

    A little less known however is the fact that this also can be done with user controls. You can create a public property on the user control, place it on a webform and set, declaratively, the property in the markup of your webform.
    I did it myself a couple of years ago when I crafted a user control that on a certain webform would show the entire list coming from a database and on another webform it should only let a subset of that list be seen. So using this technique I was able to set which list would be shown, from the webform. Keeping the webform in control of what's shown once it was rendered.

    A small example is in place here:

    First I have my user control:

        1 <%@ Control Language="C#" ClassName="PropertySetDeclaratively" %>

        2 

        3 <script runat="server">

        4 

        5     public string ShowValue

        6     {

        7         set { Label1.Text = value; }

        8     }

        9 

       10 </script>

       11 

       12 <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>

    As you can see, I created a public property ShowValue in which the Text of the Label control, Label1, will be set to the value that's passed to it.

    And the webform which hosts the user control:

        1 <%@ Page Language="C#" %>

        2 

        3 <%@ Register Src="PropertySetDeclaratively.ascx" TagName="PropertySetDeclaratively"

        4     TagPrefix="uc1" %>

        5 

        6 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

        7     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

        8 

        9 <script runat="server">

       10 

       11 </script>

       12 

       13 <html xmlns="http://www.w3.org/1999/xhtml" >

       14 <head runat="server">

       15     <title>Untitled Page</title>

       16 </head>

       17 <body>

       18     <form id="form1" runat="server">

       19     <div>

       20         <uc1:PropertySetDeclaratively ID="PropertySetDeclaratively1" runat="server" ShowValue="13" />

       21     </div>

       22     </form>

       23 </body>

       24 </html>

    In the syntax on line 20 you see that the ShowValue, the public property on the user control, is set to 13. Once rendered the Label will be filled up with the passed content. Also be aware that the declaratively set property is filled up even before the OnInit event of the user control gets handled.

    As a nice side effect we can also turn off ViewState for the Label control because it gets set automatically on each page call, be it either an initial request or a postback. You turn of Viewstate of a control by setting its EnableViewState property to false.

    Grz, Kris.

    Friday, 21 July 2006 19:39:14 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

    IIS7 hasn't shipped yet but will be available in Vista and Longhorn server. It provides better ways to extend it and configure it. There's also already some nice video content about the subject:

    Microsoft also provides the possibility to test drive it on one of their Virtual Labs.

    Grz, Kris.

    .NET 2.0 | ASP.NET | Windows | IIS
    Friday, 21 July 2006 09:13:00 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
    # Monday, 10 July 2006

    When ASP.NET 2.0 was still out of reach for most people I already found on the internet a great looking diagram I downloaded in the past. All credits go to the original designer of the diagram: Léon Andrianarivony. Because I couldn't find the original blogpost anymore I decided to share it with you, the readers of this blog. Enjoy!

    Grz, Kris.

    kick it on DotNetKicks.com

    Monday, 10 July 2006 18:48:47 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
    # Sunday, 09 July 2006

    I found out about this new page on ASP.NET, thanks to PeteL and Brian Goldfarb: By the Community, For the Community.

    The By The Community, For the Community samples series will create ASP.NET samples that are in high demand. These samples will not be created by Microsoft but instead by a select group of ASP.NET community member MVPs. You can see their bios below.

    On a regular basis, starting Friday July 7th, we will publish a list of potential samples and allow the community to vote on which sample they are most interested in seeing developed. After the voting ends, the select MVPs will then create the sample using best practices. The samples will be published and then linked to from this page on www.asp.net.

    So go out and vote for the stuff that you want these guys to create! Personally I love this idea. There are a lot of smart people out there with an MVP status and they're getting more attention. Just think of the Wrox book MVP hacks for example. The ASP.NET forums also have a bunch of MVP people hanging around to help out other people.

    Grz, Kris.

    Sunday, 09 July 2006 12:14:02 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
    # Friday, 30 June 2006
    Friday, 30 June 2006 20:29:27 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 

    Dynamic updatepanels, bugfixes, ...

    I just read it on Nikhil's blog and downloaded it from the the Atlas site.

    Details of the new CTP:

    UpdatePanel:

    • UpdatePanels can be added to a page dynamically throughout the page lifecycle, including UpdatePanels inside templates. UpdatePanels now also work inside WebParts, and WebParts can be inside UpdatePanels.
    • UpdatePanel will preserve cookies set during an async postback when Response.Redirect() is called. This fixes Login control scenarios where an authorization cookie is set and the user gets redirected to the previous page.

    Networking:

    • ServiceMethod uses default error handler if none specified.
    • XsltBridgeTransformer now works with VirtualPathProviders
    • DBNull.Value now should be serialized as null
    • ServiceReferences now support optional InlineProxy attribute for generating service proxies in the page rather than through a serviceurl/js script reference.
    • Fix for scenarios where web service proxy contained the wrong port (webfarms, port forwarding)

    Drag and Drop:

    • Drag and drop will no longer produce debug output
    • Interactive HTML elements (input, button, textarea, select, label, anchors with an href) can no longer be dragged directly

    Miscellaneous Changes:

    • Date.toFormattedString improvements
    • Client-side data: SaveData fix for strongly-typed DataSets

     

    I for one hope that the RTM version is coming close.

    Grz, Kris.

    Friday, 30 June 2006 19:57:28 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
    # Sunday, 25 June 2006

    Most controls are just drag & dropped on a webform or handcoded by a developer in the source view of the document. Although these controls can display dynamic data, for example coming from a database, the controls on the webform themselves remain static. In some scenario's however you want dynamically added controls. For example if a certain authenticated user views the page you want to show more information, or depending on a certain choice you want to load a Repeater control with data or a DateTime control. In this article I instantiate a RadioButtonList control, add it to a PlaceHolder control and wire up the SelectedIndexChanged event of the RadioButtonList instance. Listing 1 shows the C# version and Listing 2 the VB.NET version. Either version is equivalent and it's quite easy to compare both of the code snippets since both have the same equivalent code on the same line.

    Listing 1: C# version:

        1 <%@ Page Language="C#" %>

        2 

        3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

        4 

        5 <script runat="server">

        6     protected override void OnInit(EventArgs e)

        7     {

        8         base.OnInit(e);

        9 

       10         // Instantiate a RadioButtonList control

       11         RadioButtonList rbl = new RadioButtonList();

       12 

       13         rbl.AutoPostBack = true;

       14         rbl.ID = "rblID";

       15 

       16         // Wire up the eventhandler

       17         rbl.SelectedIndexChanged += new EventHandler(rbl_SelectedIndexChanged);

       18 

       19         // Add the items

       20         rbl.Items.Add(new ListItem("One", "1"));

       21         rbl.Items.Add(new ListItem("Two", "2"));

       22         rbl.Items.Add(new ListItem("Three", "3"));

       23 

       24         rbl.DataBind();

       25 

       26         PlaceHolder1.Controls.Add(rbl);

       27     }

       28 

       29     void rbl_SelectedIndexChanged(object sender, EventArgs e)

       30     {

       31         // Get the control and cast it to the

       32         // appropriate type. In our case a RadioButtonList.

       33         RadioButtonList c = (RadioButtonList)FindControl("rblID");

       34         Label1.Text = c.SelectedItem.Text;

       35     }

       36 </script>

       37 

       38 <html xmlns="http://www.w3.org/1999/xhtml" >

       39 <head runat="server">

       40     <title>Untitled Page</title>

       41 </head>

       42 <body>

       43     <form id="form1" runat="server">

       44     <div>

       45         <asp:PlaceHolder ID="PlaceHolder1" runat="server" /><br />

       46         <asp:Label runat="server" ID="Label1" />

       47     </div>

       48     </form>

       49 </body>

       50 </html>

    Listing 2: VB.NET version:

        1 <%@ Page Language="VB" %>

        2 

        3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

        4 

        5 <script runat="server">

        6 

        7     Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)

        8 

        9 

       10         ' Instantiate a RadioButtonList control

       11         Dim rbl As New RadioButtonList

       12 

       13         rbl.AutoPostBack = True

       14         rbl.ID = "rblID"

       15 

       16         ' Wire up the event handler

       17         AddHandler rbl.SelectedIndexChanged, AddressOf rbl_SelectedIndexChanged

       18 

       19         ' Add the items

       20         rbl.Items.Add(New ListItem("One", "1"))

       21         rbl.Items.Add(New ListItem("Two", "2"))

       22         rbl.Items.Add(New ListItem("Three", "3"))

       23 

       24         rbl.DataBind()

       25 

       26         PlaceHolder1.Controls.Add(rbl)

       27 

       28     End Sub

       29 

       30     Protected Sub rbl_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)

       31 

       32         ' Get the control and cast it to the

       33         ' appropriate type. In our case a RadioButtonList.

       34         Dim c As RadioButtonList = DirectCast(FindControl("rblID"), RadioButtonList)

       35         Label1.Text = c.SelectedItem.Text

       36 

       37     End Sub

       38 

       39 </script>

       40 

       41 <html xmlns="http://www.w3.org/1999/xhtml">

       42 <head runat="server">

       43     <title>Untitled Page</title>

       44 </head>

       45 <body>

       46     <form id="form1" runat="server">

       47         <div>

       48             <asp:PlaceHolder ID="PlaceHolder1" runat="server" /><br />

       49             <asp:Label runat="server" ID="Label1" />

       50         </div>

       51     </form>

       52 </body>

       53 </html>

    On line 11 the RadioButtonList is instantiated. After that it's given an ID and the AutoPostBack property is set to true (line numbers 13 & 14).
    Then we wire up the event that'll be handled when a certain selection is made, remember we set the AutoPostBack property to true so once another choice than the current is made an automatic postback to the server will occur. Note the different syntax for C# and VB.NET to wire event handlers on line 17.

    At this moment we already have a RadioButtonList instance, wired up the SelectedIndexChanged event, added 3 items to it and databound these items (Lines 20 to 24) but at this moment it's still not visible to the enduser since it was not already put on the page. ASP.NET provides a dedicated control for this: the PlaceHolder control. You can place this control somewhere on your webform and later on use it to hang dynamic controls to. Another convenient control for this is the Panel control. Adding our RadioButtonList to the PlaceHolder control is done on line 26.

    We can now render our webform in a browser and upon checking a radiobutton in the list an automatic postback occurs, goes through the code of adding the RadioButtonList again to the page in the Page_Init/OnInit event again, which is necessary because the page has completely forgotten about the existance of it after the previous rendering. After that the rbl_SelectedIndexChanged event gets handled.
    In this event we first need to obtain the correct control based upon its ID property with the FindControl method. This method returns an instance of a Control class, which is the base class of all controls in ASP.NET. Once obtained we need to cast it back to the proper class, which is in this case a RadioButtonList. Once cast the Text property of the SelectedItem is used to fill up the Text property of the Label control.

    Grz, Kris.

    Sunday, 25 June 2006 14:13:21 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
    # Saturday, 24 June 2006

    You know that your collegue has created a class with interesting method that you like to reuse in your ASP.NET 2.0 web project but your project is in C#. Instead of waisting time to rewriting the whole chunk of code that your collegue wrote you can simply reuse the code. The only need is to create a couple of subfolders, putting your classes, C# and VB.NET, in these separate subfolders and put some extra configuration in the web.config file.

    So for example you add these subfolders to the App_Code folder: CSharp and VB.

    In the web.config you put these lines in the <compilation> element:

      <system.web>

        <compilation debug="true">

          <codeSubDirectories>

            <add directoryName="CSharp"/>

            <add directoryName="VB"/>

          </codeSubDirectories>

        </compilation>



      </
    system.web>

    Another nice thing about this is that you could also use it to organise your classes somewhat better. For example you can create several subdirectories which hold business classes that belong together and make them known in the <codeSubDirectories> element.

    Grz, Kris.

    Saturday, 24 June 2006 18:49:25 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
    # Monday, 12 June 2006

    Just saw that Scott Mitchell, of 4guysfromrolla fame, announced that he's busy writing tutorials about working with data in ASP.NET 2.0. You can find the tutorials in the Learn section of the ASP.NET official site among other tutorials like videos's, starter kits, ... Be sure to check out the Working with data in ASP.NET 2.0 tutorials. They're also downloadable in pdf format in both VB.NET and C#.

    Grz, Kris.

    Monday, 12 June 2006 21:08:05 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
    # Wednesday, 07 June 2006

    Thanks to the newly added service by Microsoft in Belgium, I was told that this service was already longer available for other countries, called MSDN Connection one can purchase every month a book of the month at a 40% discount. Today I bought those of May and June:

    May:

    $blank(www.microsoft.com/mspress/books/6522.asp,CLR via C# Second Edition)

    June:

    $blank(www.microsoft.com/MSPress/books/8377.asp,Programming Microsoft ASP.NET 2.0 Applications: Advanced Topics)

    The weather's finally getting better in Belgium so I can relax and read some interesting stuff the next couple of weeks.

    Grz, Kris.

    Wednesday, 07 June 2006 18:11:02 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
    # Monday, 05 June 2006

    I read this kind of questions multiple times on the $blank(forums.asp.net,ASP.NET forums). Most of the time it's suggested that one can use one of the events of the grid control they're using to use the FindControl method to find a Label control in one of the template columns and add the current row number to its Text property. I also used to do it like that when I started with ASP.NET.

    However it can be done easier, and in markup, without the use of events, and best of all, the grid controls(1) of ASP.NET support the technique.


    Figure 1: The GridView, DataGrid, Repeater and DataList controls shown to present the technique.

    If Figure 1 you can see that it also supports pagination, which is shown in the GridView control.

    Code says more than words so here goes:

        1 <%@ Page Language="C#" %>

        2 

        3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

        4 

        5 <script runat="server">

        6 

        7     protected void DataGrid1_PageIndexChanged(object source, DataGridPageChangedEventArgs e)

        8     {

        9         DataGrid1.CurrentPageIndex = e.NewPageIndex;

       10         DataGrid1.DataBind();

       11     }

       12 </script>

       13 

       14 <html xmlns="http://www.w3.org/1999/xhtml" >

       15 <head runat="server">

       16     <title>Autonumbering grid controls</title>

       17 </head>

       18 <body>

       19     <form id="form1" runat="server">

       20     <div>

       21         GridView</div>

       22         <asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True"

       23             AutoGenerateColumns="False" DataSourceID="SqlDataSource1" PageSize="5">

       24             <Columns>

       25             <asp:TemplateField>

       26                 <ItemTemplate>

       27                     <%# Container.DataItemIndex + 1 %>

       28                 </ItemTemplate>

       29             </asp:TemplateField>

       30                 <asp:BoundField DataField="CategoryName" HeaderText="CategoryName" SortExpression="CategoryName" />

       31                 <asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />

       32             </Columns>

       33         </asp:GridView>

       34         <br />

       35         DataGrid

       36         <br />

       37         <asp:DataGrid runat="server" ID="DataGrid1" DataSourceID="SqlDataSource1" AllowPaging="True" OnPageIndexChanged="DataGrid1_PageIndexChanged" PageSize="5">

       38             <Columns>

       39                 <asp:TemplateColumn>

       40                     <ItemTemplate>

       41                         <%# Container.DataSetIndex + 1 %>

       42                     </ItemTemplate>

       43                 </asp:TemplateColumn>

       44             </Columns>

       45         </asp:DataGrid><br />

       46         Repeater<br />

       47         <asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1">

       48             <ItemTemplate>

       49                 <span style="margin-right:20px;"><%# Container.ItemIndex + 1 %></span>

       50                 <span><%# Eval("CategoryName") %> <%# Eval("Description") %></span><br />

       51             </ItemTemplate>

       52         </asp:Repeater><br />

       53         DataList

       54         <br />

       55         <asp:DataList ID="DataList1" runat="server" DataSourceID="SqlDataSource1">

       56             <ItemTemplate>

       57                 <%# Container.ItemIndex + 1 %>

       58                 CategoryName:

       59                 <asp:Label ID="CategoryNameLabel" runat="server" Text='<%# Eval("CategoryName") %>'>

       60                 </asp:Label><br />

       61                 Description:

       62                 <asp:Label ID="DescriptionLabel" runat="server" Text='<%# Eval("Description") %>'>

       63                 </asp:Label><br />

       64                 <br />

       65             </ItemTemplate>

       66         </asp:DataList>

       67         <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"

       68             SelectCommand="SELECT [CategoryName], [Description] FROM [Categories]"></asp:SqlDataSource>

       69     </form>

       70 </body>

       71 </html>

    For simplicity I used the SqlDataSource control that ships with ASP.NET 2.0 and used the Northwind database (lines 67 - 68). The following lines are of importance: 27, 41, 49 and 57. The + 1 is added each time because of the zero based index.

    As you can see, it's each time a very simple addition to the markup of the grid control you're using but it adds that nice extra touch of information that endusers like to see.

    Grz, Kris.

    (1): I tested it upon the GridView, DataGrid, DataList and Repeater controls.

    kick it on DotNetKicks.com

    Monday, 05 June 2006 15:27:28 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
    # Saturday, 03 June 2006

    Like most ASP.NET developers I also first installed SQL Express 2005 together with visual studio.net 2005. After a while however I decided to get it off my dev laptop and install the full blown SQL Server 2005 instead because I wanted to test against this database and because I also needed it for an internal course at work. Things went fine, I also played around with the aspnet_regsql tool to make a dedicated database for my ASP.NET 2.0 services like Membership. I even changed the default setting for the LocalSqlServer connection string in my machine.config file in order to not be forced to override that setting in each new webproject I created.

    After a while I felt the urge to reïnstall SQL Express 2005 because I downloaded several example sites and starter kits. Although it's quite easy to attach a .mdf file to SQL Server 2005, you can read my blogpost about it here: Attaching a .mdf file when you don't have the .ldf file available.

    The installation went smoothly, I could see the extra database in SQL Server Management Studio but when I wanted to add a new local database, ie SQL Express database, in the App_Data subfolder of a web project I got this error:

    "Failed to generate a user instance of SQL Server due to a failure in starting the process for the user instance. The connection will be closed."

    Huh?

    Well I search around, gained some knowledge about the problem and thought I share it with you:

    First you'll need to open up SQL Server Configuration Manager. Navigate to that in the menu like Microsoft SQL Server 2005 > Configuration tools > SQL Server Configuration Manager. Take a look at figure 1:


    Figure 1: The SQL Server Configuration Manager tool.

    Double click, or right click and choose Properties, of the selected line and you'll get the properties window which you can see in Figure 2:


    Figure 2: The properties window

    You'll need to make sure that the Local system is selected.

    The second part of the solution's to delete the following folder on your hard drive: c:\Documents and Settings\[user]\Local Settings\Application Data\Microsoft\Microsoft SQL Server Data\SQLEXPRESS(1). This folder's used to store information and apparently it messes up the proper working of SQL Express.

    Grz, Kris.

    (1): http://forums.microsoft.com/msdn/showpost.aspx?postid=98346&siteid=1

    Saturday, 03 June 2006 19:23:25 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [2]  | 
    # Friday, 02 June 2006

    A lot of sites allow people to upload a file like pictures, word documents, ... or even videos. ASP.NET provides an easy way to do this(1).

    What not everyone seems to know that ASP.NET only allows, by default to upload 4Mb of formdata to the server. Endusers can get frustrated when they try to upload their large sized document or video and see, after wasting bandwidth and time, that they don't succeed. This leaves your endusers with a bad taste in their mouth about your application and most likely they won't return or go to the competition.

    However, as with many things in ASP.NET, this can be easily adjusted. Open up the web.config file of your current application and check the line, or add it in case it isn't already in the config file, <httpRuntime /> (2). This has an attribute maxRequestLength that you can set. The number represents the amount of kilobytes that the total form can transfer to the server. Setting this to a higher number than the default 4098 allows you, the developer, to let endusers upload larger sized files.

     

    Grz, Kris.

    (1): Uploading Files in ASP.NET 2.0, Uploading Files Using the File Field Control or Uploading in ASP.NET to name a few.
    (2): Take a look at the documentation for other settings that you can make.

    Friday, 02 June 2006 15:31:52 (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  |