Jack @ ASP.NET

As a software engineer, I focus on .NET, especially asp.net, C#, WCF and so on, and I am also very interested in Search Engine Optimization.

Entries Tagged ‘Code’

Tips and Tricks for the Visual Studio .NET IDE

1. Record and play temporary macro

Ctrl+Shift+R to record a new temporary macro. Press Ctrl+Shift+R to stop recording. Ctrl+Shift+P to play the recorded macro.

This works similar to *recording* in Vim. If you think you are going to be repeating a set of keyboard keys, then record them once and play them each time after.

2. Multiple copy/pastes

Ctrl+Shift+V cycles through the clipboard ring. You can copy/cut multiple times from one area of code, then go to another area and paste them one after another.

3. Drag and drop code snippets

The Toolbox (Ctrl+Alt+X) window has multiple tabs. You can drag and drop code onto this window and copy it elsewhere. Some tabs do not allow dropping code into them; those that allow will have the appropriate icon. The General tab works for me.

4. Previous cursor positions

Ctrl+- i.e. Ctrl + Hyphen. This cycles you through the code positions you visited.

Ctrl+Shift+- to navigate in the opposite direction.

5. Incremental search

To incrementally search for text as you type, first press Ctrl+i. Then type the word you want to search. Hit backspace to clear a character and enter to finish. Pressing F3 after this will work as usual, i.e. search for the next occurrence of previous search.

Ctrl+iCtrl+i works like F3.

6. Matching brace/comment/region/quote

Ctrl+] takes you to the matching brace. It also takes you to the matching comment, region or quote depending on what is at the cursor now.

7. Vertical block selection

Press Alt and then select the area you want with your mouse.

8. Closing/Showing support windows

There are a bunch of necessary/useful windows in the Visual Studio IDE like Properties (F4), Solution Explorer (Ctrl+Alt+L), Output Window (Ctrl+Alt+O), Task List (Ctrl+Alt+K) etc. However, they take up a lot of space. An easy way around this is to use the auto hide feature.

Open the window you want. Right click on its title and choose Auto Hide. The window will dock in whenever your mouse is not hovering over it.

9. Tab groups – group code editor windows

If you have many source code windows open, you can group them logically using tab groups. Right click the tab of the code window and choose New Horizontal Tab Group. This will move the window into a split window, allowing you to see both files. You can add more files to this new tab group and also move files back to the previous group by choosing Move To Previous Tab Group.

10. Track things you have to do with Task List

The Task List window (Ctrl+Alt+K) allows you to keep track of the things you have to do. Right click on the Task List window and choose Show Tasks|All to see a list of tasks. Ctrl+Shift+F12 to cycle through your list of tasks.

By default, comments marked with a TODO will appear in the task list.

11. Edit Task List Comment Tokens

You can add your own set of comment tokens (like the TODO comment token). Goto Tools|Options|Environment|Task List|Comment Tokens and make your changes. You can change the priority appearance of each comment token too.

12. Add Task List Shortcut

Add a shortcut to the task list with Ctrl+K, Ctrl+H. This will add the current line to the task list.

13. Auto-complete

Press Ctrl+Space or Alt+RightArrow to auto-complete the word. Intellisense suggestions may pop up a window if there is more than one possibility.

14. Intellisense suggestions window

Press Ctrl+Shift+Space to bring up the intellisense suggestions window. When giving parameters for functions, I often need to escape the suggestions window to check another part of code. To bring it back, I used to delete a comma and then type it again; but this is easier.

15. Word wrap

Ctrl+R Ctrl+R

or

Tools|Options|Text Editor|All Languages|General|Word Wrap

If you want to set this option for only one language, then choose the appropriate language instead of All Languages.

16. Line numbering

Tools|Options|Text Editor|All Languages|General|Line numbers.

  • Digg
  • DZone
  • Yahoo Buzz
  • Delicious
  • Reddit
  • StumbleUpon
  • SmakNews
  • Jumptags
  • Ping
  • Share/Bookmark

ASP.NET Interview Questions and Answers

1. Explain the differences between Server-side and Client-side code?
Server-side code executes on the server. Client-side code executes in the client’s browser.aspnet

2. What type of code (server or client) is found in a Code-Behind class?
Server-side code. Since code-behind is executed on the server. However, during the code-behind’s execution on the server, it can render client-side code such as JavaScript to be processed in the clients browser. But just to be clear, code-behind executes on the server, thus making it server-side code.

