Quick Fix: Unwanted Rounding When String Formatting Number as Currency

Sometimes it’s the little things you forget the easiest and most often that throw you for a loop. Today I was attempting to show a value in an ASP.NET MVC View which is stored as type long, representing a monetary amount in cents.

I formatted it as currency:

@string.Format("{0:c}", Model.Subtotal / 100)

But when I saw the output it rounded the value of 1250 to $12.00. This was strange since it was rounding down instead of up, which would still be incorrect, but at least make sense.

In an attempt to fix, I added a decimal place to the formatting:

@string.Format("{0:c2}", Model.Subtotal / 100)

But apparently currency is already set to two decimals. I can add more decimals, but it will always be zero, since it’s rounding.

I then realized that the Subtotal is long, which is an integer, as is of course 100, so it’s doing integer division. I need to cast one of the values to ensure the result doesn’t round. I defined the 100 value as a decimal by adding M at the end:

@string.Format("{0:c}", Model.Subtotal / 100M)

which revealed the expected output of $12.50 and I can go about my day.

It’s all so obvious in retrospect, but it’s one of those things that is easily forgotten. hopefully this note will help me remember!

as always, hope this was helpful and thanks for reading!

Dead Simple ASP.NET MVC Authentication

You may already know that, due to its lightweight architecture, ASP.NET MVC makes it simple to get a website up and running. But another advantage to such a manageable framework is how simple it is to implement any necessary component with just the bare minimum functionality.

One such requirement is the need to enforce Forms Authentication for your website. When creating a simple prototype, you’re probably not concerned with the specifics of the user security, implementation, but you probably do want to demonstrate it!

Read more at the Falafel Software Blog: Dead Simple ASP.NET MVC Authentication

Check if a Sitefinity Module is Installed or Disabled

When working with the Sitefinity API and its various Content Managers, you need to make sure and consider the fact that after version 5.1, users have the ability to disable modules. Attempting to access the content manager of a disabled module will result in an exception.

Developing an Add-in for Outlook 2010

I had a difficult time just finding relevant and useful information on just how the heck you do this. I searched for hours on MSDN, as well as general searching on the internet for variations of “how to create an outlook add-in” that yielded pretty useless results.

So this blog post is meant to list some of the helpful resources I WAS able to find, as well as some of the things I learned along the way.

JustCode is JustSmart

I was doing some coding today when I discovered something very slick about Telerik’s JustCode tool I just had to share.

Telerik-Just-Code-Context-Menu

I needed to add a property to a class, and my coding style puts private properties and their public accessors in separate #regions. I added the private member to the “Private Properties” region, and decided to let Just Code stub it out for me, expecting it to generate the public property directly beneath my private variable. I figured I would just copy and paste it into the appropriate region.

Imagine my surprise when instead of generating the code beneath my variable, it popped up inside my “Public Properties” region!

Telerik-Just-Code-Property

I thought that this might be a fluke, so I added a few test regions in between to see if it was just grabbing the first one after it. Sure enough, however, it popped right back into the right region!

Telerik-Just-Code-Property2

It’s the little things, you know?

More about JustCode ยป

MVC Attributes with SubSonic ActiveRecord T4 Templates

One of my favorite features of the ASP.NET MVC Framework is the ability to include form validation out of the box using Attributes. Marking a Model with the Required attribute and including a few script references enables a built-in framework that validates your forms automatically.

However, my ORM tool, SubSonic, by default doesn’t account for this, as it has its own rules for generatic the code for the data models. However, after playing with the T4 templates for a few minutes, I discovered just how easy it is to manipulate the generated code to fit right into the MVC framework.

In the ActiveRecord.tt file somewhere around line 358 is the template code for generating the data model classes. Between the private and public declaration of the individual properties, I simply added a check to see if the column is Nullable

If the column is not Nullable, that means it must have a value, and is therefore required. The CheckNullable method used returns a ? character, so I just used that to determine if the property should be included:

<#=col.SysType #><#=CheckNullable(col)#> _<#=col.CleanName #>;
<# if (CheckNullable(col) != "?") { #> [Required] <# } #>
public <#=col.SysType #><#=CheckNullable(col)#> <#=col.CleanName #>

Now when I look at my generated code, the required properties are now marked with the Required attribute. For example in my model I have a field for collecting a User’s Address, which I need to be required:

string _Address;
[Required]         
public string Address
{
    get { return _Address; }
    set {
        if(_Address!=value){
            _Address=value;
            var col=tbl.Columns.SingleOrDefault(x=>x.Name=="Address");
            if(col!=null){
                if(!_dirtyColumns.Any(x=>x.Name==col.Name) && _isLoaded){
                    _dirtyColumns.Add(col);
                }
            }
            OnChanged();
        }
    }
}

This allows me to now use and I can use this to validate this and any other required properties automatically:

