Tag Archives: C#

QuickBytes: Decimal to Indian Numeric formatting

image

Recently I came across the need to format Decimal as Currency, but force it down to Indian/Vedic/South Asian numeric formatting (thousands, lacs, crores etc.) instead of the standard Arabic/Metric system (thousands, hundred thousands, million, billion etc.).

The answer was easily found in this StackOverflow thread. The code snippet is reproduced here:

string fare = “123000.0000”;
decimal parsed = decimal.Parse(fare,
CultureInfo.InvariantCulture);
CultureInfo hindi = new CultureInfo(“hi-IN”);
string text = string.Format(hindi, “{0:c}”, parsed);

The above code gives us the following string

₹ 1,23,000.00

However, the next requirement was to keep the decimals and formatting but remove the Currency symbol. Another quick search gave us this little gem from Jon Skeet on StackOverflow. Essentially he extracted the NumberFormatInfo from the CultureInfo and reset the Currency Symbol to an empty string. Then use the NumberFormatInfo instance to format the decimal value. So the above code can be modified as follows:

string fare = “123000.0000”;
decimal parsed = decimal.Parse(fare,
    CultureInfo.InvariantCulture);
CultureInfo hindi = new CultureInfo(“hi-IN”);
NumberFormatInfo hindiNFO =
    (NumberFormatInfo)hindi.NumberFormat.Clone();
hindiNFO.CurrencySymbol = string.Empty;

string text = string.Format(hindiNFO, “{0:c}”, parsed);

This gives us the following string. It’s difficult to see here but there is a leading space that you might want to trim if you need to.

1,23,000.00

A Sample Application

I thought it would be a fun project to write some code that gives you the above code for any Culture Code you want, so I setup a basic ASP.NET project and deployed it for free on the AzureWebsites. You can see it in action here – Currency Formatter on Azure WebSites

  • I spun up Visual Studio 2013 and setup a default MVC project.
  • Next I updated KnockoutJS to the latest version

PM> update-package KnockoutJS

  • Added an Entity to encapsulate the culture information. I referred to this list on MSDN as my source.

public class IsoCultureInfo
{
    public int Id { get; set; }
    public string LanguageCultureName { get; set; }
    public string DisplayName { get; set; }
    public string CultureCode { get; set; }
    public string ISO639xValue { get; set; }
}

  • Scaffolded up an EntityFramwork controller: CultureInfoController
  • Added two methods to the CultureInfoController that return JsonResults
  • The first one simply returns the entire list of IsoCultureInfo objects in the DB

public JsonResult List()
{
    return Json(db.IsoCultureInfoes.ToList(), JsonRequestBehavior.AllowGet);
}

  • The second one formats the predefined text based on the incoming Culture Name and returns the formatted text as a JSON object.

public JsonResult FormattedText(string id)
{
     try
     {
         string fare = "123000.0000";
         decimal parsed = decimal.Parse(fare, CultureInfo.InvariantCulture);
         CultureInfo cultureInfo = new CultureInfo(id);
         NumberFormatInfo cultureNFO = (NumberFormatInfo)
cultureInfo.NumberFormat.Clone();
         //cultureNFO.CurrencySymbol = string.Empty;
         string text = string.Format(cultureNFO, "{0:c}", parsed);
         return Json(new { formattedCurrency = text });
      }
      catch (Exception ex)
      {
          return Json(new { formattedCurrency = "N/A" });
      }
}

  • Both these methods are invoked from the Index HTML. The UI is databound to a Knockout ViewModel. This is defined in the script formatCurrency.js

/// <reference path="_references.js" />

var isoCultureInfo = {
    LanguageCultureName : ko.observable(“”)
};

var viewModel = {
    dataList: ko.observableArray([]),
    formattedString: ko.observable(“Test”),
    selectedCulture: ko.observable(isoCultureInfo)
};

