Thursday, December 31, 2009

jQuery DocumentReady.js – A Best Practice?




I recently noticed some developers creating a DocumentReady.js file and keeping all their document.ready stuff inside of it. I like this practice. I think it’s clean, but I can see how it could get out of hand. Especially if you start adding ALL of your document.ready stuff in there even though it doesn’t pertain to the majority of your pages.

I imagine you’d like to see some examples of things I have in my DocumentReady.js file. Well, I like rounded corners and I found a pretty sweet corners plugin for jQuery, which was the first thing I put in my DocumentReady.js file and it started out looking like this:

    $(document).ready(function() {
$(
'.rounded').corners();
});

So this code says for everything with a rounded class, add the corners. Simple and I have full control and access to it on all of my pages. For more information about jquery.corners, see jquery plugins and jquery.corners demo.


Then I found myself setting the focus on all my forms on each individual page and I thought…this isn’t going to work! I hate all this redundant code and I don’t like it all over the place. I think I’ll add it to my DocumentReady.js file. So I did and it looked something like this:

    $(document).ready(function() {
$(
'.rounded').corners();

var inp = $('.input-validation-error:first').get(0);
if (!inp) var inp = $('input:first').get(0);
if (inp) inp.focus();
});

Okay, so what this says is if there is any items with the input-validation-error class then get the first one. The reason for this is that if there is an error, I want to set the focus to the error and not the first item in the form. So, if there isn’t an error, then I set inp to the first input on the page and then I check if it exists and then I set the focus. The reason I had to add the second check is because this code runs on all my pages and not ALL of them have inputs, so instead of throwing a JavaScript error, I handle it. Obviously if you’re building a basic Web site, you’re not going to want to put this in your DocumentReady.js. The reason I’m doing it is because my project is an application and almost all the screens have form elements.


I also started using a Bootstrapper.js and only reference it on my main template. In the bootstrapper, I have this code:

function IncludeJavaScript(jsFile)
{
document.write(
'<script type="text/javascript" src="'
+ jsFile + '"></script>');
}

IncludeJavaScript(
'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js');
IncludeJavaScript(
'/_j/jquery.corners.min.js');
IncludeJavaScript(
'/_j/DocumentReady.js');

I don’t remember exactly where I first saw this, but I’m pretty sure it was either on the CodeCampServer project or in the ASP.NET MVC in Action sample code download.


So there you have it. Is it a best practice? I’m not sure yet because I just started doing it in the last couple projects, but so far I really like it. What do you think?


As always, please comment if you see anywhere that I could improve or you just have a comment. Thanks for reading!

kick it on DotNetKicks.com

Wife’s Site – Post Launch




Mostly everything went smooth today. There were a couple of things I had to go in and fix and get discountasp.net to setup. Primarily the RSA keypair so I could encrypt the web.config settings.

I also had to setup a configSection for flickrNet and point the cacheLocation to a folder on the server. Apparently it defaults to the local appdata under a FlickrNet folder for the current user. Well obviously on the server it doesn’t have access to do such a thing so you have to specify the cache folder. It was a simple fix, just unexpected. Once corrected, it looked like this:

<configSections>
<!—OTHER SECTIONS & SECTION GROUPS HERE—>
<
section name="flickrNet" type="FlickrNet.FlickrConfigurationManager,FlickrNet"/>
</
configSections>



<flickrNet cacheLocation="e:\\myflickrcachepath"/>
 

We were also monitoring the Google Analytics and noticed that her /portfolio URL was still being hit quite a bit and the new site redirects to a 404 error page, which I have not formatted yet…just need to apply the style. We didn’t want to lose the traffic, so I thought…hey this is an easy fix with a new route! So here it is:

 routes.MapRoute(
"OldPortfolio",
"portfolio",
new {Controller="Portfolio", action="Index", name="families"});

Basically this says when you see /portfolio, go to the most popular gallery. Done! In webform ASP.NET, I would’ve either created a redirect page or setup a virtual directory that just redirects…I like this way much more…all in one place!


What else…I went through and added the title to my top navigation. Since I’m new to the RouteLink, I just forgot to add the title attribute. I did that and here’s a sample of one:

<%=Html.RouteLink("families", "Portfolio", new { name = "families" }, new { title = "families" })%>

On the top navigation, I also ended up opening a new window for the “share on facebook”. It appears to me that their UI was designed to be a pop-up and the flow wasn’t easy to me because you couldn’t simply hit back to get back to our site. I know it’s not the best practice for accessibility, but it was really annoying. Hopefully whoever is annoyed by it will forgive me.


