Raj Kaimal

Creating an ASP.NET report using Visual Studio 2010 - Part 1

This tutorial walks you through creating an ASP.NET report based on the Northwind sample database. It shows how to add a client report definition file (RDLC), create a dataset for the RDLC, define queries using LINQ to Entities, design the report and add a ReportViewer web control to render the report in a ASP.NET web page. The report will have a chart control. The result can be filtered by two drop downs at the top..

At the end of the walkthrough, you should have a UI like the following.  As shown, there is a product list report with an embedded chart. The chart shows the sum of Unit price for a given category. It is possible to filter the results by Category and Supplier. The drop downs auto post back when the selection is changed.  This demo uses Visual Studio 2010 RTM.

This post is split into three parts. The last part has the sample code attached.

Creating an ASP.NET report using Visual Studio 2010 - Part 2
Creating an ASP.NET report using Visual Studio 2010 - Part 3

image 

Lets start by creating a new ASP.NET empty web application called “NorthwindReports”
image
Creating the Data Access Layer (DAL)

Add a web form called index.aspx to the root directory. You do this by right clicking on the NorthwindReports web project and selecting “Add item..”
.
Create a folder called “DAL”. We will store all our data access methods and any data transfer objects in here.

 image

Right click on the DAL folder and add a ADO.NET Entity data model called Northwind.

image

Select “Generate from database” and click Next.

image
Create a connection to your database containing the Northwind sample database and click Next.

image 
From the table list, select Categories, Products and Suppliers and click next.

image
Our Entity data model gets created and looks like this:

image  
Adding data transfer objects

Right click on the DAL folder and add a ProductViewModel. Add the following code. This class contains properties we need to render our report.

public class ProductViewModel
{
    public int? ProductID { get; set; }
    public string ProductName { get; set; }
    public System.Nullable<decimal> UnitPrice { get; set; }
    public string CategoryName { get; set; }
    public int? CategoryID { get; set; }
    public int? SupplierID { get; set; }
    public bool Discontinued { get; set; }
}


Add a SupplierViewModel class. This will be used to render the supplier DropDownlist.
public class SupplierViewModel
{
    public string CompanyName { get; set; }
    public int SupplierID { get; set; }
}

Add a CategoryViewModel class.
public class CategoryViewModel
{
    public string CategoryName { get; set; }
    public int CategoryID { get; set; }
}

Create an IProductRepository interface. This will contain the signatures of all the methods we need when accessing the entity model.  This step is not needed but follows the repository pattern.

interface IProductRepository
    {
        IQueryable<Product> GetProducts();
        IQueryable<ProductViewModel> GetProductsProjected(int? supplierID, int? categoryID);
        IQueryable<SupplierViewModel> GetSuppliers();
        IQueryable<CategoryViewModel> GetCategories();
    }

Create a ProductRepository class that implements the IProductReposity above. The methods available in this class are as follows:

  • GetProducts – returns an IQueryable of all products.
  • GetProductsProjected – returns an IQueryable of ProductViewModel. The method filters all the products based on SupplierId and CategoryId if any. It then projects the result into the ProductViewModel.
  • GetSuppliers() – returns an IQueryable of all suppliers projected into a SupplierViewModel
  • GetCategories() – returns an IQueryable of all categories projected into a CategoryViewModel 
public class ProductRepository : IProductRepository
{
    /// <summary>
    /// IQueryable of all Products
    /// </summary>
    /// <returns></returns>
    public IQueryable<Product> GetProducts()
    {
        var dataContext = new NorthwindEntities();
        var products = from p in dataContext.Products
                       select p;
        return products;
    }
 
