View Errors Migrating WebForms To ASP.NET MVC Pattern

I’ve been working a project where we had a really solid WebForms application, but wanted to utilized ASP.NET MVC and more client side programming.  We created some partial views used by some controllers and kept getting this error “The name 'Model' does not exist in the current context”.  It turns out that the the Views folder needs a web.config file underneath it.  The easiest way to do this is to copy a web.config from the Views folder in a template project of a MVC web app.

.NET Localization And Your Application

In today’s market, localization is a forward thinking design decision, or is it?  If your application is going to be a full blown multi-lingual application, I’d say that localizing is a great idea, but if it’s it’s going to other countries where it’s understood that the application is geared towards a particular business language (typically English) why bother.  Localization is one of those decisions that should be made upfront and thought through, because adding it after the fact is a real pain.  I worked for a POS company where the application necessitated it be in multi languages.  I worked at another company, an online Ad company company, where it wasn’t cut and dry.  At the Ad company we had 3 applications, one for internal employees, one for publishers, and one for advertisers.  At this Ad company, our internal users were split between a couple of countries and one of the countries had 2 languages.  These internal users only spoke English, so the idea of localizing the application would be a waste of time.  On the other hand our external applications were growing, and just because the root of business started in the US and Canada, that shouldn’t blind us from considering foreign countries.  Opening you Ad network to all languages would increase you share of the market and localization is an easy way to accomplish this.

A great article on using localization in ASP.NET can be found here, Extending the ASP.NET 2.0 Resource-Provider Model.  Even though this article focuses on ASP.NET, much of it can be utilized by WinForms.  In a lot of MS examples out there they talk about storing image paths, image files, etc. but in my experience I’ve found that the most important resource to store is just text.  I define different text types to be in these categories: word or word group, full sentence or paragraph, and replacement text.  A word or word group is text that always stands alone.  Replacement text is a category I put dynamic typed items, for example “Item number {0} has not been found.” which would be used with the string.Format method.  Replacement text is the trickiest, because in almost all languages, order at which you arrange the noun/verbs is different and not literally translatable from English.  Below is a list of considerations to think about when internationalizing an application.

  • Width of labels, buttons, columns, or any area that has some perceivable width constraint.  A lot of time the English words take much less space than their translated counterpart.  This can lead to bizarre and undesirable UI shifting or hidden overflow.
  • Stay away from using slangs or acronyms.  Slangs are tough because there typically isn’t a correct translation for it.  Acronyms should only be used if they are and industry standard, for example mass in kg instead of kilogram is standard in any language.  On the other hand, something like ROI (return on investment) should most likely be spelled out.
  • When using replacement text, the translator should be given some context in which the sentence or phrase is used in so that word ordering can be correct especial when phrase contains words that have double meaning.  For example, a replacement text with double meaning could be “Server {0} is not found.”, which a translator can make the easy mistake of assuming this is a computer server or a restaurant server.  In English the word is interchangeable but not in other languages.
  • Considering limiting yourself to fewer dialects than more.  There’s little use in, for instance, translating all the various dialects of French.  Unless there is an overwhelming need to, like zh-cn and zh-hk, don’t.

jQuery Kicks Ass

If Chuck Norris were a javascript framework, he would be jQuery.  If you spell jQuery in the game of Scrabble , you win for ever.  That’s how awesome jQuery is.  I’ve used many a javascript frameworks, such as prototype.js, mootools, and script.aculus.us, but none have I found so flexible, so light, and so extendable a jQuery.  The core framework is very compact and whatever you need that the core does not provide, you can find a jQuery plugin that will do it.  I’m not really going to go into any examples, this blog is more like a notebook of common plugins that I’ve found very useful.  As a note to Visual Studio users, they have done a excellent job of providing javascript intellescene and now ship ASP.NET MVC with jQuery plus a .js file with all the code commenting.

Date pickers

http://www.eyecon.ro/datepicker/

http://arshaw.com/fullcalendar/ (full calendar)

Validation

http://validity.thatscaptaintoyou.com/

http://bassistance.de/jquery-plugins/jquery-plugin-validation/

Tooltip

http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/

Templating

http://publicityson.blogspot.com/2009/11/dynamic-content-using-html-templates.html

The Log In This Blog

One thing I have to praise about moving from one job to another in the software industry, is all the new tools you pick up or pass on.  This is not always the case, but hopefully your move is an equal or better learning experience.  Such a simple but powerful tool have I seen, and this is the log4net logging framework for .NET.  This framework is actually ported from the benevolent log4j framework which is the Java equivalent.  It’s simple, elegant, and gets the job done.  Many open source projects for both Java and .NET utilize this framework because it is so powerful.  The main points to take away is that it’s easy to configure, easy to add different logging capabilities, and lightweight. 

To get log4net working in .NET, you need to do the following easy steps:

1)  Download log4net from Apache’s website.

2)  Add the correct information in the app.config, in case of a web site this would be the web.config.  Below show’s an example of the simplest setup.  A section is added to the <configSections>, which allows the log4net framework to be loaded via app.config settings only. This is convenient for web applications since IIS doesn’t need to be restarted for changes to take affect. In the section <log4net>, you define "appenders", which are the classes that handle whatever type of logging that is desired; you can even adjust specific logging for other frameworks such as NHibernate, which utilizes log4net. The SDK describes all the built in appenders which include, but not limited to file types, database, UDP, event log, etc. For each appender that is added, you need to add the appropriate <appender-ref> element to the root element inside the log4net section. The last important item is the logging level which is listed below as well.

Available logging levels: ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF

<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender" >
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level %logger [%ndc] - %message%newline" />
</layout>
<file type="log4net.Util.PatternString" value="C:\SomeDirectoryPath\SomeFileName-%date{yyyyMMdd}.txt" />
<!--<file value="example_log.txt" />-->
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyyMMdd" />
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingFileAppender" />
</root>
</log4net>
3)  Put the logger in your code for use.  Using log4net in your code is even easier.  In order to get the logging working, you need to make sure it initializes.  Below shows a way to do this for a web app and a windows type service.
//////////////////////////
// for a web app
/////////////////////////
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
// init web.config configured logger before any logging occurs
log4net.Config.XmlConfigurator.Configure();
}
}

//////////////////////////
// for a windows service
/////////////////////////
private void OnStart()
{
// init app.config configured logger before any logging occurs
log4net.Config.XmlConfigurator.Configure();
}
Now to use the logging in your application code add something similar to the following class example.  Registering the class with the logger allows the logging to indicate where exactly the information is coming from.  This is actually very useful since you don’t have to write statements like “MethodNameXYZ had an error….”.
public class FooBar
{
private static readonly ILog _log = LogManager.GetLogger(typeof(FooBar));
private static readonly bool _isDebugEnabled = _log.IsDebugEnabled;

public void DoSomething()
{
_log.Info("I'm starting to do something really useful.");

// better performance than calling _log.Debug(...); OR (_log.IsDebugEnabled) ...
if (_isDebugEnabled)
_log.Debug("Some extra useful debug info...");

try {...}
catch (Exception x)
{
_log.Error("Oh darn, something bad happened", x);
// you can also do LogManager.GetLogger(typeof(FooBar)).Error(...) if you don't want to have a static.
}
finally {...}
}
}