ASP.NET MVC custom binder for currency

June 24, 2009 on 8:05 am | In ASP.NET MVC, DotNet | No Comments

I can imagine that’s quite common problem. You have a double (or better decimal) value that you want to show formatted as a currency field. Lets assume we are storing the price data in an object like this:

public class TestModel
{
    public double NumberField
    {
        get;
        set;
    }

    public double CurrencyField
    {
        get;
        set;
    }
}

The MVC view is strongly typed with this TestModel. And the view model value is formatted like this:

<%=Html.TextBox(“NumberField”, Model.NumberField)%>

<%=Html.TextBox(“CurrencyField”, Model.CurrencyField.ToString(“c”))%>

If you set the current culture to German-Swiss, for example in (base)controller like that:

protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
    base.Initialize(requestContext);

    string culture = “de-CH”;

    CultureInfo ci = CultureInfo.GetCultureInfo(culture);

    Thread.CurrentThread.CurrentCulture = ci;
    Thread.CurrentThread.CurrentUICulture = ci;
}

Done so we will get a text boxes looking like this:

image

What will happen if you use a default binder to get this value? The default binder will try to parse the string as a double value and get an ModelState error. The string does not represent a double value.

To deal with this issue we have to write our own model binder. This can be done by implementing the IModelBinder. But I don’t want to reimplement this how DefaultModelBinder reads other values than my currency doubles. So I though I will set a special attribute to the “special” properties. Something like this:

[AttributeUsage(AttributeTargets.Property)]
public class CurrencyAttribute : Attribute
{
}

And my object:

public class TestModel
{
    public double NumberField
    {
        get;
        set;
    }

    [Currency]
    public double CurrencyField
    {
        get;
        set;
    }
}

And now we can overload the DefaultModelBinder and implement our TestModelBinder like this:

public class TestModelBinder : DefaultModelBinder
    {
        public override object BindModel(ControllerContext controllerContext,
            ModelBindingContext bindingContext)
        {
            object bindingObject = base.BindModel(controllerContext,
                bindingContext);

            foreach (System.Reflection.PropertyInfo propInfo
                in bindingObject.GetType().GetProperties())
            {
                object[] attributes =
                    propInfo.GetCustomAttributes(typeof(CurrencyAttribute), false);

                foreach (object attribute in attributes)
                {
                    CurrencyAttribute currAtt = attribute as CurrencyAttribute;

                    if (currAtt != null)
                    {
                        bindingContext.ModelState[propInfo.Name].Errors.Clear();

                        string attempted =
                            bindingContext.ValueProvider[propInfo.Name].AttemptedValue;
                        CultureInfo ci =
                            bindingContext.ValueProvider[propInfo.Name].Culture;

                        propInfo.SetValue(
                            bindingObject,
                            double.Parse(attempted, NumberStyles.Currency, ci),
                            null);

                    }
                }
            }

            return bindingObject;
        }
    }

And now we have to set the attribute to our object to tell MVC that it has to use your binder.

[ModelBinder(typeof(TestModelBinder))]
public class TestModel
{
    public double NumberField
    {
        get;
        set;
    }

    [Currency]
    public double CurrencyField
    {
        get;
        set;
    }
}

Done! Although there are a view issues with this solution (if you are using Entity Framework you cannot set custom attributes, and in the binder above you will have to implement checking if the field is present on the view), but you get the general idea!

Easiest way to have 2 submit button in one html form

June 12, 2009 on 4:41 pm | In JavaScript, DHTML, DotNet | No Comments

Here is the easiest way to have two (or more) submit buttons in one html form and to make them “do” something else. It is very helpful if you are planning to implement a toolbar like behavior. Example is from ASP.NET MVC but it does not matter. Since it uses JavaScript to dynamically change the action attribute of a form tag, it can be used everywhere. Here it is:

    <h2><%= Html.Encode(ViewData[“Message”]) %></h2>

    <script language=”javascript” type=”text/javascript”>
        function ChangeFormAction(sender, url) {
            sender.form.action = url;
        }
    </script>

    <form method=”post”>
        <input id=”text” name=”text” type=”text” value=”Hello from Action” />
        <br />
        <input type=”submit” value=”Go to action 1″
            onclick=”ChangeFormAction(this, ‘/Home/Action1′)” />
        <input type=”submit” value=”Go to action 2″
            onclick=”ChangeFormAction(this, ‘/Home/Action2′)” />
    </form>

