Wednesday, May 27, 2009

 

Domain Driven Design – Quickly

Lately I’ve been wanting to read Domain Driven Design book by Eric Evans but then I found Domain Driven Design Step by Step by InfoQ and just in the foreword it says that I must read DDDQuickly also by InfoQ before proceeding, so I downloaded it (PDF)and started reading a few chapters.

I have now stopped reading the book mainly because it got to the point where I thought I needed to see a concrete example of it’s implementation in C#/.NET which I couldn’t find and also because I have found another great read.

Below are some of the notes that I think are the key takeaways from the read so far, I’m sharing them here thinking they might be useful to someone with a disclaimer that they are my notes and I make no warranties for the accuracy, if you are serious about DDD than start reading the book.

Domain - knowledge of the the domain is important before building software, e.g. for banking. Bankers know better about the rules that anyone else.

Model - Is the internal representation of the domain, we must communicate this upfront to all the stakeholders in a software design, the domain experts, domain analysts and off course developers.

Ubiquitous Language - when domain experts and developers talk they often use some keywords use to describe the system, these keywords make up the domain that is used in UML diagram and Documents explaining those diagrams and ultimately in Classes and Variable names in the code.

Analysis model - a model created by domain experts while not taking into account the software used to code therefore make matter worst at software design time, where developers have to make few decisions on their own. The idea is to choose a model that can be appropriately represented in software.

The key is to involve developers at Domain Model design stage with Domain experts and analysts to let them get the first-hand knowledge of the domain rather than having to understand it with the help of diagrams and documents.

Entities - entities should be unique and defined with a ID, not everything should be Entity but it can be Value Object

Value Object - are unchangeable objects with no unique IDs and created using Constructor, their values cannot be and must not be changed, if new value is needed, simply create another Value object.

Labels: ,


Thursday, May 14, 2009

 

VS 2010 Beta 1 and Functional UI Testing

I just watched a video over at Channel9 which explains how to leverage some of the UI Testing capabilities that are going to be introduced with VS 2010 beta 1 expected next week.

Visual Studio had testing capabilities for C# code for a long but now I’m glad to see for the first time an integrated UI testing built right into VS 2010 IDE. In particular I like the option to store the tests in the database and be able to run them automatically.

See it for yourself, there is also a Mix09 video here

Labels: , ,


Wednesday, April 15, 2009

 

Return JSON objects the right way

Today I experienced a weird behavior when I was passing JSON string back to a jQuery call using an Ajax-enabled WCF Service.

My code looked something like this.

