Corey Coogan

.Net, C#, ASP.NET MVC, Architecture and Design

Archive for November, 2009

Command Query Responsibility Separation (CQRS)

Posted by coreycoogan on November 18, 2009

CQRS is a relatively new way of architecting systems that is the topic of much discussion on the DDD lists.  The biggest proponents (creators?), Udi Dahan and Greg Young, are constantly answering question, giving suggestions and presenting the architecture at conferences around the world.  It’s fascinating and I really like what I’ve read and watched, but I’ve always had trouble grasping the ideas as a whole, especially Event Sourcing, without something concrete to look at.

UPDATE: As pointed out by Mark Nijhof in the comments, Greg and Udi have slightly different philosophies.  We’re talking about Greg’s flavor here.

The gist of CQRS is that you access your domain model for updating via commands and a separate service from the reads (queries) and reporting.  Reading from your database happens without going through the domain layer and can be performed against a denormalized database by passing simple and complete DTO’s to the UI.  The updates to the domain eventually update the read-only database when the published event messages get picked up and acted upon.

Thanks to Mark Nijhof, I have something more in depth that I can read and also a code base I can examine.  Anyone who is interested in this architecture should read this post now.  It is pretty well written and really helps solidify the essence of what CQRS looks like the problem it is trying to solve.

Posted in Architecture and Design, Domain Driven Design | Tagged: , , , | 2 Comments »

Synching Gmail Contact and Calendar with Yahoo and Outlook

Posted by coreycoogan on November 14, 2009

As a coworker of mine put it, I recently “stepped into the 21st century” by splurging on the Droid the day after its launch. I’ve been intrigued by the smart phone for some time and would have jumped all over the iPhone but the coverage from AT&T really sucks in my neck of the woods. When they started talking about the Droid on Verizon’s network, I got all giddy and couldn’t wait to get one. Not to mention how much fun it could be writing my own mobile apps. I guess it’s time to dust off my Java books and lube up my copy of Eclipse.

This post, however, is less about technical stuff and more about getting what you want where you want it, and that is calendar and contact synchronization. I’m not saying that this is the only way, or the best way, but I dug around for several hours and tried all sorts of free and demo software and this is what ended up working for me with the least amount of pain.

First, some back story on my situation. I’m an avid Yahoo Mail user and have been for about 10 years. I like Yahoo mail with all it’s Ajax goodness and sleek interface. GMail on the other hand, seems clunky. As a coworker of mine put it, “it looks like something that was designed by programmers”. I have a GMail account to use for all the wonders that Google offers, like analytics and other services. Being that the Droid is heavily integrated with Google, the calendar and contacts functionality on the phone depends on the Google Calendar and GMail Contacts. So now I was faced with the problem – how do I get my events, appointments, reminders and contacts from Yahoo to my phone?

NOTE: I’m running Office 2007 on Windows 7 64bit

How I am Synchronizing Yahoo! Contacts and Calendar with Outlook and GMail

  1. First I am doing 2 way synchronization between Yahoo and Outlook for contacts and calendar.  This is very simple using Yahoo’s AutoSync addon for Outlook/Outlook Express.  You can install the bits for this program by first going to Calendar and then clicking the “Sync” link in the top right.  You can also get more info from VersionTracker.  This addon isn’t 100% rock solid and sometimes won’t fire up, but not sure what the circumstances are.  I don’t think it’s officially supported in Windows 7, but it’s been working good enough for now.
  2. Now that I have all my Yahoo contacts and calendar entries in Outlook, it’s time to find something to synchronize Outlook to Gmail.  I went into this thinking this would be a simple task, but let’s just say there’s a lot of crap software out there both for free and for pay.  What I ended up using was the addon from Soocial.com, which a contact management service that helps keep your contacts organized.  They offer tools to sync several providers, but the Yahoo sync is only one-way, which is why I am using AutoSync to handle that.  Their GMail sync tool only works for contacts, which leads me to item 3.
  3. To keep my outlook calendar synchronized with the GMail calendar, I am using Google’s Calendar Sync Tool.  You may be as surprised as I was to find that Google offers a tool to sync the calendar but not contacts.  I think it has something to do with the Apps Synch product that requires an Enterprise license.
    Note: Google does offer a way to sync iTunes contacts with GMail, but that seemed like a whole other can of worms.