$(document).ready(function () {
    $.ajax(“/CultureInfo/List”,
        {
            type: “GET”,
            contentType: “text/json”
        }).done(function (data) {
            viewModel.dataList = ko.mapping.fromJS(data);
            ko.applyBindings(viewModel);

            viewModel.selectedCulture.subscribe(function(newValue){
                if (newValue.LanguageCultureName() != ”) {
                    var data = { “id”: newValue.LanguageCultureName() };
                    $.ajax(“/CultureInfo/FormattedText”,
                        {
                            type: “POST”,
                            contentType: “application/json”,
                            data: JSON.stringify(data)
                        }).done(function (data) {
                            viewModel.formattedString(data.formattedCurrency);
                        }).error(function (args) {
                            alert(“”);
                        });;
                };
            });
        }).error(function () {

        });
});

  • Finally I updated the Index.cshtml of the Home Controller to show the dropdown with the list of culture info.

        Select Culture: <select id="cultureOptions"
                                class="form-control"
                                data-bind="options: dataList(), optionsText: 'LanguageCultureName', value: selectedCulture, optionsCaption: 'Choose...'"></select>

  • Added a <ul> to show all the property values of the selected Culture

<ul>
    <li>Language Culture Name: <b><span data-bind="text: LanguageCultureName"></span></b></li>
    <li>Display Name: <b><span data-bind="text: DisplayName"></span></b></li>
    <li>Culture Code: <b><span data-bind="text: CultureCode"></span></b></li>
    <li>ISO 639x Value: <b><span data-bind="text: ISO639xValue"></span></b></li>
</ul>

  • Next we have a <pre> section which contains the code that changes as per the selected Culture.

<pre>
string fare = “123000.0000”;
decimal parsed = decimal.Parse(fare, CultureInfo.InvariantCulture);
CultureInfo cultureInfo = new CultureInfo(<b><span id=”currentCulture” data-bind=”text: LanguageCultureName”></span></b>);
NumberFormatInfo cultureNFO = (NumberFormatInfo)cultureInfo.NumberFormat.Clone();
// If you don’t want the CurrencySymbol, uncomment the following line
// cultureNFO.CurrencySymbol = string.Empty;
string text = string.Format(cultureNFO, “{0:c}”, parsed);
</pre>

  • Finally we have a span to show the formatted string returned after we have selected the Culture Info

Formatted String: <b><span data-bind="text: $parent.formattedString"></span></b>

Conclusion

The code snippet changes as you select the Culture Info in the dropdown and you can copy paste it directly. I deployed it on a free Azure Website, how? That’s for another day Smile.

Advertisements
Tagged , ,

Fun with @SignalR

This article has grown a little long in the tooth because SignalR has changed significantly since this was written more than a year ago.
I recently co-wrote a new article with Suprotim Agarwal in the DNC Magazine. If you are a .NET Dev I strongly recommend you subscribe to this Free Bi-monthly Magazine. The source code for the article is on Github Repository of DotNetCurry. You can see the sample live here.

Background

For the past several months I have noticed David Fowler, Damien Edwards, Phil Haack and a few other MS Techies I follow on twitter, tweet excitedly about a new framework called SignalR. I didn’t understand the excitement fully and to be honest didn’t try too hard to figure out.

Yesterday Scott Hanselman published this article and re-distributed a link to an article which he wrote end of August, 2011. After going through both, I really wanted to take a closer look at SignalR, and while trying to get his ‘…monkey typing Shakespeare…’ code working I finally had the ‘Ah ha!’ moment.

I just had to come up with this quick and dirty sample to demonstrate a use for SignalR and since I want the bragging rights for it, I am going to throw it up as is without bothering about the niceties of a Nuget package or sample.

UPDATE: I have deployed a working sample of this application at http://apps.apphb.com/funwithsignalr

The Idea

First time I saw Google Wave’s technology demo where they showed multiple people editing/reviewing the document at the same time, it blew me away. I was fascinated by it, but told myself I was too ‘javasciptically challenged’ to design such an Async client side framework.

When my tubelight** finally came on, SignalR was the obvious way to do it. Following is my first rough cut that as of now only syncs content. We’ll get to the fancy colored carets at a later point (hopefully in another article).

**In India one is referred to as a tubelight if something strikes late. Back in the days of non-electronic ballasts for fluorescent lighting, the tubes used to flicker for few seconds before turning on.

Please go through Scott’s articles or SignalR documentation to understand SignalR better. I make no attempts to explain SignalR here (partly because I know precious little and partly it’s such a fantastic framework that you need very little up front to get going).

Head-first into SignalR