Oh, I had an error on the contact page, which was caused by me not passing the model back into the view from my Success ViewResult on the SmartController. I ended up just creating a new SuccessWithPhotos<TModel> that returns a ViewResult like this:

protected ViewResult SuccessWithPhotos<TModel>(TModel viewModel, Enumeration photoViewType)
where TModel : PhotoView
{
Success();
return ViewWithPhotos(viewModel, photoViewType);
}

Whereas before, I was just returning a View(). If you’re curious what the ViewWithPhotos looks like, here it is:

        protected ViewResult ViewWithPhotos<TModel>(TModel viewModel, Enumeration photoViewType)
where TModel : PhotoView
{
viewModel.Photos = _photoRepository.GetPhotosFor(photoViewType);
return View(viewModel);
}

Again, if curious about Success, it is a protected method on the SmartController, which SmartPhotoController inherits from and this is all it does:

protected void Success()
{
ViewData[
"success"] = "";
}

I like it simple! If you’re wondering why I just set an empty ViewData, the reason is that it was the easiest way for me to control when to display a success message. Let me show you…I created an extension for the HtmlHelper called DivSuccessMessage and it looks like so:

public static string DivSuccessMessage(this HtmlHelper html, string successMessage)
{
if (html.ViewData.ModelState.IsValid && html.ViewData["success"] != null)
return "<div class=\"success-message rounded\">" + successMessage + "</div>";

return "";
}

On my contact view, I just have this:

<%=Html.DivSuccessMessage("You have successfully contacted Amy Schilling Photography.") %>

It was a really simple way to show a message without a lot of work. If there is a better way, PLEASE let me know! Anyhow, I think the contact form was probably my biggest mistake and I should’ve just finished out with my tests and I would’ve never had that problem. I didn’t though so I had the issue…live & learn! Alright, so carrying on…


I ended up having an issue with IE7 apparently. It was pointed out by an awesome friend of mine and I think I have that fixed, it was just a float issue I think…I’m actually still waiting to hear back from her to let me know if it’s fixed.


I found another issue with the email function when you sign up for the newsletter. So I started investigating it further and it turned out to be an issue with my StructureMap configuration. Once again if I had written the tests before hand, I probably wouldn’t have this issue. Oh well, I came up with a solution that I’m okay with until one of the StructureMap geniuses is able to help me out. Here’s my helper solution fix:

public static IMailingListSubscriber GetSubscriberWith(IMailNotification notification)
{
return new MailingListSubscriberWithNotifier(DependencyRegistrar.Resolve<IMailingListSubscriber>(), DependencyRegistrar.With<IMailNotification, INotificationService>(notification));
}

So I couldn’t get StructureMap to create that exact statement above for me without making it look crazy confusing and hard to read, so I went this simpler route. Since I made this little helper, I can easily change it up when I do find the StructureMap solution. The other thing I had to change was the ForRequestedType<IMailingListSubscriber> in the Registry. Now it looks like this:

ForRequestedType<IMailingListSubscriber>()
.TheDefault.Is.OfConcreteType<
FluentMailingListSubscriber>();
//.EnrichWith(x => new MailingListSubscriberWithNotifier(x, new EmailNotificationService(new JoinMailingListNotification())));

I commented out what wasn’t working for me so I can go back to it later when I find the solution.


Alright, so I think that is everything that went wrong today…not too shabby :)


Thanks for reading and please continue to give feedback!

kick it on DotNetKicks.com

Wednesday, December 30, 2009

Wife’s Site Launched…YAY for MVC!




After weeks of writing new posts about everything I was learning and doing, the wife’s site has finally launched! Please visit it and let us know what you think. We are very excited!

We had several things that were important to both of us in the development. See below.

Deran’s List

Amy’s List

  • Use Best Practices
  • Learn New Tools
  • Make it Accessible
  • Keep the Code Clean & Maintainable
  • Keep Version Control
  • Make it Fast
  • Must be Clean Design
  • Easy to Update
  • Friendly
  • Navigation Easy

As you can see below, the site is VERY clean.

image

I hope you’ve read my previous posts and you believe that I used best practices. If not, please let me know because I will absolutely redo some things. I definitely learned A LOT during the process in particular, ASP.NET MVC, jQuery, & StructureMap. Amy thinks the site is easy to update…at least the pictures! Everything else is static XHTML and I know she’ll make me update that text, but it rarely changes.

