Reporting Services Alternating Row Colors

Reporting Services is a easy way to produce good reports with little effort.  A common tablature based report style is to have rows of alternating color.  This eases the readers eyes when it comes to visually scanning and extracting data row by row.  In order to alternate the row color, you need to give the BackgroudColor property of the row a formula to determine which color to apply.  Here is a basic formula to switch colors between white and gray.

=iif(RowNumber(Nothing) Mod 2, "White", "Gainsboro")

The UI property window would look like the image shown below, where the red arrow points to the tables highlighted row.

rs_row_alt_color

Using Subversion With Visual Studio

There are a few source control options out there, other than TFS, that provide good source control if you are working in Visual Studio.  If you have an operation that doesn’t need or want to spend the money of TFS, Subversion (SVN) is a good alternative.  You can even sign up for free SVN at Unfuddle; they also have priced packages as well.  Using SVN with Visual Studio is actually quite easy using the plugin by AnkhSVN.  One of the nice features is that you can use this SVN plugin in conjunction with TFS.  The following shows how to set this up.

1.  Download and install AnkhSVN for your version of Visual Studio.

2.  Once AnkhSVN is installed, you must tell Visual Studio to use this as the source control system.  Navigate to Tools^Options.  You will see a screen like the one below.  Select the AnkhSVN source control option.

selecting_source_control_options 

3.  Now we can add our solution or project to SVN source control.  If you right click a solution or project in the Solution Explorer you will see SVN options like the image below.

add_sln_to_svn

In this case I was adding a solution, so select “Add Solution to Subversion”.  A window will appear like the image below.  This is where you select the SVN source control location.  Verify that all the other settings are as you want, such as Project Name or Local Folder (the location of the code you are adding).  Once everything is set, click OK and all the files will be uploaded to SVN.  Once the files are uploaded you will see a “+” sign next to everything.  Right click on the solution one more time and select “Commit Solution Changes”.  This should change the yellow “+” to a green check mark.  Your done.

add_sln_window

4.  Once everything is is checked in, you can go about modifying code again.  Anytime you modify a file, you will see a red check mark next to the file; this is similar to TFS’s little edit person icon when a file is in shared edit mode.  To check the file back in, just right click the file, project, or solution and select “Commit…”, “Commit Project Changes”, or “Commit Solution Changes”, respectively.  It’s that easy.

Using master dbschema File To Resolve Login References

If you’re using MS SQL Server, Visual Studio’s database projects are a good way to manage your database objects.  After importing your database schema, if you working with existing databases, or creating from scratch, you will typically need a reference to the master.dbschema.  A typical error due to an unresolved server login reference will say “Error TSD03006: User: [someuser] has an unresolved reference to Login [someuser].”.

The schema file is just a xml file of the server object meta data, this is how it can resolve references when referenced by other database projects in your solution.  The VS Database Project comes with master.dbschema files that you can copy and modified if needed.  The different version of SQL server schema files can be found in “C:\Program Files\Microsoft Visual Studio 9.0\VSTSDB\Extensions\SqlServer\”, if “C:\Program Files\” is your installed path of VS.  I would copy the master.dbschema file that you need to another location and rename with an appropriate name so others know what it represents.  If you have server logins that you don’t want to manage through you build and deploy, adding them to this copied master schema file is the way to resolve the build references.  Below shows the an example of the element that would need to be added to the dbschema file to resolve a particular login, the added part is italicized and bold.

<DataSchemaModel FileFormatVersion="1.0" SchemaVersion="1.0" DspName="Microsoft.Data.Schema.Sql.SqlDsp.Sql100DatabaseSchemaProvider" CollationLcid="1033" CollationCaseSensitive="False">
<Header>
<CustomData Category="ModelCapability">
<Metadata Name="ModelCapability" Value="Default" />
</CustomData>
<CustomData Category="DBSchema">
<Metadata Name="DatabaseType" Value="master" />
<Metadata Name="SqlServerVersion" Value="10.00" />
<Metadata Name="Author" Value="Microsoft Corp." />
</CustomData>
<CustomData Category="DatabaseVariableLiteralValue">
<Metadata Name="Name" Value="master" />
</CustomData>
</Header>
<Model>
<Element Type="ISql90Login" Name="[someuser]">
<Property Name="DefaultLanguage" Value="us_english" />
<Property Name="IsCheckPolicyOn" Value="False" />
<Annotation Type="GloballyScoped" />
</Element>

</Model>
</DataSchemaModel>
 
Once this is added, the login in reference error will resolve correctly.  Notice that I only have the one <Element> under the <Model> node.  If your projects don’t require usage of most of the master server objects, like extended procedures, you can removed them from the <Model> node.  Doing this trimming is worth the effort, especially in the cases where your using another projects dbschema file of which only a few items are needed to resolve references.  A good article of dbchema file trimming can be found here Right sizing the master.dbschema file for better design time performance.  Only including the necessary element in the model will reduce build time for projects depending on the schema file.

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 {...}
}
}