3. Should user input data validation occur server-side or client-side?
All user input data validation should occur on the server at a minimum. Additionally, client-side validation can be performed where deemed appropriate and feasable to provide a richer, more responsive experience for the user.

4. What is the difference between Server.Transfer and Response.Redirect?
Why would I choose one over the other? Server.Transfer transfers page processing from one page directly to the next page without making a round-trip back to the client’s browser. This provides a faster response with a little less overhead on the server. Server.Transfer does not update the clients url history list or current url. Response.Redirect is used to redirect the user’s browser to another page or site. This performas a trip back to the client where the client’s browser is redirected to the new page. The user’s browser history list is updated to reflect the new address.

5. What is the Global.asax used for?
The Global.asax (including the Global.asax.cs file) is used to implement application and session level events.

6. What are the Application_Start and Session_Start subroutines used for?
This is where you can set the specific variables for the Application and Session objects.

7. Whats an assembly?
Assemblies are the building blocks of the .NET framework.

8. Can you explain what inheritance is and an example of when you might use it?
When you want to inherit (use the functionality of) another class. Example: With a base class named Employee, a Manager class could be derived from the Employee base class.

9. Describe the difference between inline and code behind.
Inline code written along side the html in a page. Code-behind is code written in a separate file and referenced by the .aspx page.

10. Explain what a diffgram is, and a good use for one?
The DiffGram is one of the two XML formats that you can use to render DataSet object contents to XML. A good use is reading database data to an XML file to be sent to a Web Service.

  • Digg
  • DZone
  • Yahoo Buzz
  • Delicious
  • Reddit
  • StumbleUpon
  • SmakNews
  • Jumptags
  • Ping
  • Share/Bookmark

How to Hack the ASP.NET Parser

The ASP.NET compliation system is pretty complex. There are all kinds of extensibility points, including BuildProviders, PageParserFilters, ControlBuilders, ExpressionBuilders and the list goes on. One unknown *feature* of the parser is it’s ability to generate code from something called an InstanceDescriptor.

The parser has a special way of dealing with ITemplate properties so if we try to do this:

<asp:Repeater ID="repeater" runat="server" ItemTemplate="~/MyUserControl.ascx">
</asp:Repeater>

It fails because the there is no way to convert the string “~/MyUserControl.ascx” into an ITemplate.

The parser uses the TypeConverter attribute defined on properties it parses to aid in the conversion.  Enter TypeDescriptionProvider. These complex beasts are used at the heart of all designers in Visual Studio. There are used for things like populating the property grid, and adding and removing properties dynamically, basically a general purpose metadata API (think of it as an abstraction on top of reflection).

VirtualPathTemplate

The code we are going to generate will instantiate a VirtualPathTemplate with a virtual path pointing to a user control on our site. Normally when you define a template in markup, a special type called CompiledTemplateBuilder (which points to a delegate that builds the template at runtime) is assigned to it. We want to replace a line of code that looks like this:

repeater.ItemTemplate = new CompiledTemplateBuilder(BuildTemplate);

to this

repeater.ItemTemplate = new VirtualPathTemplate("~/MyUserControl.ascx");

TypeDescriptionProvider

After overriding about 4 classes (TypeDescriptionProvider, CustomTypeDescriptor, PropertyDescriptor, and finally TypeConverter) we are able to control what happens when the parser asks, “can we convert “~/MyUserControl.ascx” to an ITemplate?”.

Here is the code for the TemplateTypeConverter:

public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
// Allow InstanceDescriptor so that the code gen engine can use it to generate the correct
// code for the ITemplate property
return destinationType == typeof(InstanceDescriptor) || _converter.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
var descriptorProvider = value as IInstanceDescriptorProvider;
if (descriptorProvider != null) {
return descriptorProvider.Descriptor;
    }
return _converter.ConvertTo(context, culture, value, destinationType);
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
return sourceType == typeof(string) || _converter.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
string stringValue = value as string;
if (stringValue != null) {
if (stringValue.StartsWith("~/")) {                    
// Assume this is a virtual path and return the instance description provider
// for it
return new VirtualPathInstanceDescriptorProvider(stringValue);
        }                
    }
return _converter.ConvertFrom(context, culture, value);
}