I think I’ve made it as accessible as I know how. All the images have alt tags, the links have titles, access keys are all in place (including the standard 1,2,3,4), skip navigation is there, all forms have fieldsets & labels, and it’s all laid out with CSS. If I am missing ANY accessibility things, PLEASE let me know because that is VERY important to me.

I tried to make it friendly, I set the textbox focus where necessary, I have friendly messages like “Oops! Invalid email address.”, there are messages for just about everything, the textboxes change colors when invalid, the URLs are VERY friendly, so I think that goal was met.

The code is probably some of the cleanest and most maintainable code I’ve written in a LONG time. So no worries there.

The navigation is VERY straight-forward. Categorized at the top of the page and then you have the standard links at the bottom. Simple!

I kept version control with GIT and it’s backed up to my WHS nightly.

I’ve run the site through YSlow and optimized as much as possible.

I’ve encrypted the web.config settings, turned off debug, and enabled customErrors. I think it’s done! Yay :)

Warning…vent session here:
In case any of you are wondering what I laid the site out with, I used Fireworks 8. Fireworks 8 is single-handedly the BEST Web layout tool ever…then Adobe bought it and turned it into a bloated piece of crap like the rest of their software. Just my opinion, but Fireworks was built to be a Web layout tool and that is EXACTLY what it does…nothing more…nothing less. I love it!

Thanks for reading and PLEASE give us your feedback on her new site!

Related Posts:

Final Project MVC Structure
image

kick it on DotNetKicks.com

Tuesday, December 29, 2009

JavaScript – Not Required




As an end-user of many different sites, it appears to me that it is becoming increasingly difficult to have JavaScript turned off and increasingly dangerous to have it on. I’m a huge fan of JavaScript, but I think it’s unfair to design my web sites to force my end-users to have JavaScript turned on. So I try and make everything accessible without JavaScript. It might not look as fancy, but everything on my sites function and that’s what’s important.

Take my latest project, my wife’s re-design (not yet published as of this post), we’ve added several JavaScript niceties. However, EVERYTHING still works with JavaScript disabled and we pop-up nice little messages to let the end-user know why something is appearing the way it is. Here’s what we’ve done:

  • We have a group of images that fade in and out using jQuery on the homepage. When JS is disabled, the first picture is displayed and that’s it.
  • We have a Join Mailing List feature that uses ajax via the jquery.form plugin by Mike Alsup, which converts our form into an ajax form otherwise it leaves the default action. When JS is disabled, the call is the same, but our messages are formatted so the end-user will see a specific error or message stating why it’s formatted a certain way. To read more on how we implemented this, see the “jQuery AJAX with ASP.NET MVC” post.
  • For her portfolio page, we used jquery.lightbox, which pops up a nice modal effect for her images. When JS is disabled, every link just links to the picture and the picture pops up in the browser and then the end-user has to click back to get back to the gallery.
  • On her contact page, we use jQuery to decode her email adddress. To get around this issue, we use a real address for the mailto:, but it’s meant for spammers and we display a nice message letting the end-user know why they’re seeing email [[at]] domain [[.]] com. To see more on how we did this, see the “Trick Bots from Stealing Email Address with jQuery...” post.

Bottom line, don’t force users to do something they shouldn’t HAVE to do and make your web site accessible and friendly. Provide <noscript> messages when necessary and try disabling JavaScript on your browser and browsing your web site to see how people feel.

That’s it! As always, please comment if you see anywhere that I could improve or you just have a comment. Thanks for reading!

kick it on DotNetKicks.com

Monday, December 28, 2009

US State DropDownList with ASP.NET MVC FluentHtml




I recently ran into this “issue” and thought I’d blog it real quick. So as I mentioned in a previous post, I love FluentHtml and I wanted an easy way to create a state list. So I Googled it and of course stackoverflow.com popped up with this post. I thought…that works, but I just want the 50 states and I don’t want the full name AND I want to use FluentHtml and not have to create another extension. I used Kyle West’s list as my base to get started.