At first I had reservations about putting all my contacts on Soocial.com, but I couldn’t find anything sketchy about them in the public domain.  If you have any knowledge about this service, please share.

So what I’ve ended up with is this:

Yahoo -><- AutoSync –><- Outlook –><- Soocial.com -><- Gmail Contacts
GMail Calendar
-><- GMail Calendar Synch –><- Outlook

Now when I add a contact or calendar entry in Outlook or Yahoo, I will see it on my Droid.  Conversely, if I’m on the road and add something in my Droid (Gmail), I’ll see it in Yahoo and Outlook within 90 minutes (configurable).  It not as seamless and I’d like, but it works pretty good for now.  I’ll update the post if things start to get dicey or ifwhen something better comes along.  Based on the number posts and questions on the web regarding this topic, I’m sure this will help at least a couple people trying to mesh into this new fangled era of being constantly connected to the world from your powerful little handset.

Posted in 27554455, Android | Tagged: , , , , , , , , , , | Leave a Comment »

Event Mocking with[out] Rhino Mocks

Posted by coreycoogan on November 11, 2009

One of the common tasks I come across when doing TDD is mocking events.  I’m a big fan of Rhino Mocks and it’s pretty easy to raise an event on a mocked object doing something like this:

_Broker.Raise(x => x.GetData += null, this, EventArgs.Empty);

This is representative of the most typical examples you’ll find on the web and this is all fine and good.  However, sometimes the scenario that you need to test is a little more complicated and this method of raising events on a mock object simply won’t work without too many hassles.

A More Complicated Scenario

A common scenario may be where you are testing something that is subscribing to events that are actually fired by an object a couples levels deep.  For example, you may have an object that sends messages to another object, which is responsible for raising the event.  Hopefully this very simple textual sequence figure will help make things more clear.

Proxy.Execute() -> Broker.HandleMessage() -> Broker.RaiseEvent() -> Gateway.HandleEvent(eventArg)

I want to test that when the Proxy publishes a certain message the Gateway handles the event properly.

Mocking The Old Fashioned Way

My first instinct was to look at how I could accomplish this with Rhino.  After a couple minutes, I realized that this would not be a good way to spend my time.  A better option for me was to mock the old fashioned way.  To do this, I created a MockProxy and MockBroker class that implemented the IProxy and IBroker interfaces.  I can now just write regular C# code to handle how/when to raise those events.  It took only a few minutes to write the code, is intention-revealing and works like a champ.

NOTE: I tried to figure out how I could show some sample code without getting into all the gory details but couldn’t find a simple way, so I’ll just get right to the moral of the story.

When it comes to mocking, follow the KISS principal.  Rhino and other frameworks are there to make our lives easier.  If you are spending time and effort trying to figure out how to mock something in a framework, stop and think about doing it old school.  You’ll save yourself a load of time and your simple solution should be more readable to others.  You can still create a Rhino mock of your old school mock object (assuming you used virtual methods) for the purpose of asserting expectations, which will provide the best of both worlds.

Posted in Alt.Net, Rhino Mocks, TDD | Tagged: , , | 2 Comments »

Blogging with MS Live Writer

Posted by coreycoogan on November 9, 2009

A while ago, Microsoft released some pretty cool tools under the “Live” brand.  There are some pretty cool tools under this label that allow you to work with email/calendar, images and video and synch them to multiple services throughout the web.  The tool I’m blogging about now is Live Writer. I’m writing this post right now using Live Writer and am really enjoying the interface, which is much more fluid than the editor that comes from the browser.

According to the website:

“Writer makes it easy to share your photos and videos on almost any blog service—Windows Live, WordPress, Blogger, LiveJournal, TypePad, and many more.”

Live Writer is a desktop application that supports writing blogs with images, video and more.  I’m using WordPress (WP), which is a pretty awesome platform, and the integration is seamless and the Preview feature gives me a pretty good idea of what it will look like when published.  There’s even the ability to save your drafts to the blog server so you can edit it later from a different location.  In addition, there is a nice Plugin model where you can get and develop plugins to do all sorts of things.

Syntax Highlighting

Since this is a technical blog, the ability to copy/paste code snippets into my blog is very important. WP gives me a special tag for this (sourcecode lang=’csharp’).  When this tag is found, WP will automatically format my code using the SyntaxHighlighter found on Google Code.  I really like this highlighter’s ability to show line numbers, copy/paste functionality and the ability to view the source.  Unfortunately, I haven’t found any plugins that work equally as well for LiveWriter.