    /// <summary>
    /// IQueryable of Projects projected 
    /// into the ProductViewModel class
    /// </summary>
    /// <returns></returns>
    public IQueryable<ProductViewModel> GetProductsProjected(int? supplierID, int? categoryID)
    {
        var projectedProducts = from p in GetProducts()
                                select new ProductViewModel
                                {
                                    ProductID = p.ProductID,
                                    ProductName = p.ProductName,
                                    UnitPrice = p.UnitPrice,
                                    CategoryName = p.Category.CategoryName,
                                    CategoryID = p.CategoryID,
                                    SupplierID = p.SupplierID,
                                    Discontinued = p.Discontinued
                                };
        // Filter on SupplierID 
        if (supplierID.HasValue)
        {
            projectedProducts = projectedProducts.Where(a => a.SupplierID == supplierID);
        }
 
        // Filter on CategoryID 
        if (categoryID.HasValue)
        {
            projectedProducts = projectedProducts.Where(a => a.CategoryID == categoryID);
        }
 
        return projectedProducts;
    }
 
 
    public IQueryable<SupplierViewModel> GetSuppliers()
    {
        var dataContext = new NorthwindEntities();
        var suppliers = from s in dataContext.Suppliers
                        select new SupplierViewModel
                        {
                            SupplierID = s.SupplierID,
                            CompanyName = s.CompanyName
                        };
        return suppliers;
    }
 
    public IQueryable<CategoryViewModel> GetCategories()
    {
        var dataContext = new NorthwindEntities();
        var categories = from c in dataContext.Categories
                         select new CategoryViewModel
                         {
                             CategoryID = c.CategoryID,
                             CategoryName = c.CategoryName
                         };
        return categories;
    }
}


Your solution explorer should look like the following.
image

Build your project and make sure you don’t get any errors.

In the next part, we will see how to create the client report definition file using the Report Wizard.

 

Creating an ASP.NET report using Visual Studio 2010 - Part 2

 

 

Other Posts

ASP.NET MVC Paging/Sorting/Filtering using the MVCContrib Grid and Pager

This post walks you through creating a UI for paging, sorting and filtering a list of data items. It makes use of the excellent MVCContrib Grid and Pager Html UI helpers. A sample project is attached at the bottom.

Our UI will eventually look like this. The application will make use of the Northwind database.

image
The top portion of the page has a filter area region. The filter region is enclosed in a form tag. The select lists are wired up with jQuery to auto post back the form.

The page has a pager region at the top and bottom of the product list.

The product list has a link to display more details about a given product. The column headings are clickable for sorting and an icon shows the sort direction.

A request with this UI will look similar to this : /Products?productName=chai&supplierId=29&categoryId=4&Column=CategoryName&Direction=Ascending. This request translates into a request for products that contain the text “chai” and supplierid=29 and categoryid=29. The results are sorted in ascending order by categoryname.

Strongly Typed View Models

The views are written to expect strongly typed objects. We suffix these strongly typed objects with ViewModel and will be used for passing data down to the view. 

The following listing shows the ProductViewModel. This class will be used to hold information about a Product. We use attributes to specify if the property should be hidden and what its heading in the table should be. This metadata will be used by the MvcContrib Grid to render the table. Some of the properties are hidden from the UI ([ScaffoldColumn(false)) but are needed because we will be using those for filtering when writing our LINQ query.
public class ProductViewModel
{
    [ScaffoldColumn(false)]
    public int? ProductID { get; set; }
 
    public string ProductName { get; set; }
 
    [DisplayName("Unit Price")]
    [DisplayFormat(DataFormatString = "{0:c}")] 
    public System.Nullable<decimal> UnitPrice { get; set; }
 
    [DisplayName("Category Name")]
    public string CategoryName { get; set; }
 
    [ScaffoldColumn(false)]
    public int? CategoryID { get; set; }
 
    [ScaffoldColumn(false)]
    public int? SupplierID { get; set; }
 
    public bool Discontinued { get; set; }
}

The following diagram shows the rest of the key ViewModels in our design.

image
We have a container class called ProductListContainerViewModel which has nested classes.

The ProductPagedList is of type IPagination<ProductViewModel>. The MvcContrib expects the IPagination<T> interface to determine the page number and page size of the collection we are working with. You convert any IEnumerable<T> into an IPagination<T> by calling the AsPagination extension method in the MvcContrib library. It also creates a paged set of type ProductViewModel.

The ProductFilterViewModel class holds information about the different select lists and the ProductName being searched on. It also holds the state of any previously selected item in the lists and the previous search criteria (you will recall that this type of state information was stored in Viewstate when working with WebForms). With MVC there is no default state storage and so all state has to be fetched and passed back to the view.

The GridSortOptions is a type defined in the MvcContrib library and is used by the Grid to determine the current column being sorted on and the current sort direction.


The following shows the view and partial views used to render our UI. The Index view expects a Model of type ProductListContainerViewModel.

image
Index.aspx code:

<%Html.RenderPartial("SearchFilters", Model.ProductFilterViewModel); %>
<% Html.RenderPartial("Pager", Model.ProductPagedList); %>
<% Html.RenderPartial("SearchResults", Model); %>
<% Html.RenderPartial("Pager", Model.ProductPagedList); %>

The View contains a partial view “SearchFilters” and passes it the ProductViewFilterContainer. The SearchFilter uses this Model to render all the search lists and textbox.

The partial view “Pager” uses the ProductPageList which implements the interface IPagination. The “Pager” view contains the MvcContrib Pager helper used to render the paging information. This view is repeated twice since we want the pager UI to be available at the top and bottom of the product list. The Pager partial view is located in the Shared directory so that it can be reused across Views.

The partial view “SearchResults” uses the ProductListContainer model. This partial view contains the MvcContrib Grid which needs both the ProdctPagedList and GridSortOptions to render itself.

The Controller Action 
The application receives this GET request and maps it to the Index method of the ProductController.
Within the action we create an IQueryable<ProductViewModel> by calling the GetProductsProjected() method.

/// <summary>
/// This method takes in a filter list, paging/sort options and applies
/// them to an IQueryable of type ProductViewModel
/// </summary>
/// <returns>
/// The return object is a container that holds the sorted/paged list,
/// state for the fiters and state about the current sorted column
/// </returns>
public ActionResult Index(
    string productName, 
    int? supplierID, 
    int? categoryID, 
    GridSortOptions gridSortOptions, 
    int? page)
{
 
    var productList = productRepository.GetProductsProjected();
 
    // Set default sort column
    if (string.IsNullOrWhiteSpace(gridSortOptions.Column))
    {
        gridSortOptions.Column = "ProductID";
    }
 
    // Filter on SupplierID 
    if (supplierID.HasValue)
    {
        productList.Where(a => a.SupplierID == supplierID);
    }
 
    // Filter on CategoryID 
    if (categoryID.HasValue)
    {
        productList = productList.Where(a => a.CategoryID == categoryID);
    }
 
    // Filter on ProductName
    if (!string.IsNullOrWhiteSpace(productName))
    {
        productList = productList.Where(a => a.ProductName.Contains(productName));
    }
 
    // Create all filter data and set current values if any
    // These values will be used to set the state of the select list and textbox
    // by sending it back to the view.
    var productFilterViewModel = new ProductFilterViewModel();
    productFilterViewModel.SelectedCategoryID = categoryID ?? -1;
    productFilterViewModel.SelectedSupplierID = supplierID ?? -1;
    productFilterViewModel.Fill();
 
    // Order and page the product list
    var productPagedList = productList
           .OrderBy(gridSortOptions.Column, gridSortOptions.Direction)
           .AsPagination(page ?? 1, 10);
 
 
    var productListContainer = new ProductListContainerViewModel
    {
        ProductPagedList = productPagedList,
        ProductFilterViewModel = productFilterViewModel,
        GridSortOptions = gridSortOptions
    };
 
    return View(productListContainer);
}

The supplier, category and productname filters are applied to this IQueryable if any are present in the request. The ProductPagedList class is created by applying a sort order and calling the AsPagination method. Finally, the ProductListContainerViewModel class is created and returned to the view.

You have seen how to use strongly typed views with the MvcContrib Grid and Pager to render a clean lightweight UI with strongly typed views. You also saw how to use partial views to get data from the strongly typed model passed to it from the parent view. The code also shows you how to use jQuery to auto post back.

The nice thing about the MvcContrib Pager and Grid is that it is aware of the original query string and keeps it intact when creating links for sorting and paging.


The sample is attached below. Don’t forget to change your connection string to point to the server containing the Northwind database.


Related Posts:

My name is Kobayashi. I work for Keyser Soze.

Posted by rajbk | 11 comment(s)

Autopostback select lists in ASP.NET MVC using jQuery

This tiny snippet of code show you how to have your select lists autopostback its containing form when the selected value changes.

When the DOM is fully loaded, we get all select nodes that have an attribute of “data-autopostback” with a value of “true”.

We wire up the “change” JavaScript event to all these select nodes. This event is fired as soon as the user changes their selection with the mouse. 

When the event is fired, we find the closest form tag for the select node that raised the event and submit the form.

$(document).ready(function () {
    $("select:[data-autopostback=true]").change(function () {
        $(this).closest("form").submit();
    });
});

A select tag with autopostback enabled will look like this

<select id="selCategory" name="Category" data-autopostback="true">
<option value='1'>Electronics</option>
<option value='2'>Books</option>
</select>


The reason I am using “data-" suffix in the attribute is to be HTML5 Compliant.

A custom data attribute is an attribute in no namespace whose name starts with the string "data-", has at least one character after the hyphen, is XML-compatible, and contains no characters in the range U+0041 to U+005A (LATIN CAPITAL LETTER A to LATIN CAPITAL LETTER Z).

The snippet can be used with any HTML page.
Posted by rajbk | 4 comment(s)
Filed under: , ,

A basic T4 template for generating Model Metadata in ASP.NET MVC2

I have been learning about T4 templates recently by looking at the awesome ADO.NET POCO entity generator. By using the POCO entity generator template as a base, I created a T4 template which generates metadata classes for a given Entity Data Model. This speeds coding by reducing the amount of typing required when creating view specific model and its metadata.

To use this template,

1) Download the template provided at the bottom.

2) Set two values in the template file. The first one should point to the EDM you wish to generate metadata for. The second is used to suffix the namespace and classes that get generated.

string inputFile = @"Northwind.edmx";
string suffix = "AutoMetadata";

3) Add the template to your MVC 2 Visual Studio 2010 project.

Once you add it, a number of classes will get added to your project based on the number of entities you have. 

image 
One of these classes is shown below. Note that the DisplayName, Required and StringLength attributes have been added by the t4 template.
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
 
using System; 
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
 
namespace NorthwindSales.ModelsAutoMetadata
{
    public partial class CustomerAutoMetadata
    {
            
        [DisplayName("Customer ID")]
        [Required]
        [StringLength(5)]
        public string CustomerID { get; set; }
            
        [DisplayName("Company Name")]
        [Required]
        [StringLength(40)]
        public string CompanyName { get; set; }
            
        [DisplayName("Contact Name")]
        [StringLength(30)]
        public string ContactName { get; set; }
            
        [DisplayName("Contact Title")]
        [StringLength(30)]
        public string ContactTitle { get; set; }
            
        [DisplayName("Address")]
        [StringLength(60)]
        public string Address { get; set; }
            
        [DisplayName("City")]
        [StringLength(15)]
        public string City { get; set; }
            
        [DisplayName("Region")]
        [StringLength(15)]
        public string Region { get; set; }
            
        [DisplayName("Postal Code")]
        [StringLength(10)]
        public string PostalCode { get; set; }
            
        [DisplayName("Country")]
        [StringLength(15)]
        public string Country { get; set; }
        [DisplayName("Phone")]
        [StringLength(24)]
        public string Phone { get; set; }
            
        [DisplayName("Fax")]
        [StringLength(24)]
        public string Fax { get; set; }
    }
}

 

The following shows how the generated class can be used from your project by creating a partial class with the entity name and setting the MetadataType attribute. Note that any changes to the auto generated files will be overwritten. You can also copy the code in the metadata class generated and create your own ViewModel class. In this case, you are responsible for keeping things in sync just like you would with any ViewModel class.

 
namespace MyProject.Models
{
   [MetadataType(typeof(CustomerAutoMetadata))]
    public partial class Customer
    {
      
    }
}

 
The template is super basic  and does not take into account complex properties. I have tested it with the Northwind database.  Feel free to modify the template to suite your requirements.

Standard disclaimer follows:
Use At Your Own Risk, Works on my machine running VS 2010 RTM/ASP.NET MVC 2

Mr. Incredible: Of course I have a secret identity. I don't know a single superhero who doesn't. Who wants the pressure of being super all the time?

Posted by rajbk | 7 comment(s)
Filed under: , , ,

ActionResult types in MVC2

In ASP.NET MVC, incoming browser requests gets mapped to a controller action method. The action method returns a type of ActionResult in response to the browser request. A basic example is shown below:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}

Here we have an action method called Index that returns an ActionResult. Inside the method we call the View() method on the base Controller. The View() method, as you will see shortly, is a method that returns a ViewResult.

The ActionResult class is the base class for different controller results. The following diagram shows the types derived from the ActionResult type.

image

ASP.NET has a description of these methods

  • ContentResult – Represents a text result.
  • EmptyResult – Represents no result.
  • FileContentResult – Represents a downloadable file (with the binary content).
  • FilePathResult – Represents a downloadable file (with a path).
  • FileStreamResult – Represents a downloadable file (with a file stream).
  • JavaScriptResult – Represents a JavaScript script.
  • JsonResult – Represents a JavaScript Object Notation result that can be used in an AJAX application.
  • PartialViewResult – Represents HTML and markup rendered by a partial view.
  • RedirectResult – Represents a redirection to a new URL.
  • RedirectToRouteResult – Represents a result that performs a redirection by using the specified route values dictionary.
  • ViewResult – Represents HTML and markup rendered by a view.

To return the types shown above, you call methods that are available in the Controller base class. Instead of creating instances of ActionResult or it’s inherited type, you call the helper methods on the Controller class and return it. A list of these methods are shown below.
image 
The helper methods on the controller base class and the ActionResult type they return are listed here (ref: http://msdn.microsoft.com/en-us/library/dd410269.aspx):

Action Result

Helper Method

Description

ViewResult

View

Renders a view as a Web page.

PartialViewResult

PartialView

Renders a partial view, which defines a section of a view that can be rendered inside another view.

RedirectResult

Redirect

Redirects to another action method by using its URL.

RedirectToRouteResult

RedirectToAction

RedirectToRoute

Redirects to another action method.

ContentResult

Content

Returns a user-defined content type.

JsonResult

Json

Returns a serialized JSON object.

JavaScriptResult

JavaScript

Returns a script that can be executed on the client.

FileResult

File

Returns binary output to write to the response.

EmptyResult

(None)

Represents a return value that is used if the action method must return a null result (void).

Methods without an ActionResult return type
The MVC framework will translate action methods that do not return an ActionResult into one. Consider the HomeController below which has methods that do not return any ActionResult types. The methods defined return an int, object and void respectfully.

public class HomeController : Controller
{
    public int Add(int x, int y)
    {
        return x + y;
    }
 
    public Employee GetEmployee()
    {
        return new Employee();
    }
 
    public void DoNothing()
    {
        
    }
}

When a request comes in, the Controller class hands internally uses a ControllerActionInvoker class which inspects the action parameters and invokes the correct action method. The CreateActionResult method in the ControllerActionInvoker class is used to return an ActionResult. This method is shown below. If the result of the action method is null, an EmptyResult instance is returned. If the result is not of type ActionResult, the result is converted to a string and returned as a ContentResult.

protected virtual ActionResult CreateActionResult(ControllerContext controllerContext, ActionDescriptor actionDescriptor, object actionReturnValue) {
    if (actionReturnValue == null) {
        return new EmptyResult();
    }
 
    ActionResult actionResult = (actionReturnValue as ActionResult) ??
        new ContentResult { Content = Convert.ToString(actionReturnValue, CultureInfo.InvariantCulture) };
    return actionResult;
}

 

In the HomeController class above,

  • the DoNothing method will return an instance of the EmptyResult()
    • Renders an empty webpage
  • the GetEmployee() method will return a ContentResult which contains a string that represents the current object
    • Renders the text “MyNameSpace.Controllers.Employee” without quotes.
  • the Add method for a request of /home/add?x=3&y=5 returns a ContentResult
    • Renders the text “8” without quotes.


Unit Testing

The nice thing about the ActionResult types is in unit testing the controller. We can, without starting a web server, create an instance of the Controller, call the methods and verify that the type returned is the expected ActionResult type. We can then inspect the returned type properties and confirm that it contains the expected values.

Enjoy!

Sulley: Hey, Mike, this might sound crazy but I don't think that kid's dangerous.
Mike: Really? Well, in that case, let's keep it. I always wanted a pet that could kill me.

Posted by rajbk | 12 comment(s)
Filed under: , ,

Editing Project files, Resource Editors in VS 2010

Editing Project Files

Visual Studio gives you the ability to easily edit the project file associated with your project (.csproj or .vbproj). You might do this to change settings related to how the project is compiled since proj files are MSBuild files. The ability to edit project files has been available in previous versions of Visual studio and is not a new feature.

One would normally close Visual Studio and edit the proj file using a text editor. 
The better way is to first unload the project in Visual Studio by right clicking on the project in the solution explorer and selecting “Unload Project”

image 
The project gets unloaded and is marked “unavailable”
The project file can now be edited by right clicking on the unloaded project.

image
image  
After editing the file, the project can be reloaded.

image

Resource editors in VS 2010

Visual studio also comes with a number of resource editors (see list here).
For example, you could open a file using the Binary editor like so.

Go to File > Open > File..

Select a File and choose the “Open With..” option in the bottom right.

image 
We are given the option to choose an editor.

image 
Note that clicking on the “Add..” in the dialog above allows you to include your favorite editor.
image 
Choosing the “Binary editor” above allows us to edit the file in hex format. In addition, we can also search for hex bytes or ASCII strings using the Find command.
image 

The “Open With..” option is also available from within the solution explorer as shown below:

image

Enjoy!

 

Mr. Incredible: No matter how many times you save the world, it always manages to get back in jeopardy again. Sometimes I just want it to stay saved! You know, for a little bit? I feel like the maid; I just cleaned up this mess! Can we keep it clean for... for ten minutes!

Posted by rajbk | 2 comment(s)
Filed under: , ,

Localization in ASP.NET MVC 2 using ModelMetadata

This post uses an MVC 2 RTM application inside VS 2010 that is targeting the .NET Framework 4.

.NET 4 DataAnnotations comes with a new Display attribute that has several properties including specifying the value that is used for display in the UI and a ResourceType. Unfortunately, this attribute is new and is not supported in MVC 2 RTM.

The good news is it will be supported and is currently available in the MVC Futures release.

The steps to get this working are shown below:

  1. Download the MVC futures library
     
  2. Add a reference to the Microsoft.Web.MVC.AspNet4 dll.
     
  3. Add a folder in your MVC project where you will store the resx files
    image
     
  4. Open the resx file and change “Access Modifier” to “Public”. This allows the resources to accessible from other assemblies. Internaly, it changes the “Custom Tool” used to generate the code behind from  ResXFileCodeGenerator to “PublicResXFileCodeGenerator”

     image 
  5. Confirm that the “Build Action” of the resx is set to “Embedded Resource”
     
  6. Add your localized strings in the resx.
     
  7. Register the new ModelMetadataProvider
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
     
        RegisterRoutes(RouteTable.Routes);
     
        //Add this
        ModelMetadataProviders.Current = new DataAnnotations4ModelMetadataProvider();
        DataAnnotations4ModelValidatorProvider.RegisterProvider();
    }

     
  8. Use the Display attribute in your Model
    public class Employee
    {
        [Display(Name="ID")]
        public int ID { get; set; }
     
        [Display(ResourceType = typeof(Common), Name="Name")]
        public string Name { get; set; }
    }

  9. Use the new HTML UI Helpers in your strongly typed view:
      <%: Html.EditorForModel() %>
      <%: Html.EditorFor(m => m) %>
      <%: Html.LabelFor(m => m.Name) %>

      ..and you are good to go.

    Adventure is out there!

    Posted by rajbk | 9 comment(s)
    Filed under: , , ,

    Setting up Visual Studio 2010 to step into Microsoft .NET Source Code

    Using the Microsoft Symbol Server to obtain symbol debugging information is now much easier in VS 2010. Microsoft gives you access to their internet symbol server that contains symbol files for most of the .NET framework including the recently announced availability of MVC 2 Symbols. 

    SETUP

    In VS 2010 RTM, go to Tools –> Options –> Debugging –> General. Check “Enable .NET Framework source stepping”
    image
    We get the following dialog box

     image
    This automatically disables “Enable My Code”
     image
    Go to Debugging –> Symbols and Check “Microsoft Symbol Servers”. You can selectively exclude modules if you want to.
      image
    You will get a warning dialog like so:
    image
    Hitting OK will start the download process
      image
    The setup is complete. You are now ready to start debugging!


    DEBUGGING

    Add a break point to your application and run the application in debug mode (F5 shortcut for me). Go to your call stack when you hit the break point. Right click on a frame that is grayed out.
    image
    Select “Load Symbols from” “Microsoft Symbol Servers”. VS will begin a one time download of that assembly. This assembly will be cached locally so you don’t have to wait for the download the next time you debug the app.
    image 
    We get a one time license agreement dialog box
    image

    You might see an error like the one below regarding different encoding (hopefully will be fixed).
    image  
    Assemblies for which the symbols have been loaded are no longer grayed out. Double clicking on any entry in the call stack should now directly take you to the source code for that assembly.

    image

    image

    AFAIK, not all symbols are available on the MS symbol server. In cases like that you will see a tab like the one below and be given the option to “Show Disassembly”.

    image

    Enjoy!

     

    Check out this post also: VS 2010 Debugger Improvements (BreakPoints, DataTips, Import/Export)

    Newsreel Announcer: Humiliated, Muntz vows a return to Paradise Falls and promises to capture the beast alive!
    Charles Muntz: [speaking to a large audience outside in the newsreel] I promise to capture the beast alive, and I will not come back until I do!

    Posted by rajbk | 10 comment(s)
    Filed under: , , , , ,

    ASP.NET Dynamic Data Deployment Error

    You have an ASP.NET 3.5 dynamic data website that works great on your local box. When you deploy it to your production machine and turn on debug, you get the YSD

    Server Error in '/MyPath/MyApp' Application.


    Parser Error

    Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.

    Parser Error Message: Unknown server tag 'asp:DynamicDataManager'.

    Source Error:

    Line 5: 
    Line 6:  <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
    Line 7:      <asp:DynamicDataManager ID="DynamicDataManager1" runat="server" AutoLoadForeignKeys="true" />
    Line 8: 
    Line 9:      <h2><%= table.DisplayName%></h2>

    Probable Causes

    • The server does not have .NET 3.5 SP1, which includes ASP.NET Dynamic Data, installed. Download it here.
    • The third tagPrefix shown below is missing from web.config
    • <pages>
      <controls>
      <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      <add tagPrefix="asp" namespace="System.Web.DynamicData" assembly="System.Web.DynamicData, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      </controls>
      </pages>
       
       
      Hope that helps!

      TeamHanselmanLargeBanner2
    Posted by rajbk | with no comments
    Filed under: , , ,

    ASP.NET Asynchronous Pages and when to use them

    There have been several articles posted about using  asynchronous pages in ASP.NET but none of them go into detail as to when you should use them. I finally saw a great post by Thomas Marquardt that explains the process in depth. He addresses a key misconception too:

    So, in your ASP.NET application, when should you perform work asynchronously instead of synchronously? Well, only 1 thread per CPU can execute at a time.  Did you catch that?  A lot of people seem to miss this point...only one thread executes at a time on a CPU. When you have more than this, you pay an expensive penalty--a context switch. However, if a thread is blocked waiting on work...then it makes sense to switch to another thread, one that can execute now.  It also makes sense to switch threads if you want work to be done in parallel as opposed to in series, but up until a certain point it actually makes much more sense to execute work in series, again, because of the expensive context switch.

    Pop quiz: If you have a thread that is doing a lot of computational work and using the CPU heavily, and this takes a while, should you switch to another thread? No! The current thread is efficiently using the CPU, so switching will only incur the cost of a context switch.

    Ok, well, what if you have a thread that makes an HTTP or SOAP request to another server and takes a long time, should you switch threads? Yes! You can perform the HTTP or SOAP request asynchronously, so that once the "send" has occurred, you can unwind the current thread and not use any threads until there is an I/O completion for the "receive". Between the "send" and the "receive", the remote server is busy, so locally you don't need to be blocking on a thread, but instead make use of the asynchronous APIs provided in .NET Framework so that you can unwind and be notified upon completion. Again, it only makes sense to switch threads if the benefit from doing so out weights the cost of the switch.

    Read more about it in these posts:

    Performing Asynchronous Work, or Tasks, in ASP.NET Applications
    http://blogs.msdn.com/tmarq/archive/2010/04/14/performing-asynchronous-work-or-tasks-in-asp-net-applications.aspx

    ASP.NET Thread Usage on IIS 7.0 and 6.0
    http://blogs.msdn.com/tmarq/archive/2007/07/21/asp-net-thread-usage-on-iis-7-0-and-6-0.aspx

    PS: I generally do not write posts that simply link to other posts but think it is warranted in this case.

    Posted by rajbk | 1 comment(s)
    Filed under: , , , ,
    More Posts « Previous page - Next page »