So I created a UnitedStates class in my Core.UI.Helpers.Common folder (see my MVC structure here) and it looks like this:

    public class UnitedStates
{
public static readonly IDictionary<string, string> StateDictionary = new Dictionary<string, string>
{{
"AL", "AL"},{"AK", "AK"},{"AZ", "AZ"},{"AR", "AR"},{"CA", "CA"},{"CO", "CO"},
{
"CT", "CT"},{"DE", "DE"},{"FL", "FL"},{"GA", "GA"},{"HI", "HI"},{"ID", "ID"},
{
"IL", "IL"},{"IN", "IN"},{"IA", "IA"},{"KS", "KS"},{"KY", "KY"},{"LA", "LA"},
{
"ME", "ME"},{"MD", "MD"},{"MA", "MA"},{"MI", "MI"},{"MN", "MN"},{"MS", "MS"},
{
"MO", "MO"},{"MT", "MT"},{"NE", "NE"},{"NV", "NV"},{"NH", "NH"},{"NJ", "NJ"},
{
"NM", "NM"},{"NY", "NY"},{"NC", "NC"},{"ND", "ND"},{"OH", "OH"},{"OK", "OK"},
{
"OR", "OR"},{"PA", "PA"},{"RI", "RI"},{"SC", "SC"},{"SD", "SD"},{"TN", "TN"},
{
"TX", "TX"},{"UT", "UT"},{"VT", "VT"},{"VA ", "VA"},{"WA", "WA"},{"WV", "WV"},
{
"WI", "WI"},{"WY", "WY"}};
}


I wanted to keep it an IDictionary in case I ended up wanting to use the full state name, but as you can see, pretty basic stuff. Now for the fluent goodness.


<%
=this.Select(f => f.MailingAddressState).Options(UnitedStates.StateDictionary).Selected("TX")%>



If you’re familiar with FluentHtml, then you know what the lambda is in the Select(), otherwise, go checkout FluentHtml or this previous post. After the Select() call, I call the Options() and pass in my StateDictionary and then call Selected(“TX”) to set the default selection. Good stuff!



Please let me know if you have any questions or if you see anything that I can improve. Thanks for reading!

kick it on DotNetKicks.com

Change Default TextBox Value with jQuery




So I was working on a new project and I wanted to use a descriptive text in my textbox so I wouldn’t need to display a label to keep the look a little more simple. Obviously I still have a label for the textbox for accessibility reasons, I just hide the label with CSS. Okay…this is harder to explain than I thought, so I’ll show you a picture.

image

This is what I’m talking about. I want to hide the descriptive text on focus and put it back on blur if nothing changed. So want to change the style and reset the value on focus and blur. We’ll start with the focus and here is the jQuery:

        $("input").focus(function() {
if ($(this).val() == $(this).attr("title"))
$(
this).val("").css('color', '#000');
});

What the above code says is for ALL input types onfocus do this function. The function says if this input value = this input’s title, then set the value to nothing and set the color style to black.


Simple enough right? Let’s look at the blur, which simply means out of focus.

        $("input").blur(function() {
if ($(this).val() == "" || $(this).val() == $(this).attr("title"))
$(
this).val($(this).attr("title")).css('color', '#666');
});

Okay, so this code says for ALL input types onblur do this function. The function says if this input value = nothing OR this input value = this input’s title then set this input value back to the title and change the color style to a gray.


So now anytime I want to set a descriptive text, I just need it to match the title of the input and I can use this script for all of it. We should be using the title attribute anyhow!


Please let me know if you have any questions or if you see anything that I can improve. Thanks for reading!

kick it on DotNetKicks.com

StructureMap – Part 3




This is a continuation of StructureMap – Part 2. We will be getting into adding instances for particular interfaces with StructureMap. I left off last time with the mention of the IMailNotification as a constructor dependency of the INotificationService. So I was trying to figure out how to set different classes to an IMailNotification because I don’t always want to use one. I could have 50 of the things. Basically they’re just messages that are emailed. So let’s get to the code!

Here is the StructureMap code for creating instances:

            ForRequestedType<IMailNotification>()
.AddInstances(x=>
{
x.Is.OfConcreteType<
JoinMailingListNotification>()
.WithName(
DependencyInstanceNames.JoinMailingList);

x.Is.OfConcreteType<
ContactNotification>()
.WithName(
DependencyInstanceNames.Contact);
});

It reads pretty easy, for requested type IMailNotification add instances of type JoinMailingListNotification with name JoinMailingList and of type ContactNotification with name Contact. I added a little helper class for the DependencyInstanceNames because I love being strongly-typed. My little helper looks like so:

    public class DependencyInstanceNames
{
public const string JoinMailingList = "JoinMailingList";
public const string Contact = "Contact";
}