I did a little digging and found a simple method to allow me to get my desired syntax highlighting.  First, I found this answer on Superuser.com that shows how to stop LiveWriter from formatting special characters.  Next, I used this technique, in which you simple wrap your “sourcecode” tag in a <pre> and then all is well.  It’s a little bit of a hassle, but I think the trade off is worth it.  It wouldn’t take much to develop a plugin to do this, and there’s examples on the web for how to write one, but I’m content for now to just add the <pre> tag.

//sample code to show syntax highlighting
public void BlogThis(string blogPost)
{
	WordPress.PostBlog(blogPost);
	this.Observers.Notify(blogPost);
}

Posted in Blogging, Uncategorized | Tagged: , , | Leave a Comment »

Castle Windsor Tutorial in Asp.Net MVC

Posted by coreycoogan on November 6, 2009

Castle Windsor is one of the more popular IoC containers in the .NET space today.  Others include StructureMap, NJect, AutoFac, Unity and others.  My top choices are StructureMap and Castle, but I’ve never really used NJect or AutoFac and it’s my opinion that Unity is the weakest of them all and hardly worth mentioning.  I’ll show some of the basics of Castle Windsor – enough to get you setup in your ASP.NET MVC, or any other .NET application. I’ll show you enough to handle 90%+ of the most common IoC needs. Much of my examples come from the S#arp Architecture, which I’m using in my current project.

Castle Windsor Configuration Options

Windsor offers 2 configuration options – .config file or code.  Like many others, I have moved away from trying to do everything in my .config file and do more in code, practicing Convention or Configuration (CoC).  Because the novelty of .config files is so early 2000’s, I’ll focus on configuring Castle using good ‘ole C# and some conventions I follow in my applications.

Common Conventions

Nothing ground breaking here, but I like to keep my controllers as light as possible.  Therefore, I keep my application logic in an application service layer.  My app services have one ore more repositories injected into them where domain objects can be retrieved for performing operations.  My repositories, application services and interfaces all reside in different layers, which in my case is a physical assembly.  Some folks prefer to inject repositories directly into the controller, which works as well, but using services works better for me because I feel I get better separation and it simplifies the controller’s constructor, which is how I handle dependency injection.

So here’s the breakdown of my layers (assemblies/projects):

Application Layer:
Application Services, Application Service Interfaces

Data Layer:
Repository Implementations

Domain Layer (Core):
Repository Interfaces

UI Layer:
Controllers

Configuring Castle to Handle My Conventions

All of my dependency injection is through the object’s constructor.  As long as Windsor can resolve all the dependencies required by the constructors, it will be able to create and resolve the dependent objects as well.  IoC configuration is typically left to the application (MVC, WinForms, WPF, etc.), so you would bootstrap the configuration in some sort of Application Start event, which in the case of ASP.NET is available from the Global.asax.  All the code you’re about to see will exist in a class responsible for the IoC configuration that gets called from my Application_Start event.

First, a sample of a repository class and its interface, then how to automatically register all repositories in one swoop.


//my repository class from the Data assembly
namespace S2sol.Rpo.Data
{
     public class ClassroomRepository : S2sol.Rpo.Core.DataInterfaces.IClassroomRepository
    {
    }
}

//my Repository interface from the Core assembly
namespace S2sol.Rpo.Core.DataInterfaces
{
    public interface IClassroomRepository
    {
    }
}

//this is how I would resolve an IClassroomRepository to its implementation from Castle
IClassroomRepository repo = container.Resolve<IClassroomrepository>();

To make things simple, I’ll use Castle’s AllTypes.Pick() method, which effectively scans the types in an assembly. In my example below, I’m scanning my Data assembly and looking for non-generic interfaces that are the first interface defined on the classes in my Core assembly and register them with the container.

private static void AddRepositoriesTo(IWindsorContainer container)
{
    container.Register(
    AllTypes.Pick()
    .FromAssembly(typeof(UserRepository).Assembly) //get the assembly where this repository lives
    .WithService.FirstNonGenericCoreInterface("S2sol.Rpo.Core") //look for interfaces from this assembly
    );
}

I’m going to want to automatically register all my Application Services as well so they can be injected into my controllers. This syntax is a little simpler because those interfaces and implementations are in the same assembly.