First the parser asks the converter if it can convert from a string so we always say yes. In ConvertFrom we try to convert the value to a string and check if the path starts with “~/” in order to determine if it’s a virtual path. If it is a virtual path we return an object that knows how to get an InstanceDescriptor from the virtual path (VirtualPathInstanceDescriptorProvider). Now we have successfully parsed the control.

Next the code generator tries to generate code for the ITemplate property. The code generator will eventually ask if it can convert the object we returned earlier (VirtualPathInstanceDescriptorProvider) to an InstanceDescriptor. The implementation of VirtualPathInstanceDescriptorProvider returns an instance descriptor that wraps a constructor info for a custom template we are going to use:

internal class VirtualPathInstanceDescriptorProvider : IInstanceDescriptorProvider {
private string _virtualPath;
private static ConstructorInfo s_Constructor = GetConstructor();
private static ConstructorInfo GetConstructor() {
return typeof(VirtualPathTemplate).GetConstructor(new[] { typeof(string) });
    }
public InstanceDescriptor Descriptor {
get {
return new InstanceDescriptor(s_Constructor, new[] { _virtualPath });
        }
    }
public VirtualPathInstanceDescriptorProvider(string virtualPath) {            
        _virtualPath = virtualPath;
    }        
}

The code generation engine then generates the resulting code we wanted to specify above using the constructor info and virtual path.

At runtime we use BuildManager.CreateInstanceFromVirtualPath(“~/MyUserControl.ascx”) to create an instance of the user control and add it to the control’s collection and we’re done.

public class VirtualPathTemplate : ITemplate {
private string _virtualPath;
public VirtualPathTemplate(string virtualPath) {
        _virtualPath = virtualPath;
    }
public void InstantiateIn(Control container) {
// Try to create the control from the virtual path
Control control = (Control)BuildManager.CreateInstanceFromVirtualPath(_virtualPath, typeof(Control));
if (control != null) {
// Add it to the controls collection
            container.Controls.Add(control);
        }            
    }
}

  • Digg
  • DZone
  • Yahoo Buzz
  • Delicious
  • Reddit
  • StumbleUpon
  • SmakNews
  • Jumptags
  • Ping
  • Share/Bookmark

Convert a Web Site Project to a Web Application Project

Open and Verify your Visual Studio Web Site Project
Before converting your WSP to a WAP, you should open it in Visual Studio and verify that is it working correctly.  This will help prevent the need to research errors that have nothing to do with the conversion process.

  1. In the File menu, click Open Web Site.
  2. The Open Web Site dialog box is displayed.
  3. Select the project folder that you want to open, and then click Open.
  4. In the Build menu, click Build Web Site.
  5. In the Debug menu, click Start Debugging. Alternatively, you can press F5.
  6. Verify your project compiles and runs as expected

Create a new, empty Visual Studio WAP
A good strategy for converting a WSP to a WAP is to create a new, blank Visual Studio Web Application Project in a separate directory, but in the same solution. This avoids changing any part of the existing Web site files. It also allows you to copy existing functionality and files into the new WAP easily, within the same Visual Studio instance.

  1. In the File menu, click Add, and then click New Project.
  2. The Add New Project dialog box is displayed.
  3. In the Installed Templates section of the Add New Project dialog box, expand the language that you want to use, and then select Web to display the Web-related templates.
  4. Select Empty ASP.NET Web Application.
  5. Type values for Name, Location, and then click OK to create the Web Application Project.
  6. After the project has been created, delete the Web.config file that is created automatically.

WSPandWAP

Set Project / Assembly References
If the WSP required additional project or assembly references, you need to add them to the WAP. You can see the list of default references associated with the new (empty) Visual Studio Web Application Project under the References node in Solution Explorer.

  1. In the Solution Explorer, make sure Show All Files is turned on.
  2. In the Solution Explorer, right-click References, and then click Add Reference.
  3. The Add Reference dialog box is displayed.
  4. Select the reference that you have already added in the Web Site Project and then click OK.
  5. Note: To help prevent errors, add references to the Web Application Project for assemblies that existed in the \bin folder of the WSP.

AddRef