So then…how do you reference this in your code? Guess what? It’s easy too! So in the UI , I simply call:

 var notification = DependencyRegistrar.Resolve<IMailNotification>(DependencyInstanceNames.JoinMailingList);

If you remember from the last post, I said I “stole” the DependencyRegistrar from the sample code in the ASP.NET MVC in Action book. So you can either buy the book or download the sample code from their site. I think I made a few modifications, but nothing major. I know I at least added this method:

public static TInstance With<TWith, TInstance>(TWith o)
{
return ObjectFactory.With(o).GetInstance<TInstance>();
}

I added it so I could make this call:

var notificationService = DependencyRegistrar.With<IMailNotification, INotificationService>(notification);

This call is what I was referring to in Part 2, when I said I would talk about it in the next post. If you remember from the Part 2, I had a constructor dependency that looked like this in the StructureMap configure():

 ForRequestedType<INotificationService>()
.TheDefault.Is.OfConcreteType<
EmailNotificationService>()
.CtorDependency<
IMailNotification>();

Basically what the With call does is lets StructureMap know that I have to pass this into my EmailNotificationService class. Pretty slick stuff I thought. I hope you think the same.


Please let me know if you have any questions or if you see anything that I can improve. Thanks for reading!


kick it on DotNetKicks.com

Sunday, December 27, 2009

ASP.NET MVC Solution Structure




After reading Jimmy Bogard’s post “Organizing ASP.NET MVC Solutions”, I decided to give it a try in my latest project. Basically it means ALL C# code is in the Core project and everything that represents a deployment are in the UI project. It makes deployment really simple. So far I like it because compile time is much faster and dealing with all the references is much simpler. Another thing to note is that if I wanted to extract anything out of my Core project, I’d just cut the folder I want to separate into another project. Here’s the structure of my current project after I got everything setup:

image

One difference between my setup and Jimmy’s is I don’t like having a Content folder. I’ve been doing the _c, _i, & _j since around 2003 and I like it for a few reasons. One, I always know that “global” items are at the top of my folder structure and I can quickly delete all other files in the structure. Two, it’s much shorter than content/images, content/css, content/etc. Three, I just like sticking with my standards I’ve created over the years. Definitely read Jimmy’s post for all his reasons and loads of comments.

Please let me know your thoughts! Thanks for reading!

kick it on DotNetKicks.com

Saturday, December 26, 2009

CSS – It’s been a while old friend…




I remember back in 2003 reading Zeldman’s book called Designing with Web Standards and it is one book that truly changed the way I was marking up my pages. Since then, Zeldman’s on his 3rd edition and I haven’t developed a site using table-based layout.

Since the baseline of standards came into play, I have developed many sites with css-based layout and thought I was doing good. Well my wife had this little project for me and I thought I’d look and see if anything has changed or if there are any new standards I could really start using since I last started using back in 2003. I think I’ve researched one other time around 2005 for CSS sprites, so it appears I look into CSS every couple years or so. I guess it doesn’t change too often, which is a good thing!

Basically, what I found was that there are some new things out there. You have the CSS Pseudo-classes (kinda new), the reset stylesheet, the 960 grid, the YUI library, etc. I’ve been developing and dealing with a lot of these headaches just by figuring out “hacks” myself, but obviously there has been progress and I’ve just missed out the last couple years.

So based-off the recent research, these are the things I’ve started to use.

  1. reset.css – I ended up using Eric Meyer’s Reset CSS
    • I did consider using Yahoo’s since it’s hosted and probably already cached on a lot of different end-user machines, but ultimately went with the “Master of CSS”.
  2. Taking advantage of a type of if statement for IE, which looks like this:
    <!--[if gte IE 7]><!-->
    <link rel="stylesheet" type="text/css" media="screen, projection" href="~/_c/screen.css" />
    <!-- <![endif]-->
    <!--[if IE 6]><link rel="stylesheet" type="text/css" media="screen, projection" href="~/_c/ie.css" /><![endif]—>
  3. Taking advantage of having one reference to a stylesheet called “screen.css”. My screen.css looks like this:
    /* import css and hide on IE/Mac \*/
    @import url("reset.css");
    @import url("lo.css"); /*lo = Layout*/
    /* end import/hide */
  4. There are a couple of Pseudo-classes I’m using in my CSS and they are :first-letter and :after…of course I’ve always used :visited, :hover, :active, and :link
    • I’ve noticed the pseudo-classes seem to be the least dependable other than those relating to anchors.