private static void AddApplicationServicesTo(IWindsorContainer container)
{
      container.Register(
        AllTypes.Pick()
        .FromAssembly(typeof(ProfileService).Assembly)
        .WithService.FirstInterface());
}

Now I’ll want to make sure that all my controllers are registered. This done by using the RegisterControllers extension method from the MvcContrib.Castle library.

private static void AddControllersTo(IWindsorContainer container)
{
	container.RegisterControllers(typeof(HomeController).Assembly);
}

Now all that’s left is to show the simple part, and that’s how to register any one-offs that may not fit into your conventions. For example, I have an IValidator interface that I want to resolve to the Validator implementation I’m using in this project.

container.AddComponent<IValidator,Validator>();

It’s as simple as that. Once this has been put in place, I can just continue to develop repositories, application services, controllers and their respective interfaces and never have to remember to register any of them as long as I follow my conventions.

Castle’s Factory Facility

Facilities are how Castle handles extensibility. These are plugins for Castle that can be used for just about anything. Some of the more popular ones support NHibernate, WCF and logging. The one that comes in handy for my needs is the FactorySupportFacility. This facility allows me to configure a factory method in the container and control how objects get resolved.

The RoomParentsOnline MVC application makes use of a custom IPrincipal object that gets injected into my UserSession class, along with an HttpSessionStateBase implementation. The UserSession class is used for interacting with the current user, and by passing it an IPrincipal and HttpSessionStateBase, I have a testable design that I can develop using TDD.

//constructor for the UserSession implementation
public UserSession(IProfileService profileSerivce,
            HttpSessionStateBase session, IPrincipal principal)

The first thing to do is make sure that Castle knows about the Factory Facility that I wish to use. To do this, you can either register the facility in the .config file or in code. I’ll show you how to add it in code. This would be done in your registrar class’s constructor to make sure it’s available right away.

container.AddFacility<FactorySupportFacility>();

Now that Castle knows I’m using the Factory facility, I can tell it how I want to resolve the IPrincipal and HttpSessionStateBase. I also have to tell it how to resolve an IIdentity because of the way my code is accessing it (for testability). In the code below, I am telling Windsor to keep the registered objects available during the scope of a request. I then pass it the Function expression for how to create the object, which is all coming from the HttpContext.

private static void AddSecurityConcernsTo(IWindsorContainer container)
{
	container.Register(Component.For<IIdentity>()
	  .LifeStyle.PerWebRequest
	  .UsingFactoryMethod(() => HttpContext.Current.User.Identity));

	container.Register(Component.For<IPrincipal>()
	  .LifeStyle.PerWebRequest
	  .UsingFactoryMethod(() => HttpContext.Current.User));

	container.Register(Component.For<HttpSessionStateBase>()
		.LifeStyle.PerWebRequest
		.UsingFactoryMethod(() => new HttpSessionStateWrapper(HttpContext.Current.Session)));

}

I’m sure you’ll agree that this code makes it very simple to invert some of those pesky dependencies that come from the core ASP.NET plumbing. This technique is very effective for designing testable classes that need to interact with some of the “ugly stuff”.

The MvcContrib WindsorControllerFactory

Now that we have our Windsor container all configured to resolve our controllers, why not let the MVC framework use that container for creating our controllers. This can be done quite easily using the WindsorControllerFactory from the MvcContrib project. This is an implementation of ASP.NET MVC’s IControllerFactory interface. Using it is simple – just create an instance and give it your container and then register the factory with MVC. This is something that needs to be done during Application_Start.

ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container));

Common Service Locator

The last thing that I’ll mention is the CommonServiceLocator project. If you already have your IoC configured, you might as well make it available to all your code that may need to get object implementations without dependency injection. The CommonServiceLocator makes this easy by adapting all the major IoC containers to work under a common interface with a few key static methods. This is something that should also happen in the Application_Start.

ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(container));

Bringing it all Together

Now I’ll just put everything together for your copy/paste pleasure.

Global.asax

protected void Application_Start()
{
	InitializeServiceLocator();

	//do everything else here
}