Copy and Convert the App_Code folder from the Web Site Project to the Web Application Project
In WSPs, the files in the App_Code folder are all compiled together and then referenced (automatically) as a “dll” by all other files in the WSP. In WAPs, this is not the case. All code is compiled together as one .dll. I’ve found that copying the App_Code folder over first and converting it to the WAP model helps to head off some dependency issues which could arise if one copied the entire site, converted, and then tried to compile.

  1. In the Solution Explorer, copy the entire App_Code folder from the WSP to the WAP
  2. In the Solution Explorer, select the WAP’s root node; right-click, select Convert to Web Application
  3. You will see our standard Convert to Web Application confirmation dialog.  Select “Yes” to this dialog.
  4. The App_Code folder should now be renamed to Old_App_Code folder
  5. Note: Do NOT name it back. As mentioned above, in the WAP model all code will be compiled into one assembly. At runtime, ASP.NET doesn’t know what type of project model you have created and will take anything in the “App_Code” folder and create a dynamic assembly for it, thereby causing “could not load type” exceptions as there would be duplicate types exists in two assemblies (the one for the VS web application and the one for App_Code).  Learn more about why App_Code folder does not work well with WAPs.
  6. Compile the WAP
  7. If you see an error, the most likely causes are:
    1. Missing assembly reference. See the section above to add missing references to your project.
    2. Files marked with Build Action = Content instead of Build Action = Compile. Any file you want compiled should be marked as such.
    3. To set the Build Action property:
      1. Select the file in the Solution Explorer
      2. Press F4 (Brings up the File’s Property Grid)
      3. Look at the Build Action property. Change as necessary.

converttowap

Copy and Convert the remaining Files and Folders from the WSP to the WAP
Once your Old_App_Code folder is compiled (by compiling your WAP in the step above), your WAP will have an assembly in the \bin directory. This will make it easier for the remaining files you are copying over to successfully compile, especially if they reference or use code in the files contained within that folder.

  1. Select the remaining files / folders from the WSP project and copy them into the WAP.
  2. Make sure not to copy the App_Code folder again.
  3. In the Solution Explorer, right click the root node of the WAP and select Convert to Web Application.
    1. Don’t worry, this won’t affect (or try to reconvert) any files or the Old_App_Code folder you have already converted.
  4. Note: This will cause VS to automatically generate a .designer.cs (or .vb) file for each page, user-control, and master page in the project. Additionally, each .aspx/.ascx will be modified to use the ‘Codebehind’ instead of the ‘CodeFile’ attribute in the Page directive.
    1. Example of the ‘CodeFile’ to ‘Codebehind’ change
      1. WSP file:  <%@ Page Title=”Home Page” Language=”C#” CodeFile=”Default.aspx.cs” Inherits=”_Default” %>
      2. Converted WAP file:  <%@ Page Title=”Home Page” Language=”C#” Inherits=”_Default” Codebehind=”Default.aspx.cs” %>

convertedfiles

Compile your WAP
After all the files have been added and converted, you should build your project again to see if there are any compilation errors. At this point, some of the most likely causes of errors are:

  1. Code files set with Build Action = Content. These should be changed to Compile. Refer to the above section.
  2. Missing project or assembly references. See above for steps for adding project or assembly references.
  3. Class name collisions. In the WSP model, each .aspx and associated codefile was compiled together as a separate, individual unit. Therefore, one could have files such as foo\widget.ascx.cs and bar\widget.ascx.cs where the classes were the same. Once these files are moved to a WAP and all compiled together, class name collisions occur with errors something like, “has multiple definitions with identical signatures”. If this occurs, unique class names should be created.

Run your WAP
After completing the above steps and you have a WAP which successfully compiles, you are ready to try running your application. One of the most common problems I’ve seen encountered is the “Unknown server tag ‘SomeTag: Control’ (as it applies to user controls and such)”. This can be corrected in one of two ways.

  1. Add or modify the register directive on the page that is using the control. This will only register it for this specific page.
    1. <%@ Register Namespace”namespace the control is in” TagPrefix=”SomeTag” Assembly=”Name of dll compiled into the \bin folder” %>
  2. Register the control in the Web.config, making it available to all pages in the project
    1. In the <pages><controls> section add the following:
    2. <add tagPrefix=”SomeTag” namespace=”namespace the control is in” assembly=” Name of dll compiled into the \bin folder” />
  • Digg
  • DZone
  • Yahoo Buzz
  • Delicious
  • Reddit
  • StumbleUpon
  • SmakNews
  • Jumptags
  • Ping
  • Share/Bookmark