[OperationContract, WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/GetJson")]
public string GetJson()
{
    return new JavaScriptSerializer().Serialize(MyCustomObject)
}

The problem with above code is that the string returned is escaped and enclosed with inverted commas that for some reason was not handled properly using jQuery that looked like this.


“[{\"Id\":1,\"SomeKey\":\"SomeMoreText\"}]”


Not sure what I was missing and while there is a JsonResult action in ASP.NET MVC with a .svc there’s nothing that I could use (or may be there is).


To fix it I changed the method like this.



[OperationContract, WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/GetJson")]
public System.IO.Stream GetJson()
{
   byte[] resultBytes = System.Text.Encoding.UTF8.GetBytes(new JavaScriptSerializer().Serialize(MyCustomObject));
   
   WebOperationContext.Current.OutgoingResponse.ContentType = "application/json";
 
   return new MemoryStream(resultBytes); 
}
 

Here’s how Json is returned.


[{"Id":1,"SomeKey":"SomeMoreText"}]

Labels: ,


Sunday, April 12, 2009

 

Don’t use UriTemplate = "/MethodName/Param1/{Param1}/Param2/{JsonObject} for Json input with WCF Service

When building Ajax-enabled WCF service that expect a Json object as input then the following would not work

[OperationContract, WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/Methodname/jsonvariable/{jsonvariable}/param2/{param2}")]
public void MethodName(string jsonvariable, string param2)
{
 
}

Where jsonvariable is a json object passed through jQuery (or ASP.NET Ajax) to a WCF service that looks like this


[{"Name":"za","Email":zubairdotnet@hotmail.com}]


After spending a while I figured out that the following UriTemplate should be used instead


 



[OperationContract, WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/Methodname/?jsonvariable={jsonvariable}&param2={param2}")]
public void MethodName(string jsonvariable, string param2)
{
 
}

Labels: , ,


Thursday, December 11, 2008

 

DataTable.SelectRows(n)

Doing a DataTable.Select() in ADO.NET is like using a Where clause in T-SQL, but you'd have noticed that Data table lacks a way to retrieve only specific number of rows. Well this can be easy to work around using a Top N clause in T-SQL but can be tricky in case when the data is read from different sources like XML files, Web Services etc.

Steven Smith shows a little code-snippet that can be used to work around this, so I decided to use that.

I went a step ahead and added the method to my Extension methods library as below.

public static DataTable SelectRows(this DataTable dataTable, int rowCount)
{
    try
    {
        DataTable myTable = dataTable.Clone(); 
        DataRow[] myRows = dataTable.Select();
        for (int i = 0; i < rowCount; i++)
        {
            if (i < myRows.Length)
            {
                myTable.ImportRow(myRows[i]);
                myTable.AcceptChanges();
            }
        }
 
        return myTable;
 
    }
    catch (Exception)
    {
        return new DataTable();
    }
}

So for example it can be used as follows.



GridView.DataSource = MyDataTable.SelectRows(5);
GridView.DataBind();

Labels: , ,


Thursday, November 27, 2008

 

ASP.NET Chart Control

I just downloaded and installed ASP.NET Chart Controls that ScottGu just announced.

I'm looking at the sample documentation and it looks very detailed because one of the problems I had with the Telerik and ComponentOne Chart controls that I have used in the past is the poor documentation, but Microsoft ASP.NET Charts docs seem to go a step further and explain every nitty-gritty of the charts along with C# and VB.NET source code, I'm looking forward to try them soon.

Labels: ,


Tuesday, November 25, 2008

 

Using CustomValidator to compare Time Values

ASP.NET ships with many client-side validation controls out of the box, one of them is the Custom Validator control. In client input scenario if you need to compare two date values you can use a CompareValidator and set its Type property to Date, for example check this link. However anytime you need to compare two Time values then there is no support for this in any validation controls.This is how Telerik's TimePicker control looks like.

 

ScreenHunter_02 Nov. 25 12.57

Fortunately comparing the two values is easy using the CustomValidator control and a little bit of javascript. The CustomValidator control has a ClientValidationFunction property that we can use to trigger a javascript function and using the following function we can can compare two time values.

<script type="text/javascript">
    function compareTime(sender, args) {
        var start = document.getElementById("<%=rdpStarttime.ClientID %>");
        var end = document.getElementById("<%=rdpEndtime.ClientID %>");
        var starttime = new Date(0, 0, 0, start.value.substring(11, 13), start.value.substring(14, 16));
        var endtime = new Date(0, 0, 0, end.value.substring(11, 13), end.value.substring(14, 16));
        args.IsValid = (endtime >= starttime);
    }
</script>


<asp:CustomValidator ID="CustomValidator1" runat="server" ErrorMessage="End time should be greater than Start" ClientValidationFunction="compareTime" ControlToValidate="rdpEndtime"></asp:CustomValidator>
 
 

Here's how it looks like.


 ScreenHunter_03 Nov. 25 12.16

Labels: , ,


Sunday, November 23, 2008

 

C# Extension methods library

Extension methods are a quick way to extend the types available in the CLR such as string or object and add your own methods without having to re-compile your application. If you are not familiar with Extension methods then check out ScottGu's post.

A while back I brought back an old C# class that had a collection of static 'helper methods' that we used to use back in .NET 1.1 days and decided to port it to .NET 2.0 as Extension methods.

Fortunately doing that was too simple, in fact it was just a matter of adding a this keyword to a method parameter and I had a strongly typed Extension methods class ready.

While there are dozens of Extension method libraries available at CodePlex.com but I decided to stick to my own library for now that is available for download - Extensions.cs or get the code below.

using System;
using System.Web;
using System.Web.SessionState;
using System.Collections;
using System.Text.RegularExpressions;
namespace Extensions
{
    /// <summary>
    /// 
    /// </summary>
    public static class Extensions
    {
        /// <summary>
        /// Check for Positive Integers with zero inclusive  
        /// </summary>
        /// <param name="strNumber"></param>
        /// <returns></returns>
        public static bool IsWholeNumber(this string strNumber)
        {
            if (strNumber == "")
                return false;
 
            Regex objNotWholePattern = new Regex("[^0-9]");
            return !objNotWholePattern.IsMatch(strNumber);
        }
 
        /// <summary>
        /// Check if the string is Double  
        /// </summary>
        /// <param name="strNumber"></param>
        /// <returns></returns>
        public static bool IsDouble(this string strNumber)
        {
            if (strNumber == "")
                return false;
 
            try
            {
                Convert.ToDouble(strNumber);
                
            }
            catch (Exception)
            {
 
                return false;
            }
 
            return true;
 
        }
 
        /// <summary>
        ///Function to Check for AlphaNumeric. 
        /// </summary>
        /// <param name="strToCheck"> String to check for alphanumeric</param>
        /// <returns>True if it is Alphanumeric</returns>
        public static bool IsAlphaNumeric(this string strToCheck)
        {
            bool valid = true;
 
            if (strToCheck == "")
                return false;
 
            Regex objAlphaNumericPattern = new Regex("[^a-zA-Z0-9]");
 
            valid = !objAlphaNumericPattern.IsMatch(strToCheck);
            return valid;
        }
 
        /// <summary>
        ///Function to Check for valid alphanumeric input with space chars also
        /// </summary>
        /// <param name="strToCheck"> String to check for alphanumeric</param>
        /// <returns>True if it is Alphanumeric</returns>
        public static bool IsValidAlphaNumericWithSpace(this string strToCheck)
        {
            bool valid = true;
 
            if (strToCheck == "")
                return false;
 
            Regex objAlphaNumericPattern = new Regex("[^a-zA-Z0-9\\s]");
 
            valid = !objAlphaNumericPattern.IsMatch(strToCheck);
            return valid;
        }
 
        /// <summary>
        /// Check for valid alphabet input with space chars also
        /// </summary>
        /// <param name="strToCheck"> String to check for alphanumeric</param>
        /// <returns>True if it is Alphanumeric</returns>
        public static bool IsValidAlphabetWithSpace(this string strToCheck)
        {
            bool valid = true;
 
            if (strToCheck == "")
                return false;
 
            Regex objAlphaNumericPattern = new Regex("[^a-zA-Z\\s]");
 
            valid = !objAlphaNumericPattern.IsMatch(strToCheck);
            return valid;
        }
 
        /// <summary>
        /// Check for valid alphabet input with space chars also
        /// </summary>
        /// <param name="strToCheck"> String to check for alphanumeric</param>
        /// <returns>True if it is Alphanumeric</returns>
        public static bool IsValidAlphabetWithHyphen(this string strToCheck)
        {
            bool valid = true;
 
            if (strToCheck == "")
                return false;
 
            Regex objAlphaNumericPattern = new Regex("[^a-zA-Z\\-]");
 
            valid = !objAlphaNumericPattern.IsMatch(strToCheck);
            return valid;
        }
 
        /// <summary>
        ///  Check for Alphabets.
        /// </summary>
        /// <param name="strToCheck">Input string to check for validity</param>
        /// <returns>True if valid alphabetic string, False otherwise</returns>
        public static bool IsAlpha(this string strToCheck)
        {
            bool valid = true;
 
            if (strToCheck == "")
                return false;
 
            Regex objAlphaPattern = new Regex("[^a-zA-Z]");
 
            valid = !objAlphaPattern.IsMatch(strToCheck);
            return valid;
        }
        
        /// <summary>
        /// Check whether the string is valid number or not
        /// </summary>
        /// <param name="strNumber">Number to check for </param>
        /// <returns>True if valid number, False otherwise</returns>
        public static bool IsNumber(this string strNumber)
        {
            try
            {
                Convert.ToDouble(strNumber);
                return true;
            }
            catch
            {
                return false;
            }
        }
 
        /// <summary>
        /// 
        /// </summary>
        /// <param name="strInteger"></param>
        /// <returns></returns>
        public static bool IsInteger(this string strInteger)
        {
            try
            {
                Convert.ToInt32(strInteger);
                return true;
            }
            catch
            {
                return false;
            }
        }
 
        /// <summary>
        /// 
        /// </summary>
        /// <param name="strDateTime"></param>
        /// <returns></returns>
        public static bool IsDateTime(this string strDateTime)
        {
            try
            {
                Convert.ToDateTime(strDateTime);
                return true;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// Function to validate given string for HTML Injection
        /// </summary>
        /// <param name="strBuff">String to be validated</param>
        /// <returns>Boolean value indicating if given input string passes HTML Injection validation</returns>
        public static bool IsValidHTMLInjection(this string strBuff)
        {
            return (!Regex.IsMatch(HttpUtility.HtmlDecode(strBuff), "<(.|\n)+?>"));
        }
 
        /// <summary>
        /// Checks whether a valid Email address was input
        /// </summary>
        /// <param name="inputEmail">Email address to validate</param>
        /// <returns>True if valid, False otherwise</returns>
        public static bool isEmail(this string inputEmail)
        {
 
            if (inputEmail != null && inputEmail != "")
            {
                string strRegex = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +
                    @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
                    @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
                Regex re = new Regex(strRegex);
                if (re.IsMatch(inputEmail))
                    return (true);
                else
                    return (false);
            }
            else
                return (false);
        }
 
        /// <summary>
        /// Converts a valid string to integer
        /// </summary>
        /// <param name="StringToConvert"></param>
        /// <returns></returns>
        public static int ToInteger(this string StringToConvert)
        {
            return Convert.ToInt32(StringToConvert);
        }
 
        /// <summary>
        /// Converts an Object to it's integer value
        /// </summary>
        /// <param name="ObjectToConvert"></param>
        /// <returns></returns>
        public static int ToInteger(this object ObjectToConvert)
        {
            try
            {
                return Convert.ToInt32(ObjectToConvert.ToString());
            }
            catch
            {
                throw new Exception("Object cannot be converted to Integer");
            }
        }
 
        /// <summary>
        /// Converts a valid string to double
        /// </summary>
        /// <param name="StringToConvert"></param>
        /// <returns></returns>
        public static double ToDouble(this string StringToConvert)
        {
            return Convert.ToDouble(StringToConvert);
        }
 
        /// <summary>
        /// Converts an Object to it's double value
        /// </summary>
        /// <param name="ObjectToConvert"></param>
        /// <returns></returns>
        public static double ToDouble(this object ObjectToConvert)
        {
            try
            {
                return Convert.ToDouble(ObjectToConvert.ToString());
            }
            catch
            {
                throw new Exception("Object cannot be converted to double");
            }
        }
 
        /// <summary>
        /// Converts a string to a Sentence case
        /// </summary>
        /// <param name="String"></param>
        /// <returns></returns>
        public static string ToSentence(this string String)
        {
            if (String.Length > 0)
                return String.Substring(0, 1).ToUpper();
 
            return "";
        }
 
        public static bool ToBool(this object Object)
        {
            try
            {
                return Convert.ToBoolean(Object.ToString());
            }
            catch {
                throw new Exception("Object cannot be converted to Boolean");
            }
 
        }
 
        public static DateTime ToDateTime(this string String)
        {
            try
            {
                return Convert.ToDateTime(String);
            }
            catch (Exception ex)
            {
                throw new Exception("Object cannot be converted to DateTime. Object: " + String);
            }
 
        }
    }
}


ScreenHunter_01 Nov. 23 14.13

Labels: , , , ,


Monday, November 03, 2008

 

Common Solutions for T-SQL Problems

Here's a page that has few useful T-SQL queries that might come in handy during those days.

http://code.msdn.microsoft.com/SQLExamples

While some of them you may know already, here' re my favorites.

Create a Comma Delimited List

Control Return Results by Range

Delete All Data From All User Tables In A Database

Exploring Recursive Common Table Expressions (CTE)

Find and/or Delete Duplicate Rows in a Table

Labels: ,


Tuesday, October 28, 2008

 

Introducing "Azure Services Platform"

Just came to know that Microsoft has released Azure - Cloud computing platform at PDC 2008

What is Azure?

well..here's an excerpt from the website.

The Azure™ Services Platform (Azure) is an internet-scale cloud services platform hosted in Microsoft data centers, which provides an operating system and a set of developer services that can be used individually or together. Azure’s flexible and interoperable platform can be used to build new applications to run from the cloud or enhance existing applications with cloud-based capabilities. Its open architecture gives developers the choice to build web applications, applications running on connected devices, PCs, servers, or hybrid solutions offering the best of online and on-premises.

Download the SDK, sign up for using the service and other resources check out here

Update - Get involved in .NET Services technical discussion here

Labels: , , , , ,


Monday, September 29, 2008

 

jQuery now official in VS 2008

Today Microsoft announced that they have partnered with the jQuery team and from now on it will be fully supported in the VS 2008 SP1, which is a great new by the way. We've been using jQuery in all our projects extensively and are looking forward to the built in intellisense-annotated version of jQuery as ScottGu announces

http://weblogs.asp.net/scottgu/archive/2008/09/28/jquery-and-microsoft.aspx


Tuesday, September 16, 2008

 

"Stackoverflow.com" launched

Go check it out

Jeff Atwood and Joel Spolsky have been working on StackOverflow.com for a while and now it's finally a public beta, here's an excerpt from the site.

Stack Overflow is a collaboratively edited question and answer site for programmers — regardless of platform or language. Jump in and share your software engineering expertise! No registration or account required.

So far I had a wonderful experience using the site and it turns out to be a easily navigable, one-stop-shop for answering all programming questions.

Labels: ,


Thursday, September 11, 2008

 

dotTrace not working with VS 2008 Web Applications

This morning I downloaded the latest build of dotTrace to profile my web application running under ASP.NET Development Server. I had a bit of problem specifying the correct web application path and I was getting this message.

dotTraceDialog 

I Google'd it a bit and found two guys having the same issue and offered suggestion that sadly didn't work.

It's was time to use IIS, since all my local web applications connect to a remote database server and I use the built-in web server for development, the web application gave a annoying 'Cannot connect to remote SQL Server' bug when run in IIS, I installed dotTrace on the remote server but it always showed 'Connecting' status, without further delay I copied the database to my local SQL Server and ran dotTrace again.

I got the same status, I google'd again and found this thread at the dotTrace forums and did all the settings suggested in the thread, but they didn't work either.

After 2-1/2 hours of trying I finally gave up and now looking to download ANTS Profiler.Hope it works.

Labels: , , ,


Thursday, August 21, 2008

 

Red Gate Acquires .NET Reflector

While going through my RSS feeds I came across the above news item. I use Reflector all the time and just wish it stays free.

An agreement between Red Gate and Lutz Roeder will place future development of .NET Reflector, the popular class browser for .NET developers, in the hands of Red Gate. Red Gate is maintaining a free version of the software for downloading at http://reflector.red-gate.com.

Get the full news from http://dotnet.sys-con.com/node/649584


Tuesday, August 12, 2008

 

DevExpress' over 60 Controls - Free

DevExpress is giving away royalty-free ASP.NET and Winforms controls so go get them from devexpress.com


 

Visual Studio 2008 and .NET Framework 3.5 SP1 'Released'

This is a big and the most anticipated update to the .NET Framework and Visual Studio 2008 as it contains bunch of new stuff and improvements most notably the ASP.NET AJAX Improvements, ASP.NET Dynamic Data, ASP.NET MVC Preview 3 drop and SQL Server 2008 support.

Grab it here or if you prefer here's the iso format (831 mb).

Update - Oh by the way, if you want to know the improvements and fixes that SP1 brings to VS 2008 and .NET Framework 3.5 here's more


Sunday, August 10, 2008

 

New Tips and Tricks blog

MSDN Team has just launched a new blog for ASP.NET, IIS and VS Web Developer tips and tricks, here's the link http://blogs.msdn.com/webdevelopertips/default.aspx and here's the link to RSS


Thursday, August 07, 2008

 

Empty Design View in Visual Studio 2008 for User controls

Just a tip, if you are facing this issue, there's a fix for it

Though I didn't have any style tags in my User control but I'm using Ajax Validator Callouts in my application that insert style information into the head tag at runtime so I moved the following at the end of my user control markup and it worked.

<head id="Head1" runat="server"></head>


Tuesday, August 05, 2008

 

Error ''This collection already contains an address with scheme http. There can be at most one address per scheme in this collection."' when deploying AJAX-enabled WCF Services

This error bugged for me a while before I found out not one but two solutions.

I prefer the first approach because I use baseAddresses[0] in the Custom Host Factory and that it doesn't require me to have two web.config files as in the 2nd approach.


Wednesday, July 02, 2008

 

XHTML Conformance and ASP.NET 2.0

Recently one of the UI developers on my team was struggling with having the Name attribute on the HTML Form element and needed a fix for this. In .NET 2.0 the fix is so trivial that in fact I forgot what I did in a similar project until I Google'd and found this switch from Scott Gu's this post.

<xhtmlConformance mode="Strict" />

This reminded me that back in the ol' ASP.NET 1.1 days the hacks that we used to do to get this working, including adding Response Filters and inherit from classes that strip off the non-XHTML complaint markup before the page is rendered, off course at a cost of the performance.

None of these solutions proved to be very useful and often we had to make this compromise and leave non-complaint markup on our pages.

I'm glad that the old .NET 1.1 days are finally over.

Labels: ,


Tuesday, July 01, 2008

 

Database Schema Comparison Utility

Recently I needed a tool to compare two databases, I know that there is a commercial product called SQLCompare from RedGate but there is also a free tool over at Codeproject titled Database Schema Comparison Utility that did the job for me because I didn't need anything beyond basic schema comparison like Automation or Script generation etc. Here's the screenshot of the tool.

 

While this tool is useful, I noticed that there was bit of a problem with the resulting pane that doesn't resize when the Form is maximized and if you make some changes in your database and Compare Databases again then the old items are not cleared before the results are added. I changed this in the source code and made it available for download here and the demo project is available here.

Update - There is another tool SQLDBDiff that appears to have more features, I haven't tried this one though.

Labels: ,


Sunday, June 29, 2008

 

What is 'Done' ?

If you are interested in Scrum methodology, Scott Hanselman sits and talks with the co-creator and famous agile advocate Ken Schwaber in his interesting podcast series.

Download the full show in different formats from http://www.hanselminutes.com/default.aspx?showID=137

Labels: , ,


Wednesday, June 25, 2008

 

ASP.NET ListView WebControl

.NET Framework 3.0 introduces yet another new data-binding webcontrol name ListView.

In March 2008 issue of MSDN magazine, Fritz Onion describes the benefits of using ListView over it's predecessors like GridView and DataGrid.

Read the full article in MSDN Magazine.

Labels: , , , ,


 

asp.NetPro Magazine

I was reading Bilal Haider's blog where he put a link to download asp.NetPro Magazine, while apparently their website doesn't give a link to download the issues, I tweaked the Url a bit to download some of their old issues to read in my free time.

Follow these links

http://www.aspnetpro.com/PDF/Issues/aspJUNE2008.pdf

http://www.aspnetpro.com/PDF/Issues/aspMay2008.pdf

http://www.aspnetpro.com/PDF/Issues/aspApr2008.pdf

http://www.aspnetpro.com/PDF/Issues/aspMar2008.pdf

Labels: , , ,


Thursday, June 05, 2008

 

What is Cloud Computing?

The author tries to define it here

Labels: , ,


This page is powered by Blogger. Isn't yours?