To build a scaffolding for SignalR framework you can use plain html with a backend server side SignalR Hub class as Scott demonstrated. But I chose to start off with an ASP.NET MVC 3 project. (Actually my first attempt at ASP.NET MVC 4 using VS 2011 Dev Preview didn’t quite go so well, so I rolled back to the stable releases of ASP.NET MVC 3 on Win 7 using VS 2010).

Setting up a support app as an ASP.NET MVC 3 web project

image

image

I called it ‘FunWithSignalR’ and set it up as an Intranet Application

Adding SignalR to your project using Package Manager Console

image

The package manager console helps you download Nuget packages among other things. If you don’t have it visible you can bring it up from the above menu (in VS 2010)

SignalR is available as a nuget package and all you have to do to include is run the following command in the Package Manager Console

Install-package SignalR

The above command will get all the dependencies you need for SignalR and if your jQuery script files are not up to speed, will get the latest libraries for jQuery too (SignalR client uses jQuery hence the dependency check results in the upgrade). The output will looks something similar to

image

Update jQuery dependencies in Views\Shared\_Layout.cshtml by pointing to the most recently updated jQuery version. As per above image the latest version for me today is jquery-1.6.4.min.js because that’s the one the package manager installed.

Setup the Code First EF Model

We’ll setup a very simple code first model by adding one Entity called BlogPost in our Model folder.

image

Add the DbContext for the BlogPost.

image

Build the solution at this point.

Scaffold the Controller and UI

To use the default scaffold tooling that comes with MVC 3, right click on the Controllers folder and select Add –> Controller.

image

Select the Template, Model and Data Context values as shown above and click Add.

At this point you will have the scaffolding necessary to Add/Edit/Delete BlogPosts.

Adding the ‘Review’ Action

Open the BlogPostController and Copy paste the Get and Post action methods for the Edit action. Change Edit to Review as shown below.

image

Copy the Edit.cshtml and paste it in the View folder. Rename it to Review.cshtml

Update the Index.cshtml such that a ‘Review’ link comes up in the Index

image

Getting SignalR into the game

The Server Side

In your web project create a folder called SignalR (You can call it anything you want, in a real life project this as server side component and could very well reside in a dll of it’s own).

In the SignalR project add a class BlogHub.cs

Add the following code to it


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using SignalR.Hubs;

namespace FunWithSignalR.SignalR
{
[HubName("blogHub")]
public class BlogHub : Hub
{
///
<summary> /// The method called from SignalR client (JS)
/// </summary>
///String Data
///Session ID: Used in this sample to track users
///A boolean value used in the example indicating
/// if incoming value should be appended or overwritten when sent back to
/// other clients
public void Send(string message, string sessnId, bool append)
{
Clients.addMessage(message, sessnId, append);
}
}
}

The Client Side

  • Open Review.cshtml and add the following script references

image

Note: json2.min.js is not packaged with the SignalR nuget. I have packaged it as a part of my code. I got it from Scott’s ‘Shakespeare demo’.

Note 2: /signalr/hubs is dynamically generated at runtime. So don’t worry if it gives a green squidgy right now. It works fine at runtime. Without this reference SignalR client won’t work.

  • Change the Html helper for the Post property from Html.EditorFor(…) to Html.TextAreaFor(…).
  • Add a hidden field to save the session Id in it (this maybe a security hole, need to investigate best practices)

<input id="sessinId" type="hidden" value="@Session.SessionID" />

  • Drop the following script in
<script type="text/javascript">// <![CDATA[
$(function () {
// Proxy created on the fly
var blog = $.connection.blogHub;
// Declare a function on the blog hub so the server can invoke it
blog.addMessage = function (message, sessnId, append) {

var sessId = $('#sessinId').val();

if (sessId != sessnId) {
if (append) {
$('#Post').append(message);
}
else {
$('#Post').val(message);
}
}
};

// Start the connection
$.connection.hub.start();

$("#Post").keyup(function (event) {
// Call the send method on the server

var sessId = $("#sessinId").val();
if (event.keyCode >= 65 && event.keyCode <= 122) {
if (event.shiftKey || (event.keyCode == 32)) {

blog.send(String.fromCharCode(event.keyCode), sessId, true);
}
else {
blog.send(String.fromCharCode(event.keyCode + 32), sessId, true);
}
}
else {
blog.send($("#Post").val(), sessId, false);
}
});
});
// ]]></script>

  • If you see closely this is pretty similar to Scott’s 11 lines of code to get a chat client going.

