blog.mha.dk
The on-line blog of Michael Holm Andersen

ASP.NET Viewstate Viewer add-on

Wednesday, 30 November 2011 10:23 by mha

If you’re a ASP.NET (WebForm) web developer and you worry about Viewstate (which you should!) – you might find this Firefox add-on very useful:

https://addons.mozilla.org/en-US/firefox/addon/aspnet-viewstate-viewer/?src=api

The add-on displays the viewstate of the current ASP.NET page in the statusbar – very handy when trying to limit the Viewstate size.

Categories:   ASP.NET | Tools
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Webshop launched

Thursday, 21 October 2010 15:21 by mha

The new B2C edition of our games and movies shop, located at http://www.mbc.dk/ is finally online.

The site is built using Visual Studio 2010, ASP.NET 4.0, Webform Routing, LINQtoSQL, jQuery and various other technologies.

The system uses LINQtoSQL as ORM and a custom build Repository on-top to handle all data access/business logic. A quick look at the DBML reveals a rather complex database schema as we exchange a lot of data with our ERP system (Axapta).

dbmlGW

The Solutions currently consists of 9 projects in total: 7 class library and 2 websites.

vsgw

The frontend website (webshop) uses Webform Routing to achieve SEO friendly URLs

frontgw

The backend website controls the all the frontend webshop’s (it’s possible to run multiple webshops on the same backend), data exchange with Axapta, CMS, CRM etc.

backendgw

.. it’s been lot’s of fun to build the system from the ground up (I started with a completely ‘clean plate’), and are now working on the B2B website.

Categories:   ASP.NET
Actions:   E-mail | del.icio.us | Permalink | Comments (2) | Comment RSSRSS comment feed

301 Redirects on IIS7 – come again Microsoft!!

Friday, 10 September 2010 14:15 by mha

Creating a 301 Redirect in IIS7 is EVEN MORE CRAPPY than on IIS6 – I was going “nuts” trying to find out why my 301 Redirect didn’t work.

What I wanted to do (a pretty common scenario) was to redirect traffic from my URL without www to the www.somethinggoeshere.dk version of my domain name – however this (one should think!) simple task is not easily done!! Here’s how to do it:

You have to create a new website (one could wonder why it’s not possible simply to add e.g. 301 Permanent headers to a host name and in this way quickly be able to add a list of URLs which would be 301 redirected) – when creating the website you HAVE to enter a Physical Path when creating the site. The wizard forces you to pick a path even if you plan to redirect the site to a URL.

The most obvious would be to pick the root folder of the site you plan on redirecting to, however this (why, Microsoft?) caused an error for both sites due to a continuous redirection. You have to create an empty directory for the site you want to redirect, which makes no sense at all (why does the directory matter when all I want to do is make a 301 permanent redirect).

This ought to be MUCH SIMPLER if you ask me!

WebMatrix – alive again!

Thursday, 8 July 2010 15:54 by mha

After about 7 years, Microsoft have decided to re-activate WebMatrix aka “The Matrix” :-)

WebMatrix is everything you need to build Web sites using Windows. It includes IIS Developer Express (a development Web server), ASP.NET and SQL Server Compact (an embedded database). It streamlines Web site development and makes it easy to start Web sites from popular open-source apps. The skills and code you develop with WebMatrix transition seamlessly to Visual Studio and SQL Server.

You can download the beta here: http://www.microsoft.com/web/webmatrix/

The WebMatrix is a smaller / lighter product that the Express product series, which of course still are available for download. If you’re ‘lazy’ you can use the Microsoft Web Platform Installer 2.0 for easy setup / install.

Categories:   Tools | ASP.NET
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

ASPX Edit Add-In For Visual Studio 2010

Tuesday, 18 May 2010 09:04 by mha

Rowland O’Connor has taken the time to update the ‘ASPX Edit’ plug-in to work with Visual Studio 2010 – you can download it here:

http://www.rowlandoconnor.com/2010/04/16/aspx-edit-add-in-for-visual-studio-2010/

Usage / install info is found here:

http://ardentdev.com/aspxedithelper/

.. thanks to Jacob for the update :-)

Categories:   ASP.NET | Tools
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

AutoComplete, PageMethod and LINQtoSQL

Wednesday, 12 May 2010 15:49 by mha

I’m using AutoComplete to enhance the functionality of a TextBox and make it act like the below image, where the user enters the customer accountnumber, which is then displayed together with their name (the blurry stuff in the picture :-)

autocompletesearch

As I have to use this functionality on many pages, I needed it to be a UserControl.

I wanted to use a PageMethod (instead of a Web Service) to populate the AutoCompleteExtender, but since the page method must reside on the page (in the .aspx.cs file, it does not work if it’s placed in the .ascx.cs file – dammit MS), I wanted to limit the code needed on the .aspx.cs page to a bare minimum.

The number of entries displayed in the AutoComplete DropDown list had to be limited, but the user need to know how many matches the prefix entered.


The Page Method (ServiceMethod) of the AutoCompleteExtender requires a string[] to work and I wanted the Page Method to contain as little code as possible. I ended up with this:

[System.Web.Services.WebMethodAttribute(), 
System.Web.Script.Services.ScriptMethodAttribute()] public static string[] GetDataCustomerAccountNo(string prefixText,
int count, string contextKey) { CustomerRepository customerRepository = new CustomerRepository(); return customerRepository.GetCustomerAccountNumbersByPrefix(prefixText); }


The GetCustomerAccountNumbersByPrefix looks like this:

/// <summary>
/// Retrieves all AccountNumbers which match prefix (AutoComplete)
/// </summary>
/// <param name="prefix">Prefix to match</param>
public string[] GetCustomerAccountNumbersByPrefix(string prefix)
{
    var customers = from e in db.Customers
            where e.AccountNumber.StartsWith(prefix)
            orderby e.AccountNumber
            select e;

    int count = customers.Count();
    string[] result = customers.Take(21).Select(x => x.AccountNumber + " – " 
                                         + x.NameAlias).ToArray<string>();

    if (result.Count() > 20)
    {
       result[20] = ">> antal: " + count.ToString();
    }

    return result;
}


If the ResultSet contains more than 20 rows I want to provide information about this to the user, displaying the total number of rows, which is why I do a Count() before Take()

I use .Select() to transform the properties AccountNumber and NameAlias into a single string, which is then returned as a string[] using ToArray(), in the process I limit the number of rows to a maximum of 21 using Take()

And all there’s left to do is to optionally change the 21th entry to show the total number of rows information. As the string[] is fixed it’s much easier simply to take out an extra row - Take(21) – and use this last row to show the information.

Hope the above example is useful to others who might want to use the AutoCompleteExtender in a UserControls only to find out that the PageMethod actually DO have to reside in the .aspx.cs file.

Categories:   C# | ASP.NET | LINQ
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

LINQtoSQL – Grouping and selecting

Wednesday, 21 April 2010 15:00 by mha

I have a Order->OrderLine table setup where I need to check if any “duplicate” orders exists. In order to check this I need to be able to select select various columns *not* contained in the group (key) – playing around in LinqPad I quickly came up with this query:

from line in AxSaleLines
where line.QuantityRemaining > 0
group line by new {line.AxSale.AccountNumber, line.ItemNumber, 
ProdName = line.Product.Name, ProdFormat = line.Product.ProductFormat.Name}
into myGroup
where myGroup.Count() > 1
from s in AxSaleLines
where s.ItemNumber == myGroup.Key.ItemNumber && 
      s.AxSale.AccountNumber == myGroup.Key.AccountNumber
select new { s.AxSale.SalesId, s.AxSale.AccountNumber, 
             CustomerName = s.AxSale.Customer.Name, s.ItemNumber, 
             ProductName = s.Product.Name, s.Product.ProductFormatName, 
             s.Quantity, s.AxSale.SalesOrigin}
 