/// <summary>
/// Instantiate the container and add all Controllers that derive from
/// WindsorController to the container.  Also associate the Controller
/// with the WindsorContainer ControllerFactory.
/// </summary>
protected virtual void InitializeServiceLocator()
{
	//create the container
	IWindsorContainer container = new WindsorContainer();
	//set the controller factory
	ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container));
	//configure the container
	ComponentRegistrar.AddComponentsTo(container);
	//setup the common service locator
	ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(container));
}

ComponentRegistrar.cs

public class ComponentRegistrar
    {
        public static void AddComponentsTo(IWindsorContainer container)
        {
            container.AddFacility<FactorySupportFacility>();

            AddControllersTo(container);
            AddGenericRepositoriesTo(container);
            AddCustomRepositoriesTo(container);
            AddApplicationServicesTo(container);
            AddOneOffs(container);
            AddSecurityConcernsTo(container);
        }

		//add all my controllers
        private static void AddControllersTo(IWindsorContainer container)
        {
            container.RegisterControllers(typeof(HomeController).Assembly);
        }

		//handle any one off registrations that aren't convention based
        private static void AddOneOffs(IWindsorContainer container)
        {
            container.AddComponent<SharpArch.Core.CommonValidator.IValidator,Validator>("validator");
        }

       //handle registrations for my security classes
        private static void AddSecurityConcernsTo(IWindsorContainer container)
        {
            container.Register(Component.For<IIdentity>()
              .LifeStyle.PerWebRequest
              .UsingFactoryMethod(() => HttpContext.Current.User.Identity));

            container.Register(Component.For<IPrincipal>()
              .LifeStyle.PerWebRequest
              .UsingFactoryMethod(() => HttpContext.Current.User));

            container.Register(Component.For<HttpSessionStateBase>()
                .LifeStyle.PerWebRequest
                .UsingFactoryMethod(() => new HttpSessionStateWrapper(HttpContext.Current.Session)));

        }

		//register my application services
        private static void AddApplicationServicesTo(IWindsorContainer container)
        {
            container.Register(
                AllTypes.Pick()
                .FromAssembly(typeof(ProfileService).Assembly)
                .WithService.FirstInterface());
        }

		//register all custom repositories (not generic)
        private static void AddCustomRepositoriesTo(IWindsorContainer container)
        {
            container.Register(
                AllTypes.Pick()
                .FromAssembly(typeof(UserRepository).Assembly)
                .WithService.FirstNonGenericCoreInterface("S2sol.Rpo.Core"));
        }

		//register all my SharpArch generic repos
        private static void AddGenericRepositoriesTo(IWindsorContainer container)
        {
            container.AddComponent("entityDuplicateChecker",
                typeof(IEntityDuplicateChecker), typeof(EntityDuplicateChecker));
            container.AddComponent("repositoryType",
                typeof(IRepository<>), typeof(Repository<>));
            container.AddComponent("nhibernateRepositoryType",
                typeof(INHibernateRepository<>), typeof(NHibernateRepository<>));
            container.AddComponent("repositoryWithTypedId",
                typeof(IRepositoryWithTypedId<,>), typeof(RepositoryWithTypedId<,>));
            container.AddComponent("nhibernateRepositoryWithTypedId",
                typeof(INHibernateRepositoryWithTypedId<,>), typeof(NHibernateRepositoryWithTypedId<,>));

        }
    }

Conclusion

This post ended up being longer than I originally intended, but hopefully you gleaned some nice little gems here. Castle Windsor is really easy to setup and use and there are many contributions out there that add more great functionality. Sometimes it’s hard to know how to use these types of tools without some concrete examples and I hope to have you shown you some useful ones here.

Posted in ASP.NET, ASP.NET MVC, Alt.Net, Architecture and Design, Design Patterns, IoC, Uncategorized | Tagged: , , , , , , , , , , , , , | 14 Comments »

NServiceBus and Event Driven Architecture (EDA)

Posted by coreycoogan on November 6, 2009

At the October 2009 ALT.NET Northeast Wisconsin user group, Scott Felder put together a great demonstration of NServiceBus and how it actually works. He has since followed up with a well written article on his new blog that talks about Domain Driven Design and when/where NServiceBus, or some other message bus/EDA, might fit in. It’s definitely worth a read.

Posted in Alt.Net, Architecture and Design, SOA | Tagged: , , , , | 1 Comment »

Adding Icons to ValidationSummary and Information Boxes with JQuery

Posted by coreycoogan on November 2, 2009

What’s so special about ValidationSumary and Information Boxes?