Changes I have made are:

1. Send message to server on KeyUp event of the Post text area, instead of an explicit button push

2. Send more meta information like the current sessionId and if the keystroke means an append action should take place at the client action of an overwrite action should take place at the client option.

Let it Roll

Run the application and navigate to the BlogPost Index

image

Add a new Post

image

Click on Review

image

Press Ctrl+N to start a new browser instance with the same page. Hit F5 so the session id (the text field next to Save button) changes. Arrange the two browsers side by side.

Type in one Post text area and watch the other one change almost simultaneously

image

As Scott says, Kabooom! brain explodes…..

In Conclusion

To wrap up, we saw how mind numbingly easy it is to use SignalR.

It’s a fantastic abstraction over various techniques available for persistent connections over http. Under the hood it can use websockets or longpolling depending on what’s available.

You can get infinitely creative with it and build fantastic collaborative ASP.NET apps using SignalR backend.

Some day (hopefully) in the near future, I would have overcome my javascript challenges and built a real collaborative editor with all the fancy bells an whistles of Google Docs.

Finally, David Fowler and team, a million thanks for such a fantastic framework. I am loving the ‘just works’ motto Smile. And Scott Hanselman for providing the ‘Aah ha!’ moment, without which I probably would have not given SignalR a look yet.

The Code

The code can be downloaded from here (size 844 KB) (skydrive). It is provided AS IS, with no warranties expressed or implied. You are free to use it without any attribution (but I would love it if you do feed my ego Winking smile).

I have now made the code available on bitbucket Mercurial repository. You can get it from here https://bitbucket.org/sumitmaitra/funwithsignalr

Update

The code in bitbucket now uses Google’s diff-match-patch implementation and is hence Apache licensed now.

Tagged , , , ,

Entity Framework and MS Web Stack of Love – First Steps

Things they didn’t show you at MIX keynotes Winking smile

Okay, so you saw the MIX keynotes and were really really impressed with what MVC, EF 4.1 Code First and Scaffolding could do for you and excitedly sat down to try and get your old lumbering enterprise app transformed using the Web Stack of Love. Couple of steps in and you start stumbling around. Visual Studio throws errors, things stop working and you are scratching your head as to where you went wrong! Well happened to me and I got lucky in finding the solutions quickly with help from the community. Here are the details.

Model First or Database First with EF 4.1

As mentioned above the first thing I tried to do was get my old lumbering enterprise app moved to the new MVC platform. Now when you have an enterprise platform you can’t throw it away with the accumulated data of last 5 years. So the easiest way is to go Database first, reverse engineer the database to generate your data model. Below are the steps you would follow

  • Create an ASP.NET MVC Web Application using the new project template
  • Create a generic Class library project
  • Add ADO.NET Entity Data Model file (edmx) to the class library
  • Generate model from DB Connection by connecting to the database. So far so good, no issues.
  • Now you add reference to your database project to the web project, copy the connection string over from the class library’s app.config to web app’s web.config, and build it. Everything builds fine.
  • You right click on the Controller folder and select Add Controller and the MVC tooling wizard comes up. You select your root entity name and ask it to generate the controller, Visual Studio whirrs for a while and bam! Error!

    —————————
    Microsoft Visual Studio
    —————————
    Unable to retrieve metadata for ‘Your.Data.Entity’. The type ‘Your.Data.Entity’ was not mapped. Check that the type has not been explicitly excluded by using the Ignore method or NotMappedAttribute data annotation. Verify that the type was defined as a class, is not primitive, nested or generic, and does not inherit from EntityObject.
    —————————
    OK  
    —————————

  • So what did you miss. Well EF is all code first so the old style generation of Entities (EF < v4) fail to work. If you read the last line of the error ‘… and does not inherit from EntityObject’ it gives you a hint.
  • What now? Manually edit everything? That would defeat the whole purpose of O-R mapping right? Well solution was provided by Julie Lerman (MS MVP) in her blog here. I’ll summarize here.
  • Go back to EDMX file and open the EDMX designer.
  • Right click and select ‘Add Code Generation Item’.
  • From the ‘Add New Wizard’ select ADO.NET DBContext Generator. You’ll see it gives a Model1.tt (t4 template) name. Change the name if you want to and select Add.