And the actions that responds to this form are here:

public class HomeController : Controller
{
    public ActionResult Action1(string text)
    {
        ViewData[“Message”] = text + “1″;

        return View(“Index”);
    }

    public ActionResult Action2(string text)
    {
        ViewData[“Message”] = text + “2″;

        return View(“Index”);
    }
}
Nice!

Keep your lib folder up to date

February 9, 2009 on 10:22 pm | In NUnit, SVN, DotNet | No Comments

I’m keeping all the 3rd party assemblies that I use in my .NET projects in a separate library folder called lib. It is a part of my Subversion repository. In most of my project it is placed in linked repository (with svn:externals property). It lets my check out the whole project on any machine I like and it compiles right away.

But be aware! In such scenario (and, well… in any other scenario as well) you have to keep your lib up to date. Take a look at this nasty bug. I was using the NUnit version 2.4.6.0

Take a look at this test method:

[NUnit.Framework.Test]
public void Test()
{
    System.Text.ASCIIEncoding ASCIIEncoding = new System.Text.ASCIIEncoding();

    string str1 = “abc”;

    byte[] array = ASCIIEncoding.GetBytes(str1.ToCharArray());

    System.Array.Resize<byte>(ref array, 10);

    string str2 = ASCIIEncoding.GetString(array);

    NUnit.Framework.Assert.AreEqual(str1, str2);
}

What would you expect?

image

Fail! Isn’t it?

No! 1 passed, 0 failed, 0 skipped, took 0,54 seconds.

Even NUnit hast bugs to! I’ve updated to the newest version and it works as a charm! So keep you lib folder up to date!

How to associate a file extension with a given file?

January 12, 2009 on 9:25 pm | In Windows | No Comments

(Windows) You can edit a file type in Explorer (XP: Tools –> Folder options, Vista: Start –> Default Programs). But lets say you want to do it automatically and you have to set an additional parameter to the program you want to start (I have still not figured it out how to define such parameter under Vista). The easiest way is to create a file with *.reg extension that contains this script:

image

Red (cicstarter) – Schell command name

Blue (startf) – Action name

Brown (cicvlm.exe f=\”%1\”) – Application path (parameter inside f=)

Green (.cic) – File extension

You can manipulate the colored parts to feet your needs. Here is the script. Good luck!

SQL from Linq to Entity Framework

November 27, 2008 on 8:49 am | In Oracle, DotNet | No Comments

Problem: how do I tell what SQL does Linq to Entity Framework generates?

If you are using SQL Server its easy. You start the SQL Profiler and you are done. If you are using Oracle the task is not so easy. You can:

1. start the trace on the Oracle server and get the huge barely readable text file physically on the server and use TKPROF

2. look up the lat SQL query from session using the Enterprise Manager-Konsole

3. buy a 3rd party tool like FlexTracer to trace the OCI communication.

Well yeah! Not fun.

But there is another option inside Entity Framework itself! It is not quite obvious, so it took me a little to figure it out:

((System.Data.Objects.ObjectQuery)Query).ToTraceString()

where Query is something like System.Linq.IQueryable<T>.

Everyone is entitled to broad opinion

October 26, 2008 on 8:18 pm | In DotNet | No Comments

I had an interesting dispute with my colleague weather to use only qualified type names in code or not. He insisted that we should not use the using directive to introduce a namespace but to write the fully qualified name every time it is necessary. I had quite opposite opinion but I agreed to give it a try. So I started to write

public class MyClass
{
    public static void Main()
    {
        System.Console.WriteLine(“Foo”);
    }
}

instead of

using System;
public class MyClass
{
    public static void Main()
    {
        Console.WriteLine(“Foo”);
    }
}