As of right now, that’s all I’m using to help my layout. I will probably end up using some of the tools on the YUI site and possibly the 960 grid system. I  haven’t yet though.

Whenever I go learn about CSS, there are a couple main places I go. They are:

I usually look at their source first to see if I see commonalities and if anything looks different than I’m used to seeing. Occasionally I’ll buy a book on the topic, but it’s been a while…probably 2 years.

So there’s the what’s new with CSS to me…I’m sure most of you are thinking…shouldn’t this post have been made 2 or 3 years ago?

Ah well, it’s done now! Have a good one and thanks for reading!

kick it on DotNetKicks.com

Wednesday, December 23, 2009

StructureMap – Part 2




Before reading this post, you might want to read StructureMap – Part 1. It’s a little more basic than this post and I’m more confident that that one is ALL correct :) What I’ll be showing below, there may be better ways, but I’m pretty new to StructureMap too.

In my first post, I had a mapping from IMailingListSubscriber to FluentMailingListSubscriber. Well, my wife had to inform me that she didn’t just want the subscriber to write to a database, she also wants to be notified and for the subscriber to be notified that it was successful via email. So I thought…well great! How am I going to do that with StructureMap? Luckily for me I had just attended an IoC workshop hosted by Headspring in Austin and they happened to go over just this type of thing. Let me show you how I modified the class before I get into the StructureMap.

I created a new class called MailingListSubscriberWithNotifier and it implements the IMailingListSubscriber interface, which you can see in this post. Well my new class depends on IMailingListSubscriber and INotificationService, so I pass both of them in via the constructor like so:

        private readonly IMailingListSubscriber _mailingListSubscriber;
private readonly INotificationService _notificationservice;
public MailingListSubscriberWithNotifier(IMailingListSubscriber mailingListSubscriber, INotificationService notificationService)
{
_mailingListSubscriber = mailingListSubscriber;
_notificationservice = notificationService;
}


So obviously I’m taking advantage of the Decorator Pattern here and I’m able to decorate the subscriber with a notify like below.

        public void Subscribe(string emailAddress)
{
_mailingListSubscriber.Subscribe(emailAddress);
_notificationservice.Notify();
}


One thing I have not shown is the INotificationService, which looks like this:

public interface INotificationService
{
void Notify();
}


I like keeping it simple :)



Okay, so how do I inject all this into my UI? It’s pretty easy too…easier than I thought it would be!



Here’s the StructureMap code:

            ForRequestedType<IMailingListSubscriber>()
.TheDefault.Is.OfConcreteType<
FluentMailingListSubscriber>()
.EnrichWith(x =>
new MailingListSubscriberWithNotifier(x, DependencyRegistrar.Resolve<INotificationService>()));


What this says is for the requested type of IMailingListSubscriber the default is FluentMailingListSubscriber and enrich it with MailingListSubscriberWithNotification and when creating MailingListSubscriberWithNotification, inject a new instance of INotificationService. This may or may not be important to note, but StructureMap never actually calls “new” on anything it injects. I was taught that at the Headspring workshop, but Matt Hinze did not mention how it actually does create the instances.



I also had to add to my original configuration the mapping for the INotificationService, which looks like this:

  ForRequestedType<INotificationService>()
.TheDefault.Is.OfConcreteType<
EmailNotificationService>()
.CtorDependency<
IMailNotification>();


This code is a little different from the others in that it has a constructor dependency of IMailNotification. I will go into more detail on how to handle the IMailNotification dependency on the next post about StructureMap because I’m going to provide an example on how to setup different instances of an interface.



Please let me know your thoughts! Thanks for reading!

kick it on DotNetKicks.com

Tuesday, December 22, 2009

AutoMapper – ASP.NET MVC




First things first, let’s setup our Profile and call our configure from the global.asax. After reading blogs and sample code, I believe this is the best practice while using AutoMapper. I try to only post best practices, but sometimes I slip up or have a brain fart. So let’s rig this thing up.

Step 1: Create an AutoMapperConfigurator

    public class AutoMapperConfigurator
{
public static void Configure()
{
Mapper.Initialize(x => x.AddProfile<MyProfile>());
}
}

Note: I put my AutoMapperConfigurator under Helpers –> Configuration


Step 2: Create the MyProfile class (as mentioned above), which inherits from AutoMapper.Profile

    public class MyProfile : Profile
{
public const string VIEW_MODEL = "MyProfileNameHere";
protected override string ProfileName
{
get { return VIEW_MODEL; }
}

protected override void Configure()
{
CreateMaps();
}

private static void CreateMaps()
{
//Create Maps here…we'll get to this in a second
}
}

