I’ve run across a few situations in which I wanted to animate a certain row in a GridView as a result of some client action.  The reason that this is a little tricky is that the AJAX Control Toolkit’s Animation Extender needs to act on a certain Target Control (identified of course by the TargetControlID) and you can’t point identify the target control as a specific grid view row.

Both methods I will discuss use the same actual animation code — they just differ in the way in which the animation is called.  I’ll begin with the common animation code, which flashes the row with a color change animation (basically a fading highlight).

function animateRow(affectedRow)
{
    //first save the existing row color so you can restore it after the animation is completed
    //you may have to do some post-processing to make sure the affectedRowColor is a hex value like #FFFFFF
    var affectedRowColor = affectedRow.style.backgroundColor;
    animation = new AjaxControlToolkit.Animation.ColorAnimation(affectedRow, 2, 32, “style”, “backgroundColor”, “#ffff99″, affectedRowColor);
    animation.play();
}

Basically the above code uses the AjaxControlToolkit Animation API to create a ColorAnimation that acts on the affected row, which will cause the entire row to highlight and then fade back to its original color.

The quick method for getting access to the affected row can be used when an element of that row initiates the animation (for example, click on an update button flashes the row that it is contained in).  The code would look something like this:

<asp:TemplateField HeaderText=”Highlight My Row”>
    <ItemTemplate>
        <input type=”button” value=”Click Me” onclick=”animateRow(this.parentNode.parentNode);” />
    </ItemTemplate>
</asp:TemplateField>

The onclick event of this template field button calls the above animateRow function and passes it’s grandparent node (this.parentNode.parentNode).  Since the DOM tree has the element inside a <td/> which is inside a <tr/>, we know that the element’s grandparent is the row to animate.

The second method involves giving each row a unique identifier during the handling of the rowCreated event.  The details will change depending on your implementation, but lets assume that you are using a GridView with a bound ID property (which is also a datakey).  Then you need to handle the rowCreated event and add an “id” attribute to each row:

protected void gv_RowCreated(object sender, GridViewRowEventArgs e)
    {
        GridView gview = (GridView)sender;
        e.Row.Attributes.Add(“id”, gview.DataKeys[e.Row.RowIndex]["id"].ToString());
    }

This will allow you to dynamically update any row by executing the following javascript:

var id = “idhere”;
var affectedRow = $get(id);

animateRow(affectedRow);

With a few modifications you can get some pretty dynamic per-row animations while letting the AJAX Control Toolkit do all the heavy lifting.  Enjoy!


The ASP.NET AJAX Control Toolkit’s Calendar (Click Here To See The CalendarExtender Control In Action) is a very nice control that allows you implement a client side dynamic calendar for date-picking functionality. One interesting feature is the ability to change the calendar from the default “days” mode (shows the days in one month) to “months” mode (showing all of the months in the current year) by clicking on the calendar title. Another click on the title will change the calendar into “years” mode, which shows 12 years at a time.

One feature that would be nice is the ability to start the calendar control in any of the desired modes (“days”, “months”, or “years”) depending on the type of interaction with the calendar that is most appropriate. For example, a current project of mine requires entering employee hire dates — which are almost always at least a few years old.

The following is some simple code that allows you to get the desired functionality (in this case, we switch to the “years” mode) by handling the Calendar’s OnClientShown event.

Step 0 — The initial Calendar control hooked up to a TextBox

<asp:TextBox ID="txtTitleLength" runat="server"></asp:TextBox> 
<AjaxControlToolkit:CalendarExtender ID="calTitleLength" runat="server"
TargetControlID="txtTitleLength"> 
</AjaxControlToolkit:CalendarExtender>

Step 1 — Add a callback to the OnClientShown event (here: “calendarShown”)

<asp:TextBox ID="txtTitleLength" runat="server"></asp:TextBox> 
<AjaxControlToolkit:CalendarExtender ID="calTitleLength" runat="server"
TargetControlID="txtTitleLength"
OnClientShown="calendarShown"> 
</AjaxControlToolkit:CalendarExtender>

Step 2 — Handle the OnClientShown event (which takes 2 parameters: “sender, e”) and then call the calendar control’s _switchMode() method

function calendarShown(sender, e) { sender._switchMode("years"); }

That’s all there is to it! One note: you must call the switchMode() method in the OnClientShown event and not the OnClientShowing event for the effect to work properly.



I can across a problem today where I had to attach a PDF file that is stored on a network share to an outgoing email using ASP.NET 2.0. This is pretty simple to do, except in my case the PDF filename on the share has an obfuscated name while its original name (file.pdf) is stored in a database lookup table. Looking at the System.Net.Mail.Attachment constructors, you’ll see that three take a string filename and three take a System.IO.Stream object to represent the file. The string filename constructors do not possess the ability (as far as I could see) to give the attached file a “friendly name”, although one of the Stream constructors does. So what I ended up doing was opening the file with a non-locking FileStream object and then passing it to the mail attachment object, careful to close the stream when I was done. Pretty simple, but I couldn’t find any sources using this method so I thought I’d write it down here (minus error handling code for clarity):

System.Net.Mail.MailMessage message =new System.Net.Mail.MailMessage(“from@from.com”, “to@to.com”, “Subject”, “My attachment has a friendly name”);

 //Open the filestream with non-locking read permission

System.IO.FileStream fileStream = new System.IO.FileStream(“fileSystemName”, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);

 message.Attachments.Add(new System.Net.Mail.Attachment(fileStream, “friendlyName.pdf”));

fileStream.Close();


When trying to run a WCF project using the new WCF Test Client in Visual Studio 2008 (Orcas) Beta 2, I got the following error from svcutil.exe:

Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly ’svcutil, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ or one of its dependencies. Strong name validation failed. (Exception from HRESULT: 0×8013141A)
File name: ’svcutil, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ —> System.Security.SecurityException: Strong name validation failed. (Exception from HRESULT: 0×8013141A)
The Zone of the assembly that failed was:
MyComputer

 
 

It turns out this issue was discussed in the MSDN forums at http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1932994&SiteID=1. The solution is basically that you need to strong name svcutil (as the error message implies. Unfortunately I found the instructions given on the MSDN forum lacking so I wanted to create my own set of instructions, which follow:

1. Open the VS 2008 Beta 2 command prompt as Administrator.

2. Browse to the bin directory of the windows SDK (on my computer: C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin)

3. Type: sn –Vr svcutil.exe.

 


I recently ran into a situation where I wanted to render the contents of a user control either directly to the current HTML stream or to a file format like MS Word. Fortunately .NET has the ‘LoadControl’ function that takes the virtual path of a User Control and returns a Control object. In order to get the rendered output of a user control into an HTML32TextWriter, you can use the following code:

Control report;

StringBuilder sb = new
StringBuilder();

StringWriter sw = new
StringWriter(sb);

Html32TextWriter hw = new
Html32TextWriter(sw);

 

report = LoadControl(“WebUserControl.ascx”);

report.RenderControl(hw);

 

One word of caution: When loading a Web User Control through the LoadControl() method, the normal page lifecycle events, such as Page_Init and Page_Load, are not called. To make up for this deficiency, you can cast the returned Control object to the User Control type and call any required methods directly from the object reference before rendering the control. For example, I created an IReportUserControl interface that defines a LoadReport() method, and which all report-type Web User Controls derive from. Then I can simply insert the following code in order to run the proper initialization logic:

report = LoadControl(“WebUserControl.ascx”);

((IReportUserControl)report).LoadReport(); //Initialize the control

report.RenderControl(hw);

 


When I was converting untyped data values from a SQL database into a custom Business class, I realized that I has to take special precaution when casting possibly null values. If you try to cast a null object to some type, you will get an InvalidCastException. When thinking about a solution, I remembered the As operator and decided to do some investigating. Consider the following example:

object objstr = null;
string str1 = (string)objstr; //Cast throws an Exception
string str2 = objstr as string; //No exception is throw, and str2 == null

So it turns out that the as operator is just like the cast operator except that it yields null on conversion failure instead of throwing an exception. Looking at a MSDN C# Programmer’s Reference page http://msdn2.microsoft.com/en-us/library/cscsdfbt(vs.71).aspx confirmed this, and even offered up the following explanation.

expression as type

is equivalent to

expression is type ? (type)expression : (type)null

Creating a Custom Code Snippet is pretty easy to do — you just fire up your favorite text editor, write some XML, and save the results in a *.snippet file. If you use Visual Studio as your text editor, you can even get some XML Intellisense, which is always nice. I am going to create a code snippet called rw.snippet, which will simply expand to Response.Write();, and leave your cursor inside the parenthesis (something I use far too often, along with Trace.Write(), for debugging).

To get started, create an empty text file in Notepad (or similar), and add the following lines to indicate that you want to write a custom code snippet.

<?xml version=”1.0″ encoding=”utf-8″ ?>
<CodeSnippets xmlns=”http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet”>
<CodeSnippet Format=”1.0.0″>
</CodeSnippet>
</CodeSnippets>

Now save the file as rw.snippet (I would recommend saving it in your Visual Studio 2005\Code Snippets\[Language]\My Code Snippets folder) and close out of NotePad. Open the file in Visual Studio (note: since the file has the *.snippet extension, it should now be registered to open with Visual Studio by default). You should see the XML scheema information that you copied earlier, and you should get some next text highlighting as well.

Inside the <CodeSnippet> tag, you can add header information inside a <Header> tag, including a Title, Shortcut (the keyboard shortcut to be used), Description and more. You can use Intellisense to see all the possibilities. For now, I’ll add the following information:

<Header>
<Title>rw</Title>
<Shortcut>rw</Shortcut>
<Description>Code snippet for generating Response.Write</Description>
<Author>Scott K</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>

Next, you create the <Snippet> tag where the actual implementation will take place. Inside the snippet tag, you can define variables (literals/objects) to be filled in later (called Declarations) as well as the <Code> section containing your actual snippet content. The <Code> tag itself can define a few properties, like the declaration ‘delimiter’, ‘kind’ (to filter snippets based on code location), and ‘language’ (mainly helpful for organization) options. Inside the <Code> tag, you will create a <![CDATA[]]> section which will hold the snippet body as a plain string. The Snippet section for my Response.Write() snippet will look like the following:

<Snippet>
<Code Language=”csharp”>
<![CDATA[Response.Write($end$);]]>
</Code>
</Snippet>

Here, ‘end’ is a built-in declaration for the position the cursor will end up after expanding the snippet, and since we didn’t change the delimiter is it defaulted to $. So the complete code for the rw.snippet file is:

<?xml version=”1.0″ encoding=”utf-8″ ?>
<CodeSnippets xmlns=”http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet”>
<CodeSnippet Format=”1.0.0″>
<Header>
<Title>rw</Title>
<Shortcut>rw</Shortcut>
<Description>Code snippet for Response.Write</Description>
<Author>Scott K</Author>
<SnippetTypes>
<SnippetType>Expansion</SnippetType>
</SnippetTypes>
</Header>
<Snippet>
<Code Language=”csharp”>
<![CDATA[Response.Write($end$);]]>
</Code>
</Snippet>
</CodeSnippet>
</CodeSnippets>

Once you have saved your file, inside Visual Studio click on Tools->Code Snippets Manager. Now choose the Import Option, navigate to your file save location and choose rw.snippet Choose where to put the snippet (I chose Visual C#) and click OK. Thats it! Now when you are typing in a normal coding environment, type rw and you will see the code snippet paper icon appear with rw in Intellisense. Press tab to expand out this snippet, and you will get Response.Write(); with your cursor ready for action inside the parenthesis.

Now the you have a working snippet, you may want to create a more complex snippet with custom declarations. All you have to do is add declarations to the <Snippet> tag and give them IDs, and then reference those IDs inside your CDATA[] block. For example, I will create a variable name declaration called var and then add it to the rw snippet I just created (disclaimer: this is just for demonstration purposes, obviously the following code would not be very helpful) which will print out a string. The declarations section would look like this:

<Declarations>
<Literal>
<ID>var</ID>
<ToolTip>Name for the string variable</ToolTip>
<Default>var</Default>
</Literal>
</Declarations>

And then the new CDATA[] section would look like this:

<![CDATA[string $var$ = "Hello World";
Response.Write($var$);
$end$]]>

When you expand that out as a code snippet and fill in the var name, you’ll get a code block like this:

string helloString = “Hello World”;
Response.Write(helloString);

That’s really all there is to it — for more advanced snippets you can look at the built in ones that Microsoft wrote, but this tutorial should give you all the tools you need to write some pretty advanced and time saving snippets.


There is a little used function of Visual Studio that will save you a lot of coding time: Code Snippets. Code Snippets are handy key shortcuts that expand into commonly used .NET constructs such as regions, constructor, loops (do/while/for/foreach), and try/catch blocks. To use a code snippet you can type in its ’shortcut’ and in Intellisense you will see a little piece of paper next to the word indicating that it is indeed a code snippet. Then you press TAB twice, and the code snippet is expanded into the full construct, and depending on the snippet you may be directed to enter some pertinent information.

Let’s try my favorite example: a property declaration with a backing field.

  1. Type in prop and then press TAB twice
  2. You will see an expanded property declaration with green fields, indicating that you need to supply this information.
  3. The first field to fill in will be highlighted in blue, which in this case is ‘int’. Let’s type ’string’ to make a string property, but any .NET type will work.
  4. Now hit TAB again to go to the next field, which is the name of the private variable. Let’s call it _stringProperty.
  5. Press TAB again to go to the public property name. Notice that it filled in the get/set values of the private variable for you. Now you can call the public string StringProperty, and press ENTER to indicate that you are finished (if you press TAB, you will cycle back through the customizable fields).

Now this saves me a lot of time since I can create properties rapidly instead of typing curly braces and get/set over and over. Other huge time savers include foreach/for, try, and cw (which does a Console.WriteLine()).


Exporting a SQL Server Reporting Services 2005 (SSRS) Report Directly to PDF/Excel is a handy way of generating high quality reports without being stuck to using the ReportViewer interface. Sometimes the ReportViewer interface is an unnecessary step, but other times the ReportViewer won’t render correctly even though the underlying report is correct. This is especially true when your audience might use Firefox or Safari (or anything other than IE), since the ReportViewer control almost never outputs a readable report. Of course it would be nice to just have a button on your page that generates a PDF or Excel file in any browser, and uses a SSRS back-end to do all of the report creating and heavy lifting.

The following code will show how to export such a report, including the passing of an arbirary number of custom parameters. Note that the identity of the application pool that your website runs under will need to have at least “browser” access to the folder containing the report you want to display. This is usually pretty simple if both the IIS and SSRS server are withing the same domain, but it might be tricky if this is not the case.

Microsoft.Reporting.WebForms.ReportViewer rview = new Microsoft.Reporting.WebForms.ReportViewer();
//Web Address of your report server (ex: http://rserver/reportserver)

rview.ServerReport.ReportServerUrl = new Uri(WebConfigurationManager.AppSettings["ReportServer"]);

System.Collections.Generic.List<Microsoft.Reporting.WebForms.ReportParameter> paramList = new System.Collections.Generic.List<Microsoft.Reporting.WebForms.ReportParameter>();

paramList.Add(new Microsoft.Reporting.WebForms.ReportParameter(“Param1″, “Value1″));
paramList.Add(new Microsoft.Reporting.WebForms.ReportParameter(“Param2″, “Value2″));

rview.ServerReport.ReportPath = “/ReportFolder/ReportName”;
rview.ServerReport.SetParameters(paramList);

string mimeType, encoding, extension, deviceInfo;
string[] streamids;
Microsoft.Reporting.WebForms.Warning[] warnings;
string format = “PDF”; //Desired format goes here (PDF, Excel, or Image)

deviceInfo =
“<DeviceInfo>” +
“<SimplePageHeaders>True</SimplePageHeaders>” +
“</DeviceInfo>”;

byte[] bytes = rview.ServerReport.Render(format, deviceInfo, out mimeType, out encoding, out extension, out streamids, out warnings);

Response.Clear();

if (format == “PDF”)
{
Response.ContentType = “application/pdf”;
Response.AddHeader(“Content-disposition”, “filename=output.pdf”);
}
else if (format == “Excel”)
{
Response.ContentType = “application/excel”;
Response.AddHeader(“Content-disposition”, “filename=output.xls”);
}

Response.OutputStream.Write(bytes, 0, bytes.Length);
Response.OutputStream.Flush();
Response.OutputStream.Close();
Response.Flush();
Response.Close();

One potential issue that you might run into upon deploying your project is that your application server may not have the ReportViewer DLLs that are needed. You have two options in this case. The first is to copy the three Microsoft.ReportViewer.*.dll’s (ReportViewer.Common.dll, ReportViewer.ProcessingObjectModel.dll, and ReportViewer.WebForms.dll) from your developement computer into the BIN folder of your application server (or into the GAC). The second option (though I have not verified it), is to install the SSRS redistributable on the application server (http://www.microsoft.com/downloads/details.aspx?familyid=8a166cac-758d-45c8-b637-dd7726e61367&displaylang=en).

Check out http://www.microsoft.com/sql/technologies/reporting/default.mspx for good SSRS resources, including some nice learning tools and report packs.


My development environment involves working on code that is not stored locally on my machine, but on a centralized development server on our network. I like working this way because it allows me to decouple my computer from IIS, and running the remote debugger (comes on the Visual Studio 2005 DVD) is really simple.

However, a problem arises when you try to run certain assemblies from a your remote development machine — you get compilation errors telling you that an assembly can’t be loaded because permission request problems. I first noticed this issue when I started using the ASP.NET AJAX (formerly Atlas) binary builds. You will get one of the following two error messages when you try to build your project:

1) Request for the permission of type ‘System.Web.AspNetHostingPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=xxxx’ failed.

2) ASP.NET runtime error: Could not load file or assembly ‘Microsoft.Practices.ObjectBuilder, Version=1.0.51205.0, Culture=neutral, PublicKeyToken=null’ or one of its dependencies. Failed to grant minimum permission requests. [Note: The specific assembly information may differ depending on your project]

These errors occur because your remote development environment does not have enough permission to compile the ASP.NET AJAX (or other) DLLs on your system [For a nice explanation of Code Access Security, see http://www.15seconds.com/issue/040121.htm]. In order to give your remote development environment permission, you need to configure the Code Groups inside of the .NET Framework 2.0 Configuration MMC to allow your local intranet to be fully trusted by your machine. To do this, follow these steps on your development (local) computer:

  1. Go to Control Panel–>Administrative Tools on your computer.
  2. Click on .NET Framework 2.0 Configuration.
  3. Drill down to My Computer –> Runtime Security Policy –> Machine –> Code Groups –> All Code –> LocalIntranet Zone.
  4. Right click on LocalIntranet Zone, and choose Properties.
  5. Click on the Permission Set Tab and change the Permission Set to “Full Trust”.
  6. Hit Apply and OK and close the .NET 2.0 Framework Configuration window.
  7. Restart Visual Studio

Now you should be able to build, debug and run your project with your ASP.NET AJAX DLLs included in the BIN folder. Happy Coding!

PS: I have heard that adding the problem DLLs to your GAC (on your machine and the remote development machine) will fix the problem, but I have not verified this. I did not want to do this in my environment because we work with different versions of AJAX and other DLLs and I want to keep versioning by project.