Rules to Better Website Development - ASP.NET - 38 Rules
If you still need help, visit our Web Application Development consulting page and book in a consultant.
There are a lot of reasons to have nice URLs for your website:
- Easy to remember
- Easy to navigate
- Better 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.Ugly URLs don't only make it difficult for users to browse your site, they can also impact Google rankings.
northwind.com/MyInternalDB/UserDatabase/ProductList.aspx?productname=Access
Figure: A nasty URL...
You should fix it up to look more like this:
northwind.com/products/access
Figure: Users could even guess this nice URL
How to fix
- Add in Global.asax a route
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("~/MyInternalDB/UserDatabase/ProductList.aspx.aspx"))); }
Figure: OK example - create a static route if you only have a few rewrites**
- Use the URL Rewriting Module for IIS7
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.
Fortunately, RadGrid supplies this perfect feature.
Developer can turn this feature on by setting the AllowFilteringByColumn="True".
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.
$("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
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.
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).
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.
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.
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.
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 .
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.
See more about How to Publish Web Applications.
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.
$(#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")
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.
Figure: Bad way - normal email address in text format
Better way: encryption technique
- Store email addresses in the web.config file
<configuration> <appSettings> <add key="SampleEncodedEmailAddress" value="David@sample.com.au" /> ... </appSettings> </configuration>
- 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("-", "")
- 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.
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.
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.
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.
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.
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.
See SSW Rules - Do you have a zsValidate page to test your website dependencies?
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
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.
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
Related Rule
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:
-
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.
- 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.
- BLinQ
is a tool to generate websites that use LinQ to show and edit data.DEAD - now replaced by ASP.NET Dynamic Data. - 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.
-
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.
<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.
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
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
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
- Awesome Blazor Browser A Blazor example app that links to many other useful Blazor examples
- Blazor Workshop A Blazor workshop showing how to build fast food website
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
- Intro to React (Tic-tac-toe)
Introductory React tutorial that builds a simple Tic-tac-toe game - Intro to Redux (Counter example)
Introductory React Redux tutorial that builds a simple counter app
<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.
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.
✅ Some of the NuGet packages included:
- EntityFramework
- FluentValidation
- NSwag
- AutoMapper
- MediatR
✅ Some of the NPM packages included:
- Angular
- FontAwesome
- RxJs
- NgRx
- Bootstrap
- TypeScript
Note: This is part of SugarLearning Developer Induction.
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.
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
.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
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.
-
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.
- 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. - 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.
-
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:
- Enter the URL or ppload file or by Direct Input to check
- Review the results and make changes to fix errors
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:
- Enter the URL or upload file to check
- Review the results and make changes to fix errors
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
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:
- 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
- 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
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
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.
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.
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.
You can achieve this with Redgate's Feature Usage Reporting.
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, <b>world</b>!
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.
Sites can grow to get a lot of traffic from across the globe, it's important that your site complies with any local regulations. The General Data Protection Regulation (GDPR) for Europe, has been tightening cookie usage laws since 2018. The GDPR mandates that websites obtain explicit consent from users before storing or retrieving any non-essential information on their devices, such as cookies used for tracking and personalization. This regulation aims to protect users' privacy and give them greater control over their personal data.
By implementing a cookie consent banner, we ensure transparency and adhere to legal requirements, thereby fostering trust and safeguarding our users' rights.
Creating a cookie consent banner doesn't have to be tricky, it can be done in 3 steps:
- Cookie banner UI
- Creating and sending cookies
- Setting up GTM consent mode as per user preferences
Cookie banner UI
This section is very much customizable and will be different from site to site. Essentially you should create a pop-up, banner, or modal that will be prompted to users when visiting your site. Tina.io uses a banner along the bottom of the page.
The 3 button options should be:
- "Accept All" – Users accepts all types of cookies
- "Reject All" – Users reject all cookies
- "Customize" – According to GDRP we must allow users to manage their cookie preferences at any time. When users go to customize, all options must not be ticked
The Tina.io website let users customize their preferences with a modal.
Creating and sending cookies
This section will actually send your cookie based on how users have interacted with your UI. You can use a nifty library called ‘js-cookie’ which provides a super easy way to transmit a cookie.
- Install package and use on your component
npm install js-cookie
import Cookies from 'js-cookie';
- Create Cookie Variable and Set Example with a cookie that has all fields accepted, named 'consentGiven'
const acceptedConsent = { ad_storage: true, ad_personalization: true, analytics_storage: true, ad_user_data: true, }; Cookies.set('consentGiven', JSON.stringify(acceptedConsent), { expires: 365, });
- Confirm your cookie is being sent correctly
After interacting with the cookie banner, head to Developer Tools (F12) | Application | Cookies | {{ YOUR SITE }}
For example, the Tina.io cookie:
Configuring Google Tag Manager
Now that you have successfully created, customized and transmitted user cookies. Follow the following YouTube video to configure your Google Tag Manager.
Video: Guide to configuring consent code in Google Tag Manager (23 min)