Step 3: Plug into global.asax

        protected void Application_Start()
{
AutoMapperConfigurator.Configure();
}

Okay, we’re all setup, let’s make some maps. I will be mapping the two objects(FeedbackForm & INotificationMessage), which are listed below. The FeedbackForm is part of my view model on my MVC project & INotificationMessage is part of my domain model.


Here is the FeedbackForm:

    public class FeedbackForm
{
public string SenderName { get; set; }
public string SenderEmail { get; set; }
public string Subject { get; set; }
public string MessageBody { get; set; }
}

And my INotificationMessage:

    public interface INotificationMessage
{
string Subject { get; set; }
string MessageBody { get; set; }
}

Step 4: Map the objects

        private void CreateMaps()
{
//Mapper.CreateMap<FeedbackForm, INotificationMessage>() //BEFORE JIMMY’S COMMENT BELOW

CreateMap<FeedbackForm, INotificationMessage>(); //AFTER JIMMY’S COMMENT
}

UPDATED 12/22/09 8:00PM
According to Jimmy, I should use just CreateMap<> above instead of Mapper.CreateMap and since he’s the creator of AutoMapper, I guess I’ll trust him :) Thanks Jimmy!


That’s it! Done! If my property names didn’t match up exactly, there would be more work to do, but since they do, we’re done! For a GREAT tutorial on AutoMapper, see Jimmy Bogard on dnrTV.


Now let’s use it in our controller!


Step 5: Create Mapper Interface

    public interface IFeedbackMapper
{
T Map<T>(
FeedbackForm model);
}

Step 6: Implement Mapper Interface

    public class FeedbackMapper : IFeedbackMapper
{
public T Map<T>(FeedbackForm model)
{
return Mapper.Map<FeedbackForm, T>(model);
}
}
The reason we’re doing this and not just using Mapper.Map in the FeedbackController is that we’re trying to keep all the using statements to be our namespaces and that’s it. Everything else should be wrapped by our code so we’re not depending on 3rd party or Microsoft implementations.


Step 7: Inject the IFeedbackMapper into the FeedbackController constructor

        private readonly IFeedbackMapper _feedbackMapper;
public FeedbackController(IFeedbackMapper feedbackMapper)
{
_feedbackMapper = feedbackMapper;
}

Note: You can inject the feedbackMapper using your favorite IoC tool. See my StructureMap posts for more info or the StructureMap site.


Step 8: Use the _feedbackMapper

        [AcceptVerbs(HttpVerbs.Post), ValidateModel(typeof(FeedbackForm)), ValidateAntiForgeryToken]
public ViewResult Index(FeedbackForm form)
{
if (!ModelState.IsValid)
return View("index", form);

var message = _feedbackMapper.Map<NotificationMessage>(form);
//send message via notification service or something and return Success View
}

Step 9: Add more stuff to the mapper and map away!


Please let me know your thoughts! Thanks for reading!

kick it on DotNetKicks.com

Monday, December 21, 2009

ASP.NET MVC – Understanding Routes




Basically what I’m creating is a new web site for my wife’s photography company. Obviously I should’ve made a series out of my last several posts because they all relate to one another. Who knew I’d be learning so much and wanting to share? Anyhow, since I didn’t make it into a series, I’ll just link the related posts below.

  1. jQuery AJAX with ASP.NET MVC
  2. Beauty of Interfaces
  3. Learning Fluent NHibernate
  4. Refactoring my MVC & Photo Repository
  5. StructureMap with ASP.NET MVC

So let’s talk routes! This has got to be one of the coolest things about MVC. The amount of control you have over EVERYTHING is awesome! If you’ve ever created a MVC application, you know this default route:

            routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);

Basically this says route name is “Default” and the URL is constructed by your controller name then the action and then the id and then the new {} sets the default controller and action with a blank id. Pretty simple and you can use it for most things, although on my wife’s site, I’m pretty sure I overrode all my routes to create simpler URLs. However, I did go ahead and leave the default route.


So my wife didn’t want to see /information/about or /information/help in the URL for her customers, so I had to modify my route so her users could go straight to /about and /help. The route to do something like that looks like this:

            routes.MapRoute(
"Information",
"{action}",
new {controller = "Information"});

This is calling my Information controller and passing whichever action is required. Pretty simple. Okay, so let’s continue.


