Sponsored
Thursday, April 15, 2021
dotPeek: a Totally Free Alternative for .NET Reflector
Friday, November 20, 2020
Reuse a MemoryStream without Writing to a FileStream
MemoryStream is a very useful class as it allows working with a Stream-like data in memory without having dependencies on any external resources like files, etc. Even though the MemoryStream implements an IDisposable interface it does not actually have any critical resources to dispose of, so, explicitly disposing of a MemoryStream object is not strictly necessary as the .NET memory management will take care of it. This specifics presents an opportunity of reusing the MemoryStream object if needed across multiple code scopes.
Friday, November 6, 2020
Best Practices of Working with Date in JavaScript/TypeScript
Date is a built-in type in JavaScript/TypeScript (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) and provides most of the basic needs for manipulating with Date and Time values in the code. Being one of the most well-defined and often used basic types of the language it still generates a lot of confusion, questions and erroneously working code among a wide developers' community. Let's try and figure out some of the best practices that should be applied to the JavaScript/TypeScript code when dealing with the Date type.
Monday, April 3, 2017
Ingenious USB Flash Drive Repair Utility
Every now and then it happens when you expect it the least: Windows fails to mount and read your trusted USB flash drive that is urgently needed and requests to format it. When you reluctantly agree after struggling to remember whether there was any important information on it (check point: never use USB flash drives for long term storage) you only see that Windows recognized just a tiny portion of the drive as accessible and it's useless because the file you need to copy is way larger. What to do?
Tuesday, December 29, 2015
Easily add config transformation files to a Console App project
Thursday, July 3, 2014
PDF4NET: Setting Transparent Background for a Barcode
Here is a small trick that allows setting a transparent background for a bar code inside a PDF document.
Cheat Sheet for Enabling Output Caching in ASP.NET MVC
What is Output Caching
ASP.NET output caching feature allows increasing web application performance by returning content that was built some time ago instead of rebuilding it on every request. Returning content from cache only takes a few milliseconds as opposed to executing a full request cycle that could take much longer.
The content is being cached on the ASP.NET level and the request would not reach the application code for the content that is still in cache. ASP.NET output caching can be used in both WebForms and MVC applications and using it in MVC has become even easier than before.
When to use Output Caching
Output caching is useful when content returned by a controller action method does not change frequently, requires more than few CPU cycles or database access and does not require a lot of memory to store. For example, I would not recommend to use output caching for a large binary object like an image or a file. Also there is no point to cache a short string that only takes a few milliseconds to build. The best use case would be an average size content that requires some calculation or database access to produce but does not change on every request.
How to enable Output Caching
The easiest way to enable output caching in MVC is using an OutputCache attribute on the controller or controller action method. Applying output caching on a controller action method is recommended as it gives much better granularity and control over output caching. The best way to control output caching behaviour is via caching profiles that allow defining all parameters in a web.config file and override them for each environment where the web application is deployed (i.e. Dev, QA, Stage, Live, etc.)
Limitations
ASP.NET MVC has some limitations for output caching, for example: caching profile is not supported for a partial/child controller method therefore caching parameters including Duration and VaryByParam must be set in the code.
Implementation and code review check points
- Apply to individual action methods
- Use Caching profiles
- Partial/child action methods should not be cached for too long
- Disable output caching in Dev/QA/Stage environment.
- Do not forget to set Duration and VaryByParam values in web.config
Example
<system.web>
<caching>
<outputcachesettings>
<outputcacheprofiles>
<add name="cacheProfile" duration="60" varyByParam="*" />
</outputCacheProfiles>
</outputCacheSettings>
</caching>
</system.web>
[OutputCache(CacheProfile = "cacheProfile")]
public ActionResult Test()
{
ViewData["result"] = "This text was rendered at " + DateTime.Now;
return View();
}
Wednesday, November 6, 2013
ASP.NET and SSL Offloading
With all above said being correct it is not always recommended to rush for turning SSL offloading on. One very specific use case is an ASP.NET application using Web Forms authentication configured to serve protected content over secure connection only. What that means is when a request for a protected page sent over unsecured HTTP the application will redirect it to a secured version of the Url. But because the SSL request never reaches a web server (since it's being intercepted by a load balancer and converted into HTTP request) the application logic will be stuck in an infinite redirect loop. To resolve the problem there are only two options: allow protected content over an unsecured connection or disable SSL offloading. If there is more of an application logic that requires secured connection between client an a server it makes more sense to not use SSL offloading at all.
There are however scenarios when SSL offloading is very helpful. Examples include but no limited to many kinds of data processing service-like web applications that are not intended to return human-readable HTML output, TCP/IP based data processing applications that do not use HTTP at all and so forth. Most likely such applications will not base their logic on a condition of a secure connection with a client.
What are PROs and CONs of using SSL offloading? Obviously one positive point is web servers performance improvement by removing SSL processing from their plates. How important that could be? Most likely that depends on traffic. For high traffic high profile publicly accessible web servers that could be very important but in such cases all the efforts must be made to not couple application logic with a type of client-server connection. From another hand modern server CPUs implement specialized command sets that make SSL processing much less intensive and not so terrifying a task for web servers so it could be more convenient to allow secure traffic directly to web servers.
Another consideration is how secure traffic passing between an SSL offloading load balancer and a web server is. Obviously both devices are supposed to be behind a firewall but it needs to be take care of because traffic may contain sensitive information and in such a case load balancer could become a point of attack.
One more concern is IT maintenance. Secured infrastructure requires setting up and maintaining SSL certificates and other components. If there are a lot of web servers in a farm it could make sense to minimize maintenance by centralizing all SSL configurations on SSL offloading devices.
In conclusion, understanding specifics of a particular implementation is crucial for making a correct decision about using SSL offloading technique.
Thursday, September 19, 2013
Why Some Web Sites Suck
In this article I am trying to analyse and describe most commonly occurring problems not visible to a non-professional eye but significantly affecting users' experience.
Base technology platform selection
Often a web site could be built on top of a platform that is familiar to a development team but not necessarily a good choice for a new project but sill would be selected. One particular example is a high traffic e-commerce web site built upon Microsoft Sharepoint Portal Server because the developer team used this technology for a corporate news portal. The platform choice always brings its limitations and must be validated against a particular web site goals and usages. How fast do you expect it to work? How cross-browser compatible do you expect it to be? Those and other similar questions should be asked to make sure the technological platform choice is proper.
Web development framework
Obviously the platform choice limits the options for a Web development framework but if you are a .NET developer you most likely have at least two choices: ASP.NET WebForms and ASP.NET MVC. Both frameworks are modern first-class web development tools and support all the recent technological advances of web development. However regardless of the framework choice a team needs to make sure it uses all those advances and follows known best practices for a selected framework.
Most frequently noticed ASP.NET development bad practices
When I come across a web site that I don't like but still have to use I usually take a pick at the source code and easily spot some from the known bad practices listed below.
- HTML 4.01 Transitional. Remind me what year is it?
- JavaScript and CSS references neither bundled nor minified. Page load time, anyone?
- Inline JavaScripts that are neither minified nor obfuscated. See the previous point.
- Inline JavaScripts do not use OOP: still the old school functions only.
- Inline handling of cross-browser differences like "<!--[if IE 7]>". Well, this is really old school. No need to do that any more especially with JS libraries like jQuery.
- Inline CSS using ASP.NET long IDs. Shame on you, development team. That was considered poor poor practice since I can remember. Basically it's just a hack.
- Still using long ASP.NET IDs. You really need to do your home work and read documentation.
- Viewstate embedded right on a page. No comments here. If I see that my only hope that it's properly encrypted. How fast have you expected it to load?
- Still using hidden input elements to manage state. Have you considered other methods like Session maybe?
- Still using server controls for simple HTML like 'a' or 'li'. I call this lazy and I want to blame your team's coding best practice policies for that.
- Multiple different JavaScript libraries are present for example jQuery and Microsoft Ajax, that functionally overlap with each other. You do need to make up your mind and pick up just one.
Recommendations
- Use HTML 5.
- Minify and bundle CSS and JavaScript files. Not only doing that improves web site load times but also makes development and maintenance easier. Take a look at http://msdn.microsoft.com/en-us/library/system.web.optimization.aspx and also try to search for ASP.NET Bundling.
- When develop on JavaScript treat it as a first class programming language and apply all the same practices as you would for a server-side language like C#. Read this http://msdn.microsoft.com/en-us/magazine/dd453033.aspx and notice that it's from the year 2009.
- Use proven JavaScript libraries that handle cross-browser compatibility well and do not try to invent your own wheel.
- Implement well known solutions for hiding framework's specifics like client IDs, Viewstate, etc. Even though you need to use them it does not mean you cannot do it right.
- Always prefer server-side technique instead of client-side for handling application state. If nothing else Session is your best friend.
- Learn and use HTML directly for simple cases instead of server controls. It's not 2001 any more and you call yourself a Web developer.
- Do not use multiple client-side libraries that functionally are similar. Not only that makes development and maintenance a nightmare but also tells a lot about your software design skills. Make your choice and use the best tool for your job.
User Experience
Conclusion
Saturday, November 5, 2011
Using Anonymous Types Outside of Local Context with Dynamic Keyword
Anonymous types that have been introduced in C# with .NET 3.5 is a convenient and powerful feature and can be used to simplify and speed up development without sacrificing code quality or violating coding standards.
Tuesday, December 28, 2010
Set up local SMTP for your .NET development environment on Windows 7
If you are developing a .NET application that sends emails then you need a way to do that without needing to actually send emails out. On Windows 7 with IIS 7 installed you can easily configure a local SMTP service that will intercept all the SMTP sessions initiated in your code and successfully emulate sending the outbound email by saving it as a text file in a folder on your local hard drive. This is extremely convenient and allows you to keep working on your code without interruption even when you are not connected to the Internet.
To achieve that just add a few lines in your application's .config file (could be web.config or app.config). Here is an example of such a configuration:
<system .net="">
<mailsettings>
<smtp deliverymethod="SpecifiedPickupDirectory">
<specifiedpickupdirectory pickupdirectorylocation="c:\smtp">
</specifiedpickupdirectory></smtp>
</mailsettings>
</system>
After adding such a configuration every time your application sends an e-mail using a .NET framework built-in SmtpClient.Send method a new file with the .eml extension will appear in the configured folder.
You can open a file with any text editor like Notepad++ for example or you can use this free EML Viewer to improve viewing experience.
Wednesday, July 14, 2010
Re: Can architecture emerge from continuous refactoring?
What is software architecture?
I see software architecture as a parallel to a traditional architecture: it consists of knowledge about everything that is required to build a successful software product as in to successfully construct a building. In a context of a particular project architecture eventually results in a team vision and a set of documents that guide the team towards the successful completion of a project and achieving the goal. From this point of view it is obvious that if the goal itself or any of its dependencies and prerequisite are not envisioned and well defined then a team simply will not know where to go and never reach the point of success.Can software architecture emerge successfully from continuous small refactoring?
Often there is some legacy software in place and there is not enough time to redo the whole project from scratch so the only way is to apply small refactoring steps in order to make software better from the architecture standpoint.Hence software architecture can and should emerge successfully from continuous small refactoring. For me this is not a theory but a proven fact since that is what most of my job as a Software architect consists of: I am orchestrating my development team to apply continuous changes and refactoring to the code base in order to shape the architecture into the right direction.
Factors of success and failure of a re-architecture project
The main reason for success is for a team to be persistent and consistent on the way and for an architect to have a complete vision, fully understand the final state of the re-architecture process and the way of the architecture transformations.Opposite to the above when an architecture transformation is not a priority target and a team is not given enough time to work on the necessary changes then the new architecture will not emerge. It's not a "rocket science" and it's exactly the same process of achieving a goal as in any other human activity.
Some other reasons of re-architecture failure could be lack of the architectural vision, poor management, lack of architecture transformation understanding but I don't consider those to be the primary reasons bur rather the missing prerequisites for a re-architecture project.
Lessons learned on the way
Even though it's somewhat useful to learn from mistakes but I'd rather learn from successful implementations since what you can learn is a way to actually achieve the success.Re-architecture methodologies
Some people are convinced that using a right tool will guarantee the success and therefore focus on comparing and selecting the "best of the best" methodology. Lately the "agile" word became very popular in regards to that.From my experience any agile method is just a tool that may or may not help depending on a use case. Agile for me in this context is only a synonym of "continuous, persistent and consistent" way of moving towards a project's target. Whatever method is embraced by a team will work for me as long as it allows a successful completion of a project.
Sunday, November 29, 2009
Automatically compress embedded JavaScript resources with Microsoft Ajax Minifier
The question however is how to use it. Microsoft Ajax Minifier package does include a set of documentation that explains how to use the tool and even discusses a couple of usage scenarios. Unfortunately the way I wanted to use the Minifier is not covered in the documentation and for some reason I haven't found useful information on the Internet too so I've decided to do some research and share my findings with the community.
So how would I like to use the Minifier? Here are the requirements:
- I want to automatically compress embedded JavaScript resources in any project of my web application solution.
- I want the compressed JavaScripts have the original names so I don't have to change the references in HTML mark-up.
- I want the compression to be done only when I switch to the Release mode in Visual Studio. When I am in the Debug mode I want all the JavaScript files to be uncompressed for easier debugging.
- I want compressed JavaScript files never overrides the original JavaScript files and I don't want to keep the compressed JavaScripts so whenever I modify my JavaScript code the compressed resources are always up-to-date.
I believe that the requirements above describe one of the most common web application solution configuration so if there is a way to achieve them it would be very useful.
Can I achieve the requirements above with the Microsoft Ajax Minifier? The answer is yes. The solution is kind of obvious: since the Microsoft Ajax Minifier includes an MSBuild task I just need to modify a project file where I have embedded JavaScript resources that I need to be compressed to include the Microsoft Ajax Minifier build task. It does not sound complicated and below is the solution which is simple indeed. Just include the following XML in your project file right before the closing </Project> tag (in most cases):
<!-- Minify all JavaScript files that were embedded as resources -->
<Import Project="$(MSBuildExtensionsPath)\Microsoft\MicrosoftAjax\ajaxmin.tasks" />
<PropertyGroup>
<ResGenDependsOn>
MinifyJavaScript;
$(ResGenDependsOn)
</ResGenDependsOn>
</PropertyGroup>
<Target Name="MinifyJavaScript" Condition=" '$(ConfigurationName)'=='Release' ">
<Copy SourceFiles="@(EmbeddedResource)" DestinationFolder="$(IntermediateOutputPath)" Condition="'%(Extension)'=='.js'">
<Output TaskParameter="DestinationFiles" ItemName="EmbeddedJavaScriptResource" />
</Copy>
<AjaxMin SourceFiles="@(EmbeddedJavaScriptResource)" SourceExtensionPattern="\.js$" TargetExtension=".js" />
<ItemGroup>
<EmbeddedResource Remove="@(EmbeddedResource)" Condition="'%(Extension)'=='.js'" />
<EmbeddedResource Include="@(EmbeddedJavaScriptResource)" />
<FileWrites Include="@(EmbeddedJavaScriptResource)" />
</ItemGroup>
</Target>
What this script does is when the solution configuration is 'Release' it finds all the project embedded resource files with the extension '.js' and creates their compressed versions with the same names in the intermediate output folder where they are picked from later by the build process.
A few tips
As you may have noticed the Microsoft Ajax Minifier MSBuild task is referenced from the default folder where it was copied to by the installer. If you want to reference it from a different location, for example if you have a shared development environment and want to have similar setting for everyone, just copy two files ajaxmin.dll and ajaxmintask.dll to another location and include the <UsingTask> tag (below) instead of the <Import> tag in the script above:
<UsingTask TaskName="AjaxMin" AssemblyFile="$(MSBuildProjectDirectory)\..\Build\AjaxMinTask.dll" />
The presented script performs so called 'Normal Crunching' (see the Ajax Minifier documentation) of the JavaScript code which already does a pretty good job that is good enough in most of the cases: compression rate is over 50%. If you would like to turn on the 'Hypercrunching' mode (see the Ajax Minifier documentation) you only need to modify one line of the script to include the 'LocalRenaming' option of the Ajax Minifier:
<AjaxMin SourceFiles="@(EmbeddedJavaScriptResource)" SourceExtensionPattern="\.js$" TargetExtension=".js" LocalRenaming="CrunchAll" />
And the last note is: don't use the default Hypercrunching mode or RemoveUnneededCode option with the ASP.NET AJAX Framework as it does not work properly with it.
Monday, April 27, 2009
How to Improve ASP.NET UpdatePanel Performance
Since ASP.NET AJAX UpdatePanel was first introduced it has earned a strange mix of reputation. From one hand it has become a tool of first choice for many ASP.NET developers who wanted an easy way of introducing an AJAX-like behavior for their ASP.NET web apps. From another hand it has earned a lot of criticism from seasoned web developers because of certain performance consequences associated with complex usage scenarios.
Well, everything may be good and may be evil based on how we use it. From my experience consious and judicious use of UpdatePanel is the key to saving its benefits and avoiding potential problems.
Below I suggest a number of rules that help achieving better results when using UpdatePanel.
- Avoid automatic refreshing of UpdatePanel; always stay in control of which UpdatePanel and when refreshes: set UpdateMode property to Conditional (the default value is Always).
- Minimize the content of the UpdatePanel: the
<ContentTemplate>should only include controls that are neccessary to refresh. For instance if user input requires server-side validation include only an error message mark-up in the UpdatePanel and leave the rest of the form outside. - Try to keep the partial postback trigger controls outside of their respective UpdatePanels unless its neccessary to change their markup.
- Try to stick to a simple rule: one trigger for one UpdatePanel. If you need to refresh multiple UpdatePanels during one request add a trigger control to only one of those UpdatePanels and refresh the others programmatically in an event handler on the server. The idea is to avoid uncontrollable refreshing of unnecessary UpdatePanels.
- Since ViewState is updated with every partial postback request turn the ViewState off on a page that contains the UpdatePanel wherever possible or store the ViewState on the server to avoid transferring it forth and back with every async request.
- Since Page runs through its lifecycle during every partial postback and executes methods like Page_Load or Page_PreRender make sure that logic that is unneccessary for refreshing UpdatePanel is not executed by wrapping it in
if(!ScriptManager.IsInAsyncPostBack). - If you use UpdatePanel event handlers like Init, Load, PreRender and Unload make sure that code inside these event handlers does not execute unless neccessary by checking
Page.IsPostBackandScriptManager.IsInAsyncPostBackproperties. - If you trigger an UpdatePanel programmatically from the client-side (via JavaScript) make sure that its event handler check for the event trigger value using
Request.Params["__EVENTTARGET"]ot avoid unnecessary execution path. - If you programmatically update Page's Header (Title, etc.) or other Page's content that is outside UpdatePanel make sure that this code never gets executed during partial postbacks. First of all its not neccessary since page does not refresh but also it may be dangerous because the content may not be handled properly by a browser.
Conclusion
There may probably be more tricks and tips regarding usage of UpdatePanel but those mentioned above have been proven by real exeprience. I would also recommend understanding how UpdatePanel works behind the scene and never hesitate using Fiddler to investigate what your web app's doing.
Thursday, January 15, 2009
Search Engine Friendly Error Handling
ASP.NET provides a standard way to handle errors in web applications by configuring a customError section in the Web.config file. Standard behaviour is to redirect a user from an erroneous page to an error page that in its turn shows some kind of more or less friendly explanation of what has happened.
This approach is quite OK for intranet web applications but usually is not appropriate for a public web app accessible for search engines. The main problem here is that when error happens ASP.NET returns 302 "temporary redirect" response redirecting browser to the error page configured in the Web.config.
If the erroneous page was accessed by a SE bot the bot would index a content of the error handling page under the original page's URL thus creating a wrong index entry.
Another problem is if the actual error on the page was that the requested content was not found. This scenario is quite regular on modern dynamic web sites that construct content pages dynamically based on a Url. In http world such a situation should be called as 404 "Not found" especially in the case of a bot visiting such a page.
But ASP.NET standard handling will once again respond 302 and let the bot include a not existing page in a search index.
What I am driving at is the correct error handling should always return a corresponding http status code for a SE bot with the appropriate content for the user.
So, how can we do that without writing too much code? Actually quite easy. Starting version 3.5 SP1 ASP.NET has a new attribute redirectMode in the customError configuration section:
<customerrors mode="RemoteOnly" defaultredirect="/errors/GenericError.aspx" redirectmode="ResponseRewrite">
The new redirectMode attribute can be assigned one of two values: ResponseRedirect (default) or ResponseRewrite. ResponseRewrite prevents the erroneous page being redirected with the code 302 to an error page however the content of the error page will be shown on the original page. Internally ASP.NET is doing Server.Execute of the error page instead of Response.Redirect as usual.
So this is already a one third of work. The next thing we need to do is to return a correct http status code. It can be achieved by adding a few lines of code to the error page let's say to a Page_Load event handler:
int httpCode = 500;
Exception ex = Server.GetLastError();
if (ex is HttpException)
{
httpCode = ((HttpException) ex).GetHttpCode();
}
Response.StatusCode = httpCode;
This code checks if the reason of the error was an HttpException (a standard .NET exception class) then it assigns an http code from the exception otherwise it returns 500. Now it's two third of work done.
What left is to handle exceptions in your code properly. The best practices here are:
- If your application can not return a requested content for any reason except your application's internal problems then throw an HttpException with the code 404 and it will be friendly handled by your error page.
throw new HttpException(404, "Not found"); - Map other your application's specific exceptions to standard http codes and return them too.
- If your application throws an exception internally then wrap the internal exception with HttpException using an appropriate http code.
try { ... } catch (Exception ex) { throw new HttpException(code, message, ex); }
Response.Clear();
If for some reason you can not use the new redirectMode attribute in the .config file (older framework, application specifics, etc.) then just add a few lines of code to the global.asax that do the same:
void Application_Error(object sender, EventArgs e)
{
// Do something with the error, i.e. log, notify, etc.
Server.Transfer(errorpage);
}
It may be a good idea to clear an error status on the error page after you're done with error handling:
ClearError();
Now that is all.
Friday, May 30, 2008
Last-Modified HTTP header on ASP.NET page
"Last-Modified" HTTP header is an important part of every web page since it helps browsers to cache pages' content locally and thus save HTML traffic. It is also used by internet search engines in order to determine the relevance of the pages' content and thus improves pages' indexing.
By default, a standard ASP.NET page does not include a "Last-Modified" header in the output HTML. One of the possible explanation for such behavior is that an ASPX page is considered dynamic by nature meaning that its content might be updated every time the page is requested. It is true in many cases for data-driven and interactive pages but most of the dynamic web sites also contain pages that are updated relatively rare or static.
So, when does it make sense to add a "Last-Modified" header to the page? First candidates usually are data-driven pages that display information from some sort of content storage systems (databases, files, etc.) and that information changes but not very frequently so there is a possibility that the same content may be viewed many times. Other apparent candidates are static pages even if they are data-driven but their content does not change for the lifetime.
What are the pages that do not need the "Last-Modified" header? Obvious candidates are interactive pages and pages that displays user session related data.
ASP.NET provides two methods to set the "Last-Modified" header on the page. Both of them belong to the HttpCachePolicy class and are accessible through the Cache property of the Response object:
Response.Cache.SetLastModified(DateTime date);
Response.Cache.SetLastModifiedFromFileDependencies();
The first method takes a DateTime parameter that allows you to apply some algorithm for calculating the Last-Modified date of the page, for instance based on information from a database. The second method will calculate the date stamp automatically based for instance on the assembly build date. For the second method you can also include additional file dependencies in date calculation using
Response.AddFileDependancy(string filename);
For instance if a page displays a content of a static XML file you could include that XML file in the dependency and the "Last-Modified" header's value would be updated based on that file's "Date Modified" attribute.
Thursday, April 3, 2008
View State: do not forget to manage!
View State is an essential part of ASP.NET and not paying proper attention to how it's set up in your web application can give you some surprises sometimes not very pleasant ones. For those who wants to refresh their memory about ASP.NET View State I recommend to start from this good article by Dino Esposito. The article is not very new but it's still relevant and it covers many topics that are actual for today's ASP.NET programming.
So now as the background is covered I would like to focus on two main aspects that have to be considered in regards to the View State: performance and security.
What is it to consider performance-wise in regards to the View State? In a nutshell as larger the View State as larger a browser payload as more time is required to process the page on both server and client side meaning worse user experience.
What does the View State have to do with security? As the View State is publicly exposed to a web browser and contains internal data of the ASP.NET page and user controls there is always a risk that its content can be altered and data compromised that could lead to some unexpected behavior of a web application.
So is it inefficient and dangerous to use the View State in your application? Answer is NO: the View State is extremely useful and sometimes absolutely essential for the ASP.NET web application to work properly but don't assume that the default View State settings and behavior are always the best choice for you: always manage them consciously.
Is there best practice about the View State? Of course and there are some of them.
- Always explicitly turn off the View State for any control that does not require it to operate. Examples are: Label control, Literal control, Image control, HyperLink control, etc.
- If your page does not perform a post back and there is no complex data binding there is a good chance that you can turn off the View State for the entire page in the @Page directive. If you doubt simply try and see how the page works with the View Stated turned off.
- If you use complex template based server controls like Login control or CreateUserWizard control, for instance, convert them to templates and check out that the View State of all the child controls is properly managed (always look for Labels and Literals).
- When optimizing your ASP.NET application use some third-party browser-based tools to analyze page's View State content and reduce its size as much as possible.
- If you use a client-side View State always encrypt it.
- Consider moving the View State to a server side: besides security benefit of not exposing the View State publicly and reduced http payload the View State is processed faster on the server. Be aware about server memory consumption when using the View State on the server side. It's much easier to implement the server-side View State in ASP.NET 2.0 then it was with ASP.NET 1.1. Look at the example here.
That's mostly it. Follow the best practices above and feel confident about having your web application's View State managed properly.
Ensure Default Values in ASP.NET Server Controls
Many of ASP.NET server controls base their internal HTML rendering algorithms on the values of their properties. Developers are mostly aware of those properties (not always about their roles in the internal rendering process though) but don't always realize the importance of the default values.
From my experience there is a common assumption that if a property appears empty in the Visual Studio property window that means the default value is empty. Not always true and can be harmful for the output HTML content! Luckily there is always a way to ensure the default values of the properties in ASP.NET markup (.aspx, .ascx). Here are a few examples.
SiteMapPath server control
It has a string property SkipLinkText that by default appears empty in the property window. But in reality if it's not set it's populated from the embedded resource string. That effectively leads to a difference in HTML rendering that does render an <img> tag inside the breadcrumb path with the height and width attributes set to 0 (don't ask me why!).
Some browsers react inadequately on such the HTML if some CSS styling applied to the breadcrumb content. For instance IE6 does not honor a line-height attribute if there is an in line image inside the paragraph.
So to ensure that unnecessary HTML is not rendered in this case always use SkipLinkText="".
ValidationSummary server control
It has a string property ForeColor that defines the color of the text appearing in the control and is prepopulated with the Redvalue. Having a value in this property effectively leads to the control rendering out an inline styling "color:Red;". But if you want to define a text color in the CSS class that you apply to the control you have to explicitly set this property to empty value ForeColor="" otherwise it will always render out the inline styling which will effectively override your CSS settings.
CreateUserWizard server control
This is quite a complex and sophisticated template-based control that comes with ASP.NET Membership framework. From the first sight you assume some degree of intelligence built into the control based on its complexity. For instance, that it does validate user input and render error messages if something is wrong. And it's true except that it does not validate e-mail address string against a regular expression unless a property EmailRegularExpression is set to a proper value and it is not by default. Also it does not provide a developer with such an expression even though it is built into a standard RegularExpressionValidator control.
So be careful and don't forget to set this property EmailRegularExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" otherwise you will be surprised that a user can enter some garbage into the e-mail field and is not stopped doing that.
So above there are just some examples illustrating an importance of paying attention to such details as default values of the server controls' properties. I am sure you can find more examples based on your own experience.
Using .skin File
Also there is another more efficient way to ensure that the critical default values are properly set across a web application: just add all the default values that you want to ensure to your default .skin file. For example, for above mentioned controls add the following lines there:
<asp:SiteMapPath runat="server" SkipLinkText="" />
<asp:ValidationSummary runat="server" ForeColor="" />
<asp:CreateUserWizard runat="server" EmailRegularExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" />
Wednesday, February 27, 2008
Dynamic Rendering of META Description HTML tag
For today's search engine optimized web sites having relevant content of the META Description HTML tag on a page is a must. It plays a significant role together with the page title in determining a page relevance ranking in regards to search keywords.
So it becomes necessary to generate a content of the META Description dynamically based on a page content. ASP.NET already provides an easy access to the page TITLE tag allowing to populate it with relevant text simply using a Page.Title property.
Unfortunately it's not the same easy and obvious how to access the META Description from the server-side code.
Luckily ASP.NET is flexible enough and the solution is easy. Simply add a META tag to your page and turn it into a server tag by adding an id and a runat="server" attributes like the following:
<meta name="description" content="your description" runat="server" id="Description" />
Immediately you'll be able to access the content from the code behind by using a Description.Content property.
The explanation is very simple, actually. When ASP.NET parses the mark-up it creates an HtmlMeta server control with the name "Description" that has a Content property of a string type. And, of course, you can employ the same technique if you want to manipulate with other META tags on the page. Just use the proper value of a "name" attribute.