Unfortunately over time it proofed no value to me. I was not happy with this rule, but I thought I’ll consult the brother audience for opinion before I start a holly war against something that I might not fully understand.

I decided to give stackoverflow.com a try. It is quite new Q&A Service dedicated specially for software developers. I write my question I was given a flood of answers. Some better, some worse. Some hitting the bottom line, some pouring “divine knowledge” of individuals that think they know things better.

Nevertheless the discussion on stackoverflow.com helped my back my opinion. Give it a try!

MTS 2008, Warsaw, Poland

October 12, 2008 on 10:28 pm | In DotNet | No Comments

image

Microsoft Technology Summit 2008 (8th and 9th November), the biggest  Microsoft technology event in Poland went quite well. It was my first MTS and I was trying not to expect anything special. And indeed I haven’t experienced anything  earth shaking but altogether it was quite interesting and a good investment of time. I surely learned a few new things and meet interesting people there. I was astonished by the sheer number of attendees that gathered in there. I presume the old communist “castle” in the center of Warsaw the “Palace of Culture and Science” was the only place to accommodate this whole crowd, but it is not a cushy place. It’s big and cold and far from perfect to host a technology event like that. And well… despite the overwhelming size of this place, you almost have to eat you lunch on the floor, because there was no enoimageugh tables ;-)

But I passed the 70-543 Exam there and gained the Microsoft Certified Professional Developer in ASP.NET title. So altogether it was a full success!

What null smaller than 0? Adventures with nullable types in .NET

September 9, 2008 on 9:14 pm | In DotNet | No Comments

Lets say we have two nullable integers like this:

int? i = null;
int? j = 0;

Is null smaller than 0

Console.WriteLine(i < j);

False – no it is not.

So probably null is greater than 0

Console.WriteLine(i > j);

False – no it is not greater as well.

All right! So null is equal 0. It has to be, JIT has no other choice, right?

Console.WriteLine(i == j);

Well False too! This two little fellows are not equal too. What? Is it raining frogs and we about to experience Armageddon?

No! We have to use Nullable.Compare() and we will by back in normal world:

switch (Nullable.Compare(i, j))
        {
               case -1:
                  Console.WriteLine(”i < j“);
              break;
               case 1:
                  Console.WriteLine(”i > j“);
              break;
               case 0:
                  Console.WriteLine(”i == j“);
              break;
        }

0 is a little more than null. null is less than 0. null equals null and 0 equals 0.

Uff!

Enum Factory

August 10, 2008 on 9:16 pm | In DotNet | 2 Comments

I have a little tip for you. Let’s say you have an enumeration. You need a enumeration constant out of string variable. simply use System.Enum.Parse(). Here a small Snippet Compiler source code.

using System;
using System.Collections.Generic;

public class MyClass
{
    public enum FooBar
    {
        Foo,
        Bar,
        FooBar
    }

    public static void Main()
    {
        WL(FooBarFactory(”Foo“));
        RL();
    }

    public static FooBar FooBarFactory(string init)
    {
        try
        {
            return (FooBar)System.Enum.Parse(typeof(FooBar), init);
        }
        catch
        {
            // Do something
            throw;
        }
    }

    #region Helper methods

    private static void WL(object text, params object[] args)
    {
        Console.WriteLine(text.ToString(), args);
    }

    private static void RL()
    {
        Console.ReadLine();
    }

    private static void Break()
    {
        System.Diagnostics.Debugger.Break();
    }

    #endregion
}

Silverlight for everybody

June 22, 2008 on 5:32 pm | In Silverlight, DotNet | No Comments

image My fist text for a Polish computer magazine NEXT hast just been published. It is called “Silverlight for everybody”. New publisher new challenge. I hope for a long lasting collaboration. In a mean time you can check my GeoCodedCalcualtor. A simple piece of Silverlight app that calculates the degrees, minutes, seconds form of latitude, longitude notation to a numeric notation and shows the translated coordinates using Google Static Maps Api. Enjoy!

Next Page »

Powered by WordPress with Pool theme design by Borja Fernandez.
Entries and comments feeds. Valid XHTML and CSS. ^Top^