image

  • You will see under in the class library a node gets added with the t4 template. When you expand the node you have the C# (or VB) classes for your entities.
  • Now build and re-try scaffolding the Controller and things will go through smoothly.

Taming the SQL Compact 4.0 for Model First Development

Here is another workaround for people who want to do Model First Development. Since SQL Compact 4.0 was released out of band from Visual Studio and .NET 4.0 releases, somewhere in the tooling chain something broke. As a result, when you try to add a new Connection using Generate Database Wizard you don’t see SQL Compact 4.0. You see up to 3.5 only. So how do you get 4.0 goodness?

Refer to the selected answer from this stackoverflow.com thread

The answer is pretty to the point so I won’t repeat it here.

Trouble with Modernizer.js  (ver 1.7.x only on VMs)

If you run your dev environment on a VM (like VM Ware on Mac), IE9 disables hardware rendering and the modernizer.js that ships by default keeps throwing exception ‘Microsoft JScript runtime error: Unexpected call to method or property access’. This happens for every page and become very irritating quickly.
Solution is to go to www.modernizer.com and download their latest library (2.0.6 at the time of writing this). Remove the 1.7.x reference from your web application and add 2.0.x version. Voila!

 

That’s about it for now. I’ll put down more of my experiences as I go forward with my EF adventures. When I started this article we had only 4.1 now we have 4.2 CTP out Smile. Fast! Very Fast!

Tagged , , , , , , , , , , , ,

How to: Use default ASP.NET Authentication and Authorization Provider Schema in your own Entity Model?

Background

Microsoft has provided a default authentication provider that stores usernames and passwords in a SQL Server Database. The schema and the provider come out of the box and now-a-days if you use and Web application template, Visual studio will generate all code necessary to do forms authentication and registration.

The default database for storing Authentication and Authorization mechanism is called aspnetdb and contains all the tables and stored procedures required.

The Problem

You can choose to keep the default aspnetdb and build your application schema separately and use the provider as needed. This works fine when your own schema elements don’t need to access the roles, user or membership entities that are getting stored in aspnetdb. But we run into trouble if we are building our schema using the Entity Framework and want to use entities from the aspnetdb. Entity Designer can connect to only one database at a time. So how do we keep the out-of-the-box goodness intact, use the Entity Framework and also use the Role/membership entities in our custom entities?

Solution

Microsoft has provided a tool for generating the entire schema in any database you want. The details are available at http://msdn.microsoft.com/en-us/library/ms229862.aspx

To Summarize

1. Open “Visual Studio Command Prompt” from “Visual Studio Tools” shortcut.

2. Type in the following commands

C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>aspnet_regsql –d [YourDataBaseSchemaName] –A all –E –S [SQLSERVER NAME]

The aspnet_regsql tool has a lot of options, details for which are well documented by MS in the above link. Above I’ve used three options

-d : Implies you are specifying a database schema where the scripts will be generated

[YourDataBaseSchemaName] : Replace this with the schema/database name with the one for your application

-A : This implies Add

all : This value implies you want all the tables in your schema. There are some options to get a subset, but I just went for the whole thing

-E : This implies you are asking it to Authenticate using current Windows Authentication for current user.

-S: SQL Server Name. It is usually the machine name or [machine name]\SQLSERVER unless you’ve named it differently yourself.

This script hardly takes a second to execute.

3. Now the authentication infrastructure is in place. Few more steps to go:

  • Change default connection string in your web.config for the provider. By default the connection string is called “ApplicationServices”. Change it such that it connects to your database.
  • Open the Entity Designer, right click on the design surface and select Update Model from Database.
  • Select all the tables (only) and add them to the Entity Design surface.
  • Rename the aspnet_* tables as per your naming conventions. Renaming the entities doesn’t change the table names in the DB so rest assured you are not breaking anything with the default provider.

That’s it. Now you have access to the entities from the providers in your schema, feel free to use them they way you want. The default provider is intact and you get all the Entity Framework goodies for reading from the provider free of custom data layer development cost.

Have Fun!

Tagged , , , , , ,
%d bloggers like this: