<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>IProgrammable &#187; ASP.NET MVC</title>
	<atom:link href="http://www.iprogrammable.com/category/asp-net-mvc/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.iprogrammable.com</link>
	<description>Kawalerowicz Consulting News</description>
	<lastBuildDate>Wed, 15 Feb 2012 13:21:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>ASP.NET MVC custom binder for currency</title>
		<link>http://www.iprogrammable.com/2009/06/24/aspnet-mvc-custom-binder-for-currency/</link>
		<comments>http://www.iprogrammable.com/2009/06/24/aspnet-mvc-custom-binder-for-currency/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 06:05:41 +0000</pubDate>
		<dc:creator>marcin.kawalerowicz</dc:creator>
				<category><![CDATA[ASP.NET MVC]]></category>

		<guid isPermaLink="false">http://www.iprogrammable.com/2009_06_24/aspnet-mvc-custom-binder-for-currency/</guid>
		<description><![CDATA[I can imagine that&#8217;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; [...]]]></description>
			<content:encoded><![CDATA[<p>I can imagine that&#8217;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:</p>
<pre><span style="color: blue">public class </span><span style="color: #2b91af">TestModel
</span>{
    <span style="color: blue">public double </span>NumberField
    {
        <span style="color: blue">get</span>;
        <span style="color: blue">set</span>;
    }

    <span style="color: blue">public double </span>CurrencyField
    {
        <span style="color: blue">get</span>;
        <span style="color: blue">set</span>;
    }
}</pre>
<p><a href="http://11011.net/software/vspaste"></a><a href="http://11011.net/software/vspaste"></a></p>
<p>The MVC view is strongly typed with this <span style="color: #2b91af">TestModel</span>. And the view model value is formatted like this:</p>
<p><span style="background: #ffee62 none repeat scroll 0% 0%">&lt;%</span><span style="color: blue">=</span>Html.TextBox(<span style="color: #a31515">&#8220;NumberField&#8221;</span>, Model.NumberField)<span style="background: #ffee62 none repeat scroll 0% 0%">%&gt;</p>
<p></span><span style="background: #ffee62 none repeat scroll 0% 0%">&lt;%</span><span style="color: blue">=</span>Html.TextBox(<span style="color: #a31515">&#8220;CurrencyField&#8221;</span>, Model.CurrencyField.ToString(<span style="color: #a31515">&#8220;c&#8221;</span>))<span style="background: #ffee62 none repeat scroll 0% 0%">%&gt;</span></p>
<p><a href="http://11011.net/software/vspaste"></a></p>
<p>If you set the current culture to German-Swiss, for example in (base)controller like that:</p>
<pre><span style="color: blue">protected override void </span>Initialize(System.Web.Routing.<span style="color: #2b91af">RequestContext </span>requestContext)
{
    <span style="color: blue">base</span>.Initialize(requestContext);

    <span style="color: blue">string </span>culture = <span style="color: #a31515">"de-CH"</span>;

    <span style="color: #2b91af">CultureInfo </span>ci = <span style="color: #2b91af">CultureInfo</span>.GetCultureInfo(culture);

    <span style="color: #2b91af">Thread</span>.CurrentThread.CurrentCulture = ci;
    <span style="color: #2b91af">Thread</span>.CurrentThread.CurrentUICulture = ci;
}</pre>
<p>Done so we will get a text boxes looking like this:</p>
<p><a href="http://www.iprogrammable.com/files/2009/06/image.png"><img src="http://www.iprogrammable.com/files/2009/06/image-thumb.png" style="border-width: 0px" alt="image" border="0" height="51" width="212" /></a></p>
<p>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.</p>
<p>To deal with this issue we have to write our own model binder. This can be done by implementing the <span style="color: #2b91af">IModelBinder</span>. But I don’t want to reimplement this how <span style="color: #2b91af">DefaultModelBinder </span>reads other values than my currency doubles. So I though I will set a special attribute to the “special” properties. Something like this:</p>
<pre>[<span style="color: #2b91af">AttributeUsage</span>(<span style="color: #2b91af">AttributeTargets</span>.Property)]
<span style="color: blue">public class </span><span style="color: #2b91af">CurrencyAttribute </span>: <span style="color: #2b91af">Attribute
</span>{
}</pre>
<p>And my object:</p>
<pre><span style="color: blue">public class </span><span style="color: #2b91af">TestModel
</span>{
    <span style="color: blue">public double </span>NumberField
    {
        <span style="color: blue">get</span>;
        <span style="color: blue">set</span>;
    }

    [<span style="color: #2b91af">Currency</span>]
    <span style="color: blue">public double </span>CurrencyField
    {
        <span style="color: blue">get</span>;
        <span style="color: blue">set</span>;
    }
}</pre>
<p><a href="http://11011.net/software/vspaste"></a>And now we can overload the <span style="color: #2b91af">DefaultModelBinder </span>and implement our <span style="color: #2b91af">TestModelBinder </span>like this:</p>
<pre><span style="color: blue">public class </span><span style="color: #2b91af">TestModelBinder </span>: <span style="color: #2b91af">DefaultModelBinder
    </span>{
        <span style="color: blue">public override object </span>BindModel(<span style="color: #2b91af">ControllerContext </span>controllerContext,
            <span style="color: #2b91af">ModelBindingContext </span>bindingContext)
        {
            <span style="color: blue">object </span>bindingObject = <span style="color: blue">base</span>.BindModel(controllerContext,
                bindingContext);

            <span style="color: blue">foreach </span>(System.Reflection.<span style="color: #2b91af">PropertyInfo </span>propInfo
                <span style="color: blue">in </span>bindingObject.GetType().GetProperties())
            {
                <span style="color: blue">object</span>[] attributes =
                    propInfo.GetCustomAttributes(<span style="color: blue">typeof</span>(<span style="color: #2b91af">CurrencyAttribute</span>), <span style="color: blue">false</span>);

                <span style="color: blue">foreach </span>(<span style="color: blue">object </span>attribute <span style="color: blue">in </span>attributes)
                {
                    <span style="color: #2b91af">CurrencyAttribute </span>currAtt = attribute <span style="color: blue">as </span><span style="color: #2b91af">CurrencyAttribute</span>;

                    <span style="color: blue">if </span>(currAtt != <span style="color: blue">null</span>)
                    {
                        bindingContext.ModelState[propInfo.Name].Errors.Clear();

                        <span style="color: blue">string </span>attempted =
                            bindingContext.ValueProvider[propInfo.Name].AttemptedValue;
                        <span style="color: #2b91af">CultureInfo </span>ci =
                            bindingContext.ValueProvider[propInfo.Name].Culture;

                        propInfo.SetValue(
                            bindingObject,
                            <span style="color: blue">double</span>.Parse(attempted, <span style="color: #2b91af">NumberStyles</span>.Currency, ci),
                            <span style="color: blue">null</span>);

                    }
                }
            }

            <span style="color: blue">return </span>bindingObject;
        }
    }</pre>
<p><a href="http://11011.net/software/vspaste"></a>And now we have to set the attribute to our object to tell MVC that it has to use your binder.</p>
<pre>[<span style="color: #2b91af">ModelBinder</span>(<span style="color: blue">typeof</span>(<span style="color: #2b91af">TestModelBinder</span>))]
<span style="color: blue">public class </span><span style="color: #2b91af">TestModel
</span>{
    <span style="color: blue">public double </span>NumberField
    {
        <span style="color: blue">get</span>;
        <span style="color: blue">set</span>;
    }

    [<span style="color: #2b91af">Currency</span>]
    <span style="color: blue">public double </span>CurrencyField
    {
        <span style="color: blue">get</span>;
        <span style="color: blue">set</span>;
    }
}</pre>
<p><a href="http://11011.net/software/vspaste"></a>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!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.iprogrammable.com/2009/06/24/aspnet-mvc-custom-binder-for-currency/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