item-validation

This pretty slick discovery is another on the growing list of reasons I truly enjoy developing with MVC and SubSonic. However, I am curious to see if I can do something similar with OpenAccess, which is the ORM I’ll be using for my next project. More on that when I get there!

Sitefinity Toolkit: Mobile Device Detection

IMPORTANT UPDATE FOR USERS OF SITEFINITY TOOLKIT 1.2

There is a compatibility issue between the Mobile Foundation library used for mobile detection and the Sitefinity Administration Login that could not be resolved. The Mobile Detection Module can still be used but the Mobile Foundation must be DISABLED in web.config by commenting out the related sections in web.config:

<!--
<sectionGroup name="fiftyOne">
<section name="log" type="FiftyOne.Foundation.Mobile.Configuration.LogSection, FiftyOne.Foundation" requirePermission="false" allowDefinition="Everywhere" restartOnExternalChanges="false" allowExeDefinition="MachineToApplication"/>
<section name="redirect" type="FiftyOne.Foundation.Mobile.Configuration.RedirectSection, FiftyOne.Foundation" requirePermission="false" allowDefinition="Everywhere" restartOnExternalChanges="false" allowExeDefinition="MachineToApplication"/>
<section name="wurfl" type="FiftyOne.Foundation.Mobile.Detection.Wurfl.Configuration.WurflSection, FiftyOne.Foundation" requirePermission="false" allowDefinition="Everywhere" restartOnExternalChanges="false" allowExeDefinition="MachineToApplication"/>
</sectionGroup>
-->

 <!--
<fiftyOne>
<wurfl wurflFilePath="~/App_Data/wurfl.xml.gz">
<wurflPatches>
<add name="browser_definitions" filePath="~/App_Data/web_browsers_patch.xml" enabled="true"/>
</wurflPatches>
</wurfl>
</fiftyOne>
-->

Commenting out these sections in web.config will disable the Mobile Foundation module from loading and interfering with the Sitefinity Login page. I hope to resolve this soon with the help of 51 Degrees, makers of the Mobile Foundation.


Overview

I think by far the best part of Sitefinity is how it is built on and makes full use of the ASP.NET architecture. Because of things like Code-Behind, Themes, Skins, and other foundations of the Framework, Sitefinity is more open and extensible than any other CMS platform I’ve ever used.

A direct consequence of the separation of content vs design is how easy it is to “swtich themes”. It’s as simple as populating a new Theme folder with new css and images mapped to the css classes defined in your page. It was a simple matter to take this one step further by creating a “Mobile” theme that can be switched to automatically based on the capabilities of the device accessing the site!

Detecting the device was the hard part. I experimented with many options including using the wurfl asp.net API, and then when that didn’t work, even building my own wurfl wrapper. Not having the time nor patience to dive into that can of worms, I was relieved to discover that an excellent mobile kit had already been developed by 51 Degrees. Their Mobile Toolkit is a GODSEND; easy to install, configure, and use! If you have ANY mobile device needs for your website, start with 51 Degrees!

Installation and Setup

The Sitefinity Toolkit already includes the necessary Mobile Toolkit libraries to run this feature, but make sure you download the correct version for your Sitefinity installation and unzip to your site’s bin folder.

In order for detection to work, you must make sure to download the latest WURFL definitions and patch file and place them somewhere accessible on your site (I placed mine in the App_Data folder). Map the files in your web.config, as well as some additional settings by adding the following to your config file (note the file locations):

<?xml version="1.0" encoding="UTF-8"?>
<
configuration>
<
configSections>
<
sectionGroup name="mobile">
<
section name="toolkit" type="Mobile.Configuration.ToolkitSection, Mobile, Version=0.1.5.0, Culture=neutral" allowDefinition="Everywhere" restartOnExternalChanges="false" allowExeDefinition="MachineToApplication"/>
<
section name="wurfl" type="Mobile.Devices.Wurfl.Configuration.WurflSection, Mobile, Version=0.1.5.0, Culture=neutral" allowDefinition="Everywhere" restartOnExternalChanges="false" allowExeDefinition="MachineToApplication"/>
</
sectionGroup>
</
configSections>

... <mobile>
<
toolkit logFile="~/App_Data/MobileLog.txt" logLevel="warn"/>
<
wurfl wurflFilePath="~/App_Data/wurfl.xml.gz">
<
wurflPatches>
<
add name="browser_definitions" filePath="~/App_Data/web_browsers_patch.xml" enabled="true"/>
</
wurflPatches>
</
wurfl>
</
mobile>
</
configuration>

NOTE: For detailed instructions on how to customize this configuration, please take a look at the .NET Mobile API User Guide from the 51 Degrees website.

Normally to use the toolkit, you would add their Detector HttpModule to your web.config. However, since this is running in Sitefinity, there’s a few extra steps I wanted to go through after detecting the device to store the status in session. This way, you don’t have to check the device on every session. Also, if a mobile user wants to see the full site, or vice-versa, you can save that in the session as well, bypassing the check (more on how to do that later).

To do this, I inherited from the default Detector module and made my own, so that’s the one you should add to your web.config HttpModules nodes:

For IIS 6

<system.web>
<
httpModules>
<
add name="BrowserDetector" type="SelArom.Net.Sitefinity.HttpModules.BrowserDetectModule" />
</
httpModules>
</
system.web>

For IIS 7

<system.webServer>
<
modules>
<
add name="BrowserDetector" type="SelArom.Net.Sitefinity.HttpModules.BrowserDetectModule" preCondition="managedHandler" />
</
modules>
</
system.webServer>

Detecting Page

Since all page requests in Sitefinity are internally routed through a single entry point (located at /Sitefinity/cmsentrypoint.aspx), you need to modify this page to inherit from the Toolkit Detector Page. This internal page handles all the fenagling to switch the to your mobile theme and master page (see next section below for requirements).

All you have to do is change the base class from which this entry point page inherits:

<%@ Page Inherits="SelArom.Net.Sitefinity.Pages.DetectingPage" MasterPageFile="~/Sitefinity/Dummy.master" %>

Mobile Theme Requirements

When a mobile device is detected (or the mobile view is forced, explained later), the Detecting Page above automatically switches to the “Mobile” theme and switches the underlying MasterPage to “Mobile.Master”. In order for this to work without crashing, you MUST have an ASP.NET Theme Folder named “Mobile” and it MUST be called “Mobile”. In addition, you MUST also define a “Mobile.Master” file in your App_Master folder (which MUST also exist). These are the files used by the Detector to switch themes.

In future releases I hope to be able to allow you to choose the themes and master pages, but for now, you can style and define these however you wish to best suit your website. However they MUST match these file names and MUST live in the specified folders.

For help getting started with a mobile theme, be sure and check out the Sitefinity Mobile Starter Theme available in the Sitefinity Marketplace. It is an awesome starter theme developed by the kind folks at Data Universal Inc.

Usage and Examples

After configuring everything above, your website should now automatically detect
mobile devices and switch themes. Try visiting any of these sites from a mobile device (or click the Mobile link to preview the mobile version on your PC); all of them use the Sitefinity Toolkit:

If you compare these to the full desktop versions, you’ll see that the text, links, pictures, and other content are pretty much exactly the same! This is because other than a few customizations here and there, it IS the same content. With this toolkit (and associated theme/master page) you don’t have to make a separate mobile site; you can feed the same content to ALL your users!

Switching Modes

Notice how both versions of these sites have a link for you to switch between mobile and full versions of the site. As you may have guessed from the links above, the “mobile” query string is used to switch between modes. Adding “?mobile=1” to the full site will switch to mobile, and it will KEEP that selection through all future pages until you either switch back or your session expires!

Switching back is simply a matter of appending the querystring to the current Url. You can place this link anywhere (I recommend on the header of your master page). Here is the code I use to create the link on the main page to swtich to mobile view (first define a HyperLink control called lnkMobile):

protected override void OnInit(EventArgs e)
{
    base.OnInit(e);

    var url = Request.RawUrl.ToLower();
    if (url.Contains("mobile="))
        url = url.Replace("mobile=0", "mobile=1");
    else if (url.Contains("?"))
        url = string.Concat(url, "&mobile=1");
    else
url = string.Concat(url, "?mobile=1"); lnkMobile.NavigateUrl = url; }

To switch back, simply reverse the polarity of the mobile flag (Add this to your Mobile.Master page):

var url = Request.Url.ToString().ToLower();
if (url.Contains("mobile="))
    url = url.Replace("mobile=1", "mobile=0");
else
if
(url.Contains("?")) url = string.Concat(url, "&mobile=0"); else
url = string.Concat(url, "?mobile=0"); lnkFull.NavigateUrl = url;

In a much later release I hope to include a “SwitchModeLink” control that you can drop onto a page, but for now, the code above should work just fine.

Tookit Version 1.1

I’ve discovered a few bugs and issues in the 1.0 release of the toolkit, and I’ll be creating a separate post to go over the details. However, there is one change to this particular feature I’d like to quickly cover.

In 1.0, the querystring remained appended to the url, causing double indexing in google to the same page. Since these are technically the same page, they should only have one Url.

So for 1.1 I’ve modified the code so that when you switch modes with the Querystring, the Detector HttpModule will automatically 301 redirect that Url to the correct Url that does NOT have that mobile flag in it. That way when your pages are crawled, only the original url to your page is ever indexed.

I hope to publish 1.1 before the end of the week. If you need it RIGHT AWAY (such as if you’re experiencing some bugs) lease email me and I’ll send you a link to download it. Those requests accompanied by a kind donation (see sidebar for details) will get a priority response, but of course no donation is ever required to access my work (though it’s always appreciated)!

If I left anything out, please let me know, and as always your comments and suggestions are welcome.

Toolkit Version 1.2

The Module will now no longer crash if the Mobile theme and Master Page are not present. Instead, the Module will create the empty theme and assign it, using the default Master Page in place. This should create a clean, mostly empty style that should render well on mobile devices.

There are some other improvements and tweaks, but make sure you take note of the very important issue noted at the top of this blog post. I will release a fix as soon as I get one worked out.

Sitefinity Toolkit: iCal Event Reminder

One of the best features of Sitefinity is the Events Module. But while you can easily add and categorize events, and even show a nifty interactive map on the event detail page, there isn’t any built-in way to let your visitors add the event to their Outlook calendar.

Fortunately, with the help of DDay.iCal Class Library by Douglas Day, I was able to bring easily incorporate this functionality. The process basically reduces to this:

  1. Retrieve the Event ID from the event details page
  2. Pass that ID to an ashx handler, which returns an iCal item

Installation and Usage

Of course you need to download the Sitefinity Toolkit and unzip it to your site’s bin directory. Be sure that you download the version that matches your Sitefinity installation, and that you have the included DDay.iCal and antl.runtime libraries, as they are required for this module.

You need to register the ASHX handler for the event reminders. This takes an Event ID and returns an iCal item. Add the following to your web.config:

<httpHandlers>
    <add verb="GET" path="/eventreminder.ashx" type="SelArom.Net.Sitefinity.HttpHandlers.EventReminder" />
</httpHandlers>

If you are using IIS 7 be sure to register the handler in the system.webserver node as well:

<system.webServer>
    <handlers>
        <add name="EventReminder" verb="GET" path="/eventreminder.ashx" type="SelArom.Net.Sitefinity.HttpHandlers.EventReminder" />
    </handlers>
</system.webServer>

Event Details External Template

In order to add the Event Reminder link to your event details page, you must map the Event Details page to an external template. The external template you map MUST include the code behind page, since this is where you’ll be adding code to retrieve the Event ID.

On the front-end (.ascx file) of your external template, add a HyperLink control, which is what users will click to get the iCal item.

<asp:HyperLink ID="CalendarReminder" runat="server" ToolTip="This event occurs in the past" Enabled="false" />

Take special note of the properties that are set here. By default, the link will not be enabled, because for events in the past, there should be no need to set a reminder.

Now we need to set the code that will retrieve the current events id, and if necessary, enable and build the link to the reminder. Add the following to your Page_Load event.

protected void Page_Load(object sender, EventArgs e)
{
    // retreive event item from current view
    var view = Parent.Parent as EventsView;
    var mgr = new EventsManager("Events");
    var ev = mgr.GetEventByContentId(view.SelectedItemId);

    // if event is not in the past
    if (ev.End >= DateTime.Now)
    {
        // build and enable link to reminder
        CalendarReminder.Enabled = true;
        CalendarReminder.ToolTip = string.Concat("Add a Reminder for ", ev.EventTitle, " to Outlook");
        CalendarReminder.NavigateUrl = string.Format("~/EventReminder.ashx?id={0}", ev.ID);
        CalendarReminder.Text = "Add To Outlook";
    }
}

As you can see, we’re using reflection to grab the selected item’s id from the EventsView control that is embedded with our template. There may be a better way to retreive this (especially since SelectedItemId is an obsolete member) but for now, this does the trick.

Next you need to check the event end date. If it’s not yet past, build the link from the event metadata and enable the link.

That’s pretty much all there is to it! If I missed anything please let me know, and if you have any suggestions or comments send them my way as well. If you enjoy this toolkit or any of my other work, please consider kicking a small donation to my studio fund via the sidebar on the right.

Sitefinity: Password Recovery

As a developer, one of the things I hate most about my job is when people call me to fix their login errors, especially when the problem is a forgotten password:

Are you sure you remember your password? Yes.

Are you sure you typed the password correctly? YES!

Are you SURE? YES!!

Do you have CAPSLOCK on? … … oh [click]

While there’s not much I can do to help them remember how their keyboard works, I can at least help maintain my sanity by enabling them to recover their passwords when they forget them.

My Sitefinity Password Recovery is available for download in my Software section. Simply unzip to your /Sitefinity folder, overwriting your login.aspx file (backup as always!).

What I like about this solution is that it first sends the user an email containing a reset link and confirmation code. This makes sure that the password is not reset by accident, and that only the user can reset the password.

As noted, these pages require that your web.config file is configured to send emails. See the Sitefinity Password Recovery page for more details, and as always, your comments and suggestions are welcome and appreciated.