When there are errors or important information that you need to call out to your users, it is important to make it unmistakably noticeable. You want to stack the odds in your favor as much as possible that the user will see your call outs and act on them accordingly. Unfortunately, the ValidationSummary in ASP.NET and ASP.NET MVC comes very vanilla. You can change the appearance in MVC by defining the “validation-summary-errors” CSS class that is set to the ValidationSummary by default, but this isn’t always enough. The same goes true for an Information Box, which is what I call a box that contains important information that I want the user to see.

It is very typical for users to gloss over these important messages when they are rendered as text only. Placing the text in a colored box with a brightly colored border can help, but I’ve still experienced frustrated users claiming that registration is broken because they miss the message that says their email has already been used. To combat this, it’s a good practice to use familiar operating system icons for Error, Information, Warning, etc. Most users will recognize familiar icons and have learned to pay attention when they see them.

Here’s an example of what we’re going to achieve:

Error callout box

Info Callout Box

Styling the “Callout Box”

I use the same technique to style all my callout boxes. It’s very simple to do with JQuery, CSS and a few icons. I’ll demonstrate this for both an Error and Info callout.

First, the CSS classes. Each type of callout (error, info, warning) will require 2 classes. One class will style the box that contains the text and the other will be used to hold the applicable icon.

.infobox
{
    border: solid 1px #228ef1;
    padding: 5px 8px 5px 8px;
    text-align:left;
    vertical-align:middle;
    background-color:#F1E7D1;
}

.infoimage
{
   padding: 5px 15px 5px 15px;
    background:#F1E7D1 url(/images/icons/info-24x24.png) no-repeat;
    background-position:left center;
}

.errorbox
{
    border: solid 1px red;
    padding: 5px 8px 5px 8px;
    text-align:left;
    vertical-align:middle;
    background-color:#F1E7D1;
}

.errorimage
{
   padding: 5px 15px 5px 15px;
    background:#F1E7D1 url(/images/icons/err-24x24.png) no-repeat;
    background-position:left center;
    vertical-align:middle;
    display:inline-block;
    height:100%;
}

For my error callouts, I want to add one more class. This will handle the heading of my errors, which typically reads something like “Please fix the following errors”.

.errorhead
{
    color:#CC0000;
    font-weight:bold;
    font-size:15px;
    padding-left:18px;
}

Using JQuery to Construct the Callout Box

The HTML used to put the icon in the callout box requires nested DIV or SPAN elements. I don’t want to depend on my memory to always add the nested elements each time I want a callout, I want to simply write something like this:

<div id="CustomSearchSelect" class="infobox">
            <strong>Can't Find Your School?</strong> Try a <a id="CustomSearchLink" href="#">Custom Search</a>.
</div>

<div class='errorbox'>
This action is not allowed!
</div>

That’s where JQuery is able to help us. By using the prepend function, we can have the appropriate icon automatically injected into our callout box. We do this by adding the following to our JQuery ready function in our Master Page.

$(document).ready(function() {
$(".infobox").prepend("<span class='infoimage'>&nbsp;</span>");
$(".errorbox").prepend("<span class='errorimage'><span class='errorhead'>Looks like we have a small problem...</span></span>");
});

Pretty simple, right? Here’s what’s happening here. The script is finding the elements styled with the infobox and errorbox class and sticking in a SPAN element styled with the corresponding icon class. The errorbox gets the additional heading added here as well. You could do the same thing for Warn, Question or any other conventions you wish to follow.

Styling the ValidationSummary

The ValidationSummary requires a little bit of extra effort. This is because I’m using the xVal 1.0 and a ValidationSummary for client-side error handling as described in my last blog post. The only thing I need to do is define the HTML for my ValidationSummary, but hide it unless I have Model Errors in my MVC application. This is done by wrapping my ValidationSummary in a div styled with the errorbox class like so.

<% string display = ViewData.ModelState.IsValid ? "none" : "block"; %>
<div class="errorbox" id="validationSummary" style="display:<%=display%>">
    <%= Html.ValidationSummary() %>
</div>

Finding the Icons

I found some pretty nice icons on various free icon websites. It took a bit of time to run them all down, so I’m including them here for you in a zip file.

Icon Zip File

Posted in ASP.NET, ASP.NET MVC, CSS, JQuery, UI | Tagged: , , , , | 1 Comment »