When bound to a grid, I can then show this to the user:

groupedgrid

Categories:   LINQ | ASP.NET
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

Register Custom Controls In Web.config

Thursday, 15 April 2010 15:43 by mha

If you’re using a lot of UserControls or a control package, you’re probably finding yourself adding tons of <%@ Register… %> tags to your .aspx pages.

Phil Haack has an excellent post about how to avoid all this mess and put your assembly references into the Web.Config file. Go check it out!

Categories:   ASP.NET
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

ASPX Edit Helper Add-In For Visual Studio

Thursday, 11 February 2010 08:07 by mha

Jacob mentioned a nice little free Add-In for VS2005/2008 yesterday while we we’re chatting on Messenger :-)

Short description: “The ASPX Edit Helper is an add-in for Visual Studio 2005 for those who like to type ASPX markup themselves instead of using the visual designer"

Usage:

Type <asp:Label and press Enter. The add-in will replace it with:

<asp:Label runat=”server” id=”asp_Label2943″ />

The add-in will also highlight the ID attribute value so you can immediately type a new ID for the control.

Very handy, thanks to Jacob for mentioning this – free download at: http://www.ardentdev.com/aspxedithelper

Categories:   ASP.NET | Tools
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed

IE8, cookies and local addresses that are not localhost

Thursday, 19 November 2009 11:20 by mha

Recently installed Windows 7 which is really nice. IE8 is the default OS browser and typical the one I use as my “default development browser”, which means it is not my default browser (Firefox is), but it’s the browser that Visual Studio opens when I do a “View page in browser”.

I have multiple sites which use ASP.NET Membership (and hence use session cookies to keep me logged in). I typical change my ‘hosts’ file to something like this below, and of course set the ‘binding’ (host header) in IIS7 to match:

127.0.0.1    site1
127.0.0.1    site2
127.0.0.1    site3

(names have been changed to protect the clients :-)

However when I fired up VS2008 and tried to log into one of my sites which uses membership, I simply could not log in. After having done some HTTP Cookie debugging I realized that IE8 did not store my cookie. A fact that was proven correct as the same site worked fine i both Firefox and Chrome.

Surfing the net I found a that this is a “security feature” of IE8 – the thing is that if you have e.g.

Site: http://mha
Cookie domain: mha

should work, but if you do

Site: http://mha
Cookie domain: 127.0.0.1

..then it won't work, because IE sees that as security risk as 127.0.0.1 does
not match the requested hostname.

Microsoft recommend that you should always name internal servers with
hostnames that are FQDNs, such as mha.local - This also helps to mitigate
problems such as DNS failures and use of suffix handling - eg. if the DNS
automatic suffix for a machine on your network is .com, and you name a
server mha, a request to http://mha could end up requesting http://mha.com
because of the automatic suffix handling.

So to get this to work you need to stop using single words for internal site
URLs and start using e.g. localhost.mha

So .. in order to make IE8 accept cookies from internal sites running on localhost / IIS7, and is mapped in your ‘hosts’ file we need to do a couple of thing:

1) Make sure you’re using a full qualified hostname, e.g. localhost.aspnethotelV25

2) In IIS7 make sure you’ve set up your hostname correctly in binding:

iis7binding

3)  In your ‘hosts’ file, make a matching entry:

# --- IIS7 / localhost ---
127.0.0.1    localhost.aspnethotelV25

4)  In IE8 make sure to add your site to always allow cookies:

  • Go to Tools –> Internet Options
  • Click ‘Privacy’
  • Click ‘Sites’
  • In Address of website, enter your host header name
  • Click ‘Allow’

ie8cookie1

ie8cookie2

That’s it!! – Finally your site, running on your own localhost / IIS7 which is using a different name that localhost or 127.0.0.1 is now able to accept cookie (because we all know that cookies server up from localhost is a big security risk!?! :-)

Enjoy the wonders of Internet Explorer v8 (or simply use Firefox, Chrome or any other browser which just work out-of-the-box)