SSW Foursquare

Rules to Better Website Development - ASP.NET - 37 Rules

If you still need help, visit our Web Application Development consulting page and book in a consultant.

  1. Do you know how to create nice URLs using ASP.NET 4?

    There are a lot of reasons to have nice URLs for your website:

    • Easy to remember
    • Easy to navigate
    • Better for search engines

    BadURL
    Figure: Bad example – This URL is impossible to remember for your users, and even search don’t like these URLs

    GoodURL
    Figure: Good example – Nice clean URL, easy to remember, easy to guess where I am and good for search engines

    With ASP.NET 4 it is easy to create this URLs. The ASP.NET team includes routing features, known from the MVC web framework.

    Add a route in Global.asax

    protected void Application_Start(object sender, EventArgs e)
    {
        //RouteTable and PageRouteHandler are in System.Web.Routing
        RouteTable.Routes.Add("ProductRoute",
            new Route("products/{productname}",
            new PageRouteHandler("~/ssw/Products/ProdCategoryList.aspx")));
    }

    Figure: Example on how to route ssw.com.au/products/{everything} to ssw.com.au/ssw/Products/ProdCategoryList.aspx page

    Note: There is no dependency on the MVC framework in order to use this code.
    Note: IIS7 has a module called URL rewrite module that can do this functionality without changing any code. Just a configuration of a "Rule" in the IIS Manager.

  2. Do you know how to filter data?

    It is difficult for users to find their required records in a huge amount of data, so adding the filter data functionalities is very useful.

    The standard DataGrid of ASP.NET doesn't include this functionality, developers need to implement it by themselves.

    FilterDataInDataGrid
    Figure: Bad Example - implement data filter manually

    Fortunately, RadGrid supplies this perfect feature.

    FilterDataInRadGrid
    Figure: Good Example - add an attribute to filter data

    Developer can turn this feature on by setting the AllowFilteringByColumn="True".

  3. Do you use jQuery for making a site come alive?

    To please customers every business knows they need to keep their services and offerings fresh and up-to-date. The same is true for websites. In order to attract new traffic, we should make the website vivid.

    OldFashionSite
    Figure: Bad example – there is no response when mouse is over the image

    NewFashionSite
    Figure: Good example – apply the different style when mouse is over

    $("p").hover(function () {
                $(this).css({ "background-color":"yellow", "font-weight":"bolder" }); },
                function () { 
                    var cssObj = { "background-color": "#ddd", 
                    "font-weight": "", 
                    color: "rgb(0,40,244)"
                }
                $(this).css(cssObj);
            });

    Figure: Mouse hover code sample

  4. Do you use jQuery Tooltips to save drilling through?

    It is common when we browse a list page, we have to click the "More..." or "Details" button to view the item detail. This process takes more time because we need to wait for the loading of the detail page.

    To improve the performance, we can use jQuery plus CSS to show tooltips in the list page that can let users determine which item detail they want to see.

    ViewDetailGrid
    Figure: Bad Example - redirect to a new page to view the detail

    ViewTooltipGrid
    Figure: Good Example - show tooltip when mouse is over in the list

  5. Do you use MSAjax for Live Data Binding which saves round trips?

    In old versions of ASP.NET AJAX the UI control couldn't get notification if the source had been changed. Developers had to write the extra code to refresh the value.

    In ASP.NET AJAX version 4.0, there is a new feature called "Live Data Binding", which means when there's any change in the data source, the changes are reflected to the data bound interface instantly and vice versa. 

    Binding Modes:

    Sys.BindingMode.auto

    This is the default binding mode. Two-way binding on an input control, and one-way binding on a context-type elements such as spans.

    <b>Name: </b><input id="name" type="text" value="{binding name, mode=auto}" />  
    <b>Echo: </b><span id="nameDisplay">{binding name, mode=auto}</span>

    Figure: When you update either textbox, the other one will be updated with the same value

    Sys.BindingMode.twoWay

    This is the default binding mode for input controls.

    <b>Name: </b><input id="name" type="text" value="{binding name, mode=twoWay}" />  
    <b>Echo: </b><span id="nameDisplay">{binding name, mode=twoWay}</span>

    Figure: When you update either textbox, the other one will be updated with the same value

    Sys.BindingMode.oneWay

    <b>Name: </b><input id="name" type="text" value="{binding name, mode=oneWay}" />  
    <b>Echo: </b><span id="nameDisplay">{binding name, mode=twoWay}</span>

    Figure: When you update the Name, it won't affect the Echo

    Sys.BindingMode.oneWayToSource

    <b>Name: </b><input id="name" type="text" value="{binding name}" />  
    <b>Echo: </b><span id="nameDisplay">{binding name, mode=oneWayToSource}</span>

    Figure: When you update the Name, it won't affect the Echo. But if you update Echo, it will affect the Name

    Sys.BindingMode.oneTime

    <b>Name: </b><input id="name" type="text" value="{binding name, mode=twoWay}" />  
    <b>Echo: </b><span id="nameDisplay">{binding name, mode=oneTime}</span>

    Figure: When you update the Name in the first time, it will affect the Echo. After the first time, it won't affect the Echo

    The live-binding syntax is similar to binding syntax in WPF (XAML).

  6. Data - Do you not allow NULLs in number fields if it has the same meaning as zero?

    NULLs create difficulty in the middle-tier because you need to add further handling. So avoid them where you can, eg. For a Discount field, make the default 0 and don't allow NULLs.

    This rule should not be applied when a NULL value is valid data. Often times data such as a percent earnings rate on a super fund is nullable because it may not be supplied or relevant. This is very different to it being zero and you have no way to determine real zero values from not supplied data. The hit of doing the work in code is often offset in this case by the validity of query results.

    As a general rule of thumb, don't use NULL if you cannot distinguish it from another value.

    Q:  What is the difference between NULL and 0 in the field "Discount"? A:  No difference, so don't allow NULL.

    Q: What is the difference between NULL and 0 in the field "DailySugarIntake"? A: NULL means unknown and 0 means no daily sugar intake, so allow NULL.

    Note:  Nulls are evil, but don't go crazy removing nulls. Never invent your own constant eg. -999 to represent a Null.

  7. Do you allow users to comment and rate your pages?

    If you have published content on the internet, it's a good idea to allow your visitors to comment and rate your pages. Collecting feedback is a great way to make it easier to maintain your content. You can see which content is out of date, and which content is more highly regarded by your user base. This lets you focus on creating the most relevant content that you can. As well as providing you with feedback, allowing people to participate makes them feel more engaged with your content, broadening your reach.

    There are a few ways that you can easily add comments and interactivity, such as using widgets from:

    The following video shows an overview of Yotpo ratings which we've implemented for our SSW Rules.

    Good Example: Yotpo ratings on the SSW Rules site

  8. Do you always put JavaScript in a separate file?

    ASP.NET injects many lines during page rendering, so if you are using inline JavaScript, the line numbers will change during client side JavaScript debugging in VS.NET, FireBug or IE8 developer Tools.

    JavaScriptBad1
    Figure: Bad Code - Using Inline JavaScript

    JavaScriptBad
    Figure: Bad Code - On PostBack Line numbers are changed for Inline JavaScript

    JavaScriptGood
    Figure: Good Code - Using JavaScript on Separate file

    So you should always put JavaScript in a separate file. Then the line numbers will stay consistent during debugging.Keeping JavaScript in a separate file is also good for production as it improves performance due to browser caching.

    Note: During development, remember to hit CTRL-F5 to force the browser to re-fetch the files from the server or you may be debugging old version of the JavaScript file.

  9. Do you avoid deploying source code on the production server?

    When you are deploying an ASP.NET project (no matter it's a website or a Web application), do not copy all files of this project to the production server because source code will be deployed during this simple copy and it makes easier for others to access or tamper the source code of your site.

    Instead, please use 'Publish' utility to deploy your website or Web application. This utility can remove the source code from the site.

    1. Website Project

    Publish Website dialog box is designed to precompile and deploy your website to a new location (whatever it is, ftp://, http:// or drive:\path). During the deployment, source code are removed automatically. Besides, the precompilation process finds any compilation errors and identifies the errors in the configuration file.j

    To access this dialog box, please open a website that you want to deploy and click Build menu, then click Publish Website .

    PublishWebsite
    Figure: How to open Publish Website dialog box

    Figure: Publish Website dialog box

    See more about Publishing Websites.

    2. Web Application Project

    The Publish Web dialog box enables you to build and publish a Web application project to a new location. Like Publish Website dialog box, this utility can remove source code. However you have to select Only files needed to run this application to specify it. Other benefit of this utility is that potential errors and compile-time errors in the Web.config file and in other non-code files can be found.

    To access this dialog box, open a Web application project that you want to publish and click Publish ApplicationName on the Build menu.

    PublishWebApp
    Figure: How to open Publish Web dialog ('WebApp' is the name of this application)

    Figure: Publish Web dialog box

    See more about How to Publish Web Applications.

  10. Do you avoid using ASP/ASP.NET tags in plain HTML?

    ASP and ASP.NET tags have no place in plain HTML pages. They simply increase the size of the file and are ignored by browsers, because the need to be processed on the server. When converting ASP.NET pages to plain HTML you must be careful to remove all of these tags.

    <%@ Page Language="C#" %>
    <html>
    <ssw:inctop id="inctop" runat="server"></ssw:inctop>

    Figure: Bad example - ASP.NET tags accidentaly placed in a plain HTML documents

    We have a program called SSW Code Auditor to check for this rule.

  11. Do you avoid using document.getElementById(id) and document.all(id) to get a single element, instead use selector $(#id)?

    $(#id) is a selector of jQuery. It gets the single element with the given id.

    jQuery is a fast and concise JavaScript Library that simplifies how you traverse HTML documents, handle events, perform animations, and add Ajax interactions to your web pages. jQuery is designed to change the way that you write JavaScript.

    With jQuery, you can write less code but do more work.

    <h1 id="Head1">Hello</h1> 
    <script type="text/javascript" language="javascript">
        document.all("Head1").style.color="red"; 
    </script>

    Figure - Bad Code

    <h1 id="Head1">Hello</h1> 
    <script type="text/javascript" language="javascript">
        document.getElementById("Head1").style.color="red"; 
    </script>

    Figure: Bad Code

    <h1 id="Head1">Hello</h1> 
    <script type="text/javascript" language="javascript">
        $("#Head1").css("color","red"); 
    </script>

    Figure: Good Code - Using $("#Head1")

  12. Do you avoid using mailto: on your website?

    Don't ever display valid individual email addresses or mailto: on a website. Nasty people on the web have created "Email Harvesting" tools. These programs search public areas on the Internet to compile, capture, or otherwise "harvest" lists of email addresses from web pages, newsgroups, and chat rooms. Any email address that is spelled out can be captured and therefore gets attacked with spam.

    The best way to avoid it is not to display valid individual email addresses in text format (especially in the form of "mailto:") on your website.

    FirstnameSurname@ssw.com.au

    Figure: Bad way - normal email address in text format

     Better way: encryption technique 

    1. Store email addresses in the web.config file
    <configuration> 
        <appSettings> 
            <add key="SampleEncodedEmailAddress" value="David@sample.com.au" /> 
            ...
        </appSettings> 
    </configuration>
    1. Encode them on the server using the BitConverter class
    Dim email As String = ConfigurationSettings
            .AppSettings("SampleEncodedEmailAddress")
    
    Application("SampleEncodedEmailAddress") = BitConverter
            .ToString( _ ASCIIEncoding.ASCII.GetBytes(email))
            .Replace("-", "")
    1. Decode on the client with a JavaScript function in the JavaScript
    <a id="linkContact" href="javascript:sendEmail('44617669644073616D706C652E636F6D2E6175')">
        CONTACT David
    </a>

    We have a program called SSW CodeAuditor to check for this rule.

  13. Do you avoid using ReportViewer local processing mode?

    ReportViewer control is a powerful control designed for Windows application and Web application to process and display reports. This control can be configured to run in local processing mode and remote processing mode.

    • Local Processing Mode This mode uses client report definition (.rdlc) files, all report processing is performed on the computer that hosts the application. All data used by the report must be retrieved from data that the client application provides, so you have to configure the ReportViewer control's Data sources, Report parameters. See Configuring ReportViewer for Local Processing for more information.
    • Remote Processing Mode This mode needs the Microsoft SQL Server 2005 Reporting Services report server, The report server processes the data and renders the report into an output format. The ReportViewer control retrieves the finished report from the report server and displays it on the screen, so you have to configure the ReportViewer control's report server information.  See Configuring ReportViewer for Remote Processing for more information.

    If you use local processing mode in your Web application, there are more configuration to do for the ReportViewer control, report processing will also slow down the web server.

  14. Do you avoid using Website Projects?

    If you're creating new web apps in ASP.NET 2.0, do you still use  Website projects ? We strongly recommend using the new  Web Application projects .

    What's the difference between the two? There is a detailed comparison here, but to summarize:

    • Website projects  have no project file and it creates multiples assemblies. (This result in a lot of annoying scenarios.)
    • Web Application projects  have a physical project file and along with all other standalone classes within the project are compiled into a single assembly.

    Please see our kb - How to upgrade VS 2005 website Projects to be VS 2005 Web Application Projects? to do the upgrade.

  15. Do you build criteria by using a where clause?

    It is very common to come up with ways to filter data. 

    As an example, you could do it like this:

    ClientSearch.aspx?Client.ClientID='ssw'&Client.CoName='S'

    Figure: Filtering Data

    This allows you to easily extract fields and values, but it only works for the fields you hard code. You could get around it by writing complex code to build a SQL query or ignore the ones that don't match.

    But this gives exact matches. E.g.:

    ClientID=ssw

    What if you want to give the ability to allow the user to be able to use a like. E.g.:

    ClientID like '%ssw%'

    Well then I could add something like:

    ClientSearch.aspx?Client.ClientID=ssw&Client.ClientID.SearchMode=OR

    But why do this when a WHERE clause in SQL can do all this. E.g.:

    ClientSearch.aspx?Where=Client.ClientID%20like%20'%ssw%'

    Figure: Similar matches

    The PROS for do this are:

    • Quicker development time.
    • SQL is very powerful - say I want to JOIN another table in the WHERE, I could use an IN statement and do a sub query - no extra code by the developer.
    • Matches HTML syntax (named value pair) and as a developer you can get it easy. E.g.:
    Request.QueryString("Where")

    The Cons:

    • It shows the database schema to the users - users maybe should not see the structure of the database.
    • Security - the where clause could show data we don't want users to see.
    • Got to add a little extra code to avoid SQL injection.
  16. Do you have a Validation page (the /zsValidate) for your web server?

    How can you know that all components are working correctly on your site? It is vitally important to have a 'Health Check' page to validate everything is working correctly. This page will check the server and make sure:

    • all the DLLs are present (and registered for COM ones)
    • all the web services are working
    • all the databases are alive, etc.

    la footer
    Figure: Link Auditor server info

    You would be surprised how many dependencies a large web page can have.The advantage of this page is if you ever need to redeploy your application on another server or you have some pages that are just not working as planned you can load up this page and get a quick diagnostics of your website.

    ValidateSetup
    Figure: One of the components on this website is down

    ValidationTests
    Figure: Automatically validating our website

    See SSW Rules - Do you have a zsValidate page to test your website dependencies?

  17. Do you have generic exception handler in your Global.asax?

    Add your code to handle generic exception of your ASP.NET application in Application_Error.

    private static readonly ILog log = LogManager.GetLogger(typeof(MvcApplication));
    
    protected void Application_Error(object sender, EventArgs e)
    {
        Exception ex = Server.GetLastError().GetBaseException();
        log.Fatal("Unhandled Exception", ex);
    }

    Figure. Exception handler in Global.asax.cs

  18. Do you keep your "DataBinder.Eval" clean?

    Remember ASP code, you had lots of inline processing. Using DataBinder.Eval encourages the same tendencies. DataBinder.Eval is OK, so is formatting a number to a currency. But not formatting based on business rules. The general rule is, any code between <%# and DataBinder.Eval is bad and should be moved into protected method on the form.

    Here is a good and a bad way to binding fields in ASP.NET in a datagrid.

    Putting all the field binding code AND the business rule in the control:

    Bad: Business logic is in the presentation layer (.aspx file)
    Bad: No intellisense
    Bad: Compile errors are not picked up

    <asp:Label 
        id="tumorSizeLabel" 
        runat="server" 
        Text='<%# iif( Container.DataItem.Row.IsNull("TumorSize"), "N/A",DataBinder.Eval(Container, "DataItem.TumorSize", "0.00")) %>'
    />

    Figure: Bad code

    Putting the code on the ItemDataBound Event:

    Good: Business logic is in the code behind (.vb or .cs file)
    Good: intellisense
    Bad: Code Bloat
    Bad: Have to use server control for all controls (viewstate bloat)

    In server page:

    <asp:Label id="tumorSizeLabel" runat="server" />

    In code behind:

    Private Sub patientDataGrid_ItemDataBound( ByVal sender As Object, ByVal e As DataGridItemEventArgs)_
    Handles patientDataGrid.ItemDataBound
    If( e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem) Then
    Dim tumorSizeLabel As Label = e.Item.FindControl("tumorSizeLabel")
    Dim rowView As DataRowView = CType(e.Item.DataItem, DataRowView)
    Dim row As PatientDataSet.PatientRow = CType(rowView.Row, PatientDataSet.PatientRow)
    If row.IsTumorSizeNull() Then
    tumorSizeLabel.Text = "N/A"
    Else
    tumorSizeLabel.Text = row.TumorSize.ToString("0.00")
    End If
    End If
    End Sub

    Figure: Good code

    We have a program called SSW Code Auditor to check for this rule.

  19. Do you keep your website loading time acceptable?

    Nobody Likes a Slow Website. You should optimize the performance of your websites so it loads as quick as possible.

    You should use Pingdom Website Speed Test to analyze the load speed of your websites and learn how to make them faster.

    Then work to keep it under 3 MB:

    • Unacceptable > 3 MB
    • OK  1.5 MB to 3 MB  (apple.com is 1.5MB)
    • Good < 1.5 MB
    • Excellent < 1 MB
  20. Do you know how to generate maintenance pages?

    In every application you focus on is the important business problems e.g. Invoices with multiple deliveries. Plus you have lots of lookup tables e.g. CustomerCategory. It is smart to work on the important business problems and have the lookup tables done automatically using a code generator.

    The code generators to generate maintenance pages automatically, come from MS and from 3rd parties. The current choices are:

    1. We recommend NetTiers (a template for Code Smith) in our 'The Best 3rd Party .NET Tools'. It is an open source template and the output code is of good quality. There are many amazing features:

      • Creates a full website project, already pre-configured and ready to begin coding against your data immediately.
      • Creates a full set of administration web controls, that serves as a basic yet fully functional web administration console for database.
      • Creates a full set of typed DataSource controls for your entire API with design time support, they are similar to the ObjectDataSource, only these are full featured and are actually developer friendly.
      • Creates a full webservice API for your domain, perfect for a .net winforms or smart client application and is simple to configure.
    2. AspDB is an alternative choice. You can click via a code generator (Designer) to produce a complete and acceptable Web DB application in several minutes.
    3. BLinQ is a tool to generate websites that use LinQ to show and edit data. DEAD - now replaced by ASP.NET Dynamic Data.
    4. ASP.NET Dynamic Data provides the Web application scaffolding that enables you to build rich data-driven Web applications. This scaffolding is a mechanism that enhances the functionality of the existing ASP.NET framework by adding the ability to dynamically display pages based on the data model of the underlying database, without having to create pages manually. 

    WARNING: ASP.NET Dynamic Data is in Beta and not installed on SEAL and SEALUS.   ASP.NET Dynamic Data has been released in VS.NET 2008 SP1.

  21. Do you know not to use LinkButton?

    If we want to refresh and data bind the same page from client side, we can use the javascript function calls "__doPostBack". We shouldn't fire this post back in LinkButton. Otherwise, there will be an error.

    Figure: Right click the link with __doPostBack event

    Figure: New window with incorrect URL

    <asp:Panel runat="server" ID="mUpdatePanel" OnLoad="mUpdatePanel_Load">
     <asp:Label runat="server" ID="lblTime" />
     <br />
     <asp:GridView ID="gvList" runat="server" AutoGenerateColumns="false">
     <Columns>
     <asp:BoundField DataField="ID" HeaderText="ID" />
     </Columns>
     <Columns>
     <asp:BoundField DataField="Name" HeaderText="Name" />
     </Columns>
     </asp:GridView>
     <br />
     ID:<asp:TextBox ID="txtID" runat="server"/>
     Name:<asp:TextBox ID="txtName" runat="server"/>
    </asp:Panel>
    C#:
    protected void mUpdatePanel_Load(object sender, EventArgs e)
    {
     lblTime.Text = DateTime.Now.ToLongTimeString();
     ArrayList mList = (ArrayList)ViewState["List"];
     if (txtName.Text.Length > 0)
     {
     Client mClient = new Client();
     mClient.ID = Int32.Parse(txtID.Text);
     mClient.Name = txtName.Text;
     mList.Add(mClient);
     ViewState["List"] = mList;
     gvList.DataSource = mList;
     gvList.DataBind();
     }
    }

    Sample Code

    <a href="javascript:__doPostBack('mUpdatePanel','');">Refresh</a>

    Bad code

    <input type="button" onclick="javascript:__doPostBack('mUpdatePanel','');" value="Refresh" />

    Good code

    We have a program called SSW Code Auditor to check for this rule.

  22. Do you know 'httpHandlers' or 'httpModules' sections in web.config must contain a 'remove' or 'clear' element?

    If web.config contains a <httpHandlers> or <httpModules> section, that section must contain a <remove... /> or a <clear /> element.

    This basically forces developers to explicitly enable inheritance in nested virtual directories. In 99% of cases this developers won't use inheritance on these two sections, however it causes issues when somebody wants to add a module or handler to the parent virtual directory.

    <configuration>
       <system.web>
          <httpHandlers>
             <add verb="*" 
                  path="*.New" 
                  type="MyHandler.New,MyHandler"/>
             <add verb="GET,HEAD" 
                  path="*.MyNewFileExtension" 
                  type="MyHandler.MNFEHandler,MyHandler.dll"/>
         </httpHandlers>
       <system.web>
    </configuration>

    Figure: Bad example

    <configuration>
       <system.web>
          <httpHandlers>
             <clear/>
             <add verb="*" 
                  path="*.New" 
                  type="MyHandler.New,MyHandler"/>
             <add verb="GET,HEAD" 
                  path="*.MyNewFileExtension" 
                  type="MyHandler.MNFEHandler,MyHandler.dll"/>
         </httpHandlers>
       <system.web>
    <configuration>

    Figure: Good example

  23. Do you know the best sample applications?

    Before starting a software project and evaluating a new technology, it is important to know what the best practices are. The easiest way to get up and running is by looking at a sample application. Below is a list of sample applications that we’ve curated and given our seal of approval.

    Northwind Schema

    northwind schema

    SQL Server

    SQL Server and Azure SQL Database

    .NET Core

    • SSW Clean Architecture Solution Template An example REST API build with .NET 7 following the principles of Clean Architecture.
    • SSW Northwind Traders A reference application built using Clean Architecture, Angular 8, EF Core 7, ASP.NET Core 7, Duende Identity Server 6.
    • eShopOnWeb Sample ASP.NET Core 6.0 reference application, powered by Microsoft, demonstrating a layered application architecture with monolithic deployment model. Download the eBook PDF from docs folder.
    • eShopOnContainers Cross-platform .NET sample microservices and container based application that runs on Linux Windows and macOS. Powered by .NET 7, Docker Containers and Azure Kubernetes Services. Supports Visual Studio, VS for Mac and CLI based environments with Docker CLI, dotnet CLI, VS Code or any other code editor.
    • ContosoUniversity This application takes the traditional Contoso University sample applications (of which there have been many), and try to adapt it to how our "normal" ASP.NET applications are built.

    Blazor

    UI - Angular

    • Tour of Heroes Default Angular sample app as part of the documentation
    • ngrx Example App Example application utilizing @ngrx libraries, showcasing common patterns and best practices

    UI - React

  24. Do you know when anchor should "run at server"?

    <a> tag should runat=“server" *ONLY* if you need to change the target at runtime.

    If you include runat=“server" for an HTML element that you do not need access to in code behind, you are introducing a whole lot of overhead you do not need.

    We have a program called SSW Code Auditor to check for this rule.

  25. Do you know which packages to add to new MVC projects?

    When you create a new MVC project in Visual Studio it is important to include the right packages from the start. This will make a solution more manageable and developers will be more efficient.

    Adding old, obsolete or incorrect packages can lead to decreased performance, scope creep as new requirements are discovered and generally lead to projects suffering.

    Some technologies to avoid are:

    • ❌ MVC Web Forms
    • ❌ KnockoutJS
    • ❌ AngularJS
    • ❌ Gulp

    When creating a new MVC project we recommend you use the Clean Architecture Template. This template not only gives you a great structure, but it also includes all the required packages.

    The following are some of the NuGet packages included:

    • ✅ EntityFramework
    • ✅ FluentValidation
    • ✅ NSwag
    • ✅ AutoMapper
    • ✅ MediatR

    The following are some of the NPM packages included:

    • ✅ Angular
    • ✅ FontAwesome
    • ✅ RxJs
    • ✅ NgRx
    • ✅ Bootstrap
    • ✅ TypeScript

    Note: Part of SugarLearning Developer Induction.

  26. Do you know why you choose .NET Core?

    Cross platform

    .NET Core works on multiple platforms like MacOS, Linux and Windows. So developers can code on their operating system of choice using Visual Studio, Visual Studio for Mac or Visual Studio Code, working on the same code base as developers on a different operating system, and best of all they can also deploy to Linux.

    Performance

    .NET Core is fast, and you get that performance out of the box.

    dotnet core performance
    Figure: ASP.NET Core easily trounces ASP.NET 4 in number of requests per second (view source)

  27. Do you release build your web applications before you deploy them?

    Reasons to release build your web applications before you deploy them with ASP.NET:

    • ASP.NET conducts a batch compilation on "release builds", which means it tries to compile all files in the current folder into one DLL
    • No resource caching is performed on debug build assemblies, which means that each request/response for a resource is not cached

    According to MSDN web developer tips, you can choose one of the following to release build your web application:

    • In web.config file, set <compilation debug="false"/>
    • Disable the <compilation debug="true"/> switch for all ASP.NET applications on the server by setting the following in Machine.config
    <system.web> 
        <deployment retail="true"/> 
    </system.web>

    The setting in machine.config will also turn off trace output in a page and detailed error messages remotely

    Machine.config file is typically located at %SystemRoot%\Microsoft.NET\Framework\%VersionNumber%\CONFIG.

  28. Do you have a useful 404 error page?

    Error page, you say? You worked hard to make sure my site has no errors!! Well, surfers don't always type URLs accurately. No website is immune to such errors.

    A well-designed custom error page encourages surfers to remain in your site and help them to the right page. Although it's possible to redirect error codes straight to your homepage, that doesn't tell visitors what's going on. It's more user-friendly to explain that there was a problem and provide some alternatives. Supply a link to your home page or other links, or offer your site's search function if you have one.

    <customErrors mode="Off"></customErrors>

    Figure: Bad example - The default code on web.config

    <customErrors mode="RemoteOnly" defaultRedirect="/ssw/ErrorPage.aspx">
    <error statusCode="404" redirect="/ssw/SSWCustomError404.aspx">
    </customErrors>

    Figure: Good example - The custom code in the web.config

    For ASP.NET website, the detailed information would be presented to the remote machines when an unhandled error occurs if the customErrors mode is off.

    This error information is useful for the developer to do debugging. However, it would leak out some confidential information which could be used to get into your system by the hackers. We can assume that if a SQL exception occurs by accident, which may expose database sensitive information (e.g. connection string; SQL script). So, to prevent these leaks, you should set the "mode" attribute of the tag <customerrors> to "RemoteOnly" or "On" in the web.config file and create a user-friendly customized error page to replace the detailed error information.

    <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm"></customErrors>

    Figure: Good example - Turning on "customErrors" protects sensitive information against Hacker

    404 bad
    Figure: Bad example - Unhandled error

    404 good
    Figure: Good example - Custom error page

  29. Do you use "301" code to redirect renamed or moved pages?

    Don't lose your Google juice when you rename a file. Do not use META refresh to redirect pages - "301" code is the most efficient and Search Engine Friendly method for webpage redirection. There are different ways to implement and it should preserve your search engine rankings for that particular page. If you have to change file names or move pages around, always use the code "301", which is interpreted as "moved permanently".

    How to do a "301" redirect in .aspx

    Any time you move a page or just delete a page you should add a "301" redirect to a new page or a page for missing pages.

    1. You can add a 301 redirect in code:

      <% Response.RedirectPermanent("NEW PAGE URL HERE") %>

      Although this works well it is difficult to manage the list of redirects and you need to keep the page around.

    2. You can write an HTTP handler
      This is better as you can choose where to store the redirect list, but you still need to manage a custom codebase.
    3. You can use rewrite maps in IIS URL Rewrite to add a number of redirects
      See Storing URL rewrite mappings in a separate file  for an explanation of how to use rewrite maps.

    Note:  If you are using a source control, like TFS, lock the old file so no-one can edit it by mistake.

    WordPress

    WordPress automatically redirects posts when you change the URL (permalink). No further action is required.

  30. Do you use CSS Validation Service to check your CSS file?

    CSS Validation Service allows you to check your webpage against the W3C recommendations. When developing web pages you want to create a clean and valid web page. It makes it easier for someone else to read and add new parts to a web page. Every web language like CSS has its own Syntax it must follow in order to produce a clean and valid web page, CSS Validation Service allows you to achieve that goal.

    Go to CSS Validation Service:

    1. Enter the URL or ppload file or by Direct Input to check
    2. Review the results and make changes to fix errors
  31. Do you use Markup Validation Service to check your HTML and XHTML code?

    Markup Validation Service allows you to check your web page against the W3C recommendations. When developing web pages you want to create a clean and valid web page. It makes it easier for someone else to read and add new parts to a web page. Every web language like HTML has its own syntax it must follow in order to produce a clean and valid web page, Markup Validation Service allows you to achieve that goal.

    Go to Markup Validation Service:

    1. Enter the URL or upload file to check
    2. Review the results and make changes to fix errors
  32. Do you use server side comments?

    Use server side comments:

    • Use <%-- Comment Here --%> instead of <!-- Comment Here --> (Does not get rendered to the client, saves us a few precious kilobytes)
    • Use CTRL + K, C to comment and CTRL + K, U to uncomment
  33. Do you use SSO (Single sign-on) for your websites?

    Many companies have more than one web applications running under different versions of .NET framework in different subdomains, or even in different domains. They want to let the user sign in once and stay logged in when switching to a different website, and this is SSO (Single Sign-On).

    In ASP.NET the logged-in user status is persisted by storing the cookie on the client computer, base on this mechanism, they are two possible solutions:

    1. Share one cookie across the web applications.  The Forms authentication cookie is nothing but the container for forms authentication ticket. The ticket is encrypted and signed using the <machineKey> configuration element of the server's Machine.config file. So if the web applications are hosted on the same machine, the point is to create a shared authentication cookie. Configure the web.config and create the cookie manually can achieve this.  Following scenarios may suit this solution

      • SSO for parent and child application in the virtual sub-directory
      • SSO for two applications in two sub-domains of the same domain
    2. Create its own cookie for each site by calling a page which can create cookie in its own domain.  If the web applications are hosted on different machine, it is not possibly to share a cookie. In this case each site will need to create its own cookie, call the other sites and ask them to create their own ones.  Following scenarios may suit this solution.

      • SSO for two applications in different domains
  34. Do you use the best Web UI libraries?

    Don't waste time evaluating which Web UI libraries to use. Most of the commonly used libraries are very similar in functionality. The recommended library is Bootstrap.

    It's the most popular available framework today, which means more people involved in the project, more tutorials and articles from the community, more real-world examples/websites, more third-party extensions, and better integration with other web development products

    bootstrap
    Figure: Leader among frameworks today, Bootstrap toolkit is recommended to build successful websites

    The 3 things a developer need to know to get up and running quickly with ASP.NET MVC

    Bootstrap & ASP.NET MVC - Intro / Quickstart

    Other useful frameworks

    Now that you saved a lot of UI development time by using Bootstrap, you can play around with other useful frameworks.

    • KendoUI for enhanced HTML and jQuery controls
    • SignalR for real-time web functionality
  35. Do you use Windows Integrated Authentication?

    Windows Integrated Authentication is the preferred option for use with intranet applications. When using Windows Integrated security, you don't need to implement the sign in system and user accounts database. The biggest advantage is if the user is already logged in to your domain they don't need to sing in to your application, it automatically logs them in instead of them having to sign in manually.

  36. Do you log usage?

    So you can see what functions are being used more often (e.g. reports, menu items).

    Plus, you can work out what fields to show on search pages (standard and advanced tabs) and which parameters are being used.

    GoodLogUsage
    Figure: Keep track of what terms are searched most often

    You can achieve this with Redgate's Feature Usage Reporting.

    logusage smartassembly
    Figure: Smart Assembly Professional keeps tracks of usage

    logusage pafortfs
    Figure: PA for TFS

  37. Do you know how to render HTML strings?

    Cross-site scripting (XSS) attacks occur when untrusted data is rendered on the browser without proper sanitization, thus potentially exposing the system to malicious scripts. To prevent XSS attacks, HTML encoding is typically applied to prevent the browser from interpreting HTML strings as code.

    However, this approach can cause confusion when an application needs to output content that is already HTML encoded.

    To solve this problem, the IHtmlString interface in .NET Core can be used to represent HTML content that is pre-encoded and should not be encoded again. This is to prevent double encoding, which can distort the original HTML content and cause it to display incorrectly on a web page.

    string message = "Hello, <b>world</b>!";
    
    Output: Hello, &lt;b&gt;world&lt;/b&gt;!

    Figure: Bad example - A string containing HTML tags will be encoded

    IHtmlContent message = new HtmlString("Hello, <b>world</b>!");
    
    Output: Hello, <b>world</b>!

    Figure: Good example - HTML tags using IHtmlContent will be treated as safe HTML and not encoded

    You should only use IHtmlString when you are sure that the string doesn't contain any potentially harmful script tags. When dealing with user-provided content or content from an untrusted source, always sanitize or validate the HTML before rendering it.

We open source. Powered by GitHub