She also wanted her customers to just go to /contact instead of /connect/contact, but I didn’t really want to map everything like that because her join mailing list calls /connect/joinmailinglist and I wanted to keep that route the same. So I created a static route just for contact, which looks like this:

            routes.MapRoute(
"Contact",
"contact",
new { controller = "Connect", action = "Contact" }
);

This route is called “Contact” and it’s set to static /contact and it goes straight to the connect controller and contact action.


So these few routes are really simple. Let me show you one that I think is really powerful, especially for her site. In order to create her portfolio, we wanted her users to go straight to portfolio/nameofportfolio. The route looks like this:

            routes.MapRoute(
"Portfolio",
"portfolio/{name}",
new { controller = "Portfolio", action = "Index" }
);

This is saying go to portfolio/nameofportfolio, which calls the portfolio controller and index action. When you do something like this, your parameter name on index has to match name like on line 3 of the above code. So my index action on the portfolio controller looks like this:

        public ActionResult Index(string name)
{
var pv = new PortfolioView {Name = name, Photos = _photorepository.GetPhotosBy(name)};
return View(pv);
}

What this gives my wife the power to do is create new portfolios all day long. All she has to do is make sure to tag her pics on flickr. To see how we’re calling her pics from flickr, see this post. So if she wants to send out a preview to her customers, she simply uploads to flickr and tags the pics with their last name or some random code and then sends them the /portfolio/lastname URL. We did pay for the pro membership to flickr, so we can get the original formats and connect to private pics.


I’m pretty sure the only place I read about routes was in the ASP.NET MVC in Action book. They have a whole chapter dedicated to routing. Great book! I don’t know how many times I’ve referenced it in my posts now…probably a lot.


That’s it! As always, please comment if you see anywhere that I could improve or you just have a comment. Thanks for reading!

kick it on DotNetKicks.com

Saturday, December 19, 2009

StructureMap - Part 1




If you’ve been keeping up with my blog, you know that I’ve been working on my wife’s new website. If you want to catch up, you can read the following previous posts:

So I wanted to share how I setup my StructureMap configuration. When I first started looking into StructureMap, I was a bit intimidated and I just want to assure you that it was unwarranted. StructureMap is a really friendly tool and easy to setup. I’m going to be using a class called DependencyRegistrar, which I basically stole from the sample code in the ASP.NET MVC in Action book. The only thing I modified was the RegisterDependencies method to add in my Registry. Once you get the DependencyRegistrar class, you’ll understand what I’m talking about.

Okay, so as I mentioned before, with StructureMap they give you a Registry class to inherit from so you can override the configure method. Here is my implementation:

    public class DependencyRegistry : Registry
{
protected override void configure()
{
Scan(x =>
{
x.TheCallingAssembly();
x.WithDefaultConventions();
});

ForRequestedType<
IPhotoRepository>()
.TheDefaultIsConcreteType<
FlickrPhotoRepository>();

ForRequestedType<
IMailingListSubscriber>()
.TheDefault.Is.OfConcreteType <
FluentMailingListSubscriber>();
}
}

Basically what this says is scan the calling assembly and use the default conventions…which means if you see an interface called IDirectorySearcher, create a new instance of DirectorySearcher by default. Below the scan, I specify specific types because they don’t match the default convention. They did originally, but if you remember from my previous posts, I ended up re-implementing a couple things. As of right now, that’s all I have in my registry and it looks really simple and readable.


The only other thing I had to do was call the EnsureDependenciesRegistered method in the DependencyRegistrar I mentioned earlier in the Application_Start() of the global.asax. It looks like this:

DependencyRegistrar.EnsureDependenciesRegistered();

That’s it for the configuration and now I can call DependencyRegistrar.Resolve() to instantiate whatever class is needed! In the Learning Fluent NHibernate post, I called the Resolve method and it looked like this:

var subscriber = DependencyRegistrar.Resolve<IMailingListSubscriber>();

When I call Resolve, it returns the FluentMailingListSubscriber implementation. The main thing I like about any IoC tool is that it forces you to code to interfaces, which is always a good thing! Say I added a new method to the FluentMailingListSubscriber, but not the IMailingListSubscriber. I wouldn’t be able to use the new method because there is nothing there to let me know I can use it. So I have to define it in the interface…good stuff!


Please let me know your thoughts! Thanks for reading!

kick it on DotNetKicks.com

Related Posts Plugin for WordPress, Blogger...