Wednesday, January 20, 2010

Diving a Little Deeper into AutoMapper Part 1

Disclaimer When reading this post, please keep in mind that there are much better ways to handle what you're about to read and the sole purpose of this post is to give you examples of how to map to different types of objects with AutoMapper and it is not a best practice or implementation post





Everytime I use AutoMapper, I think this is such an awesome tool! I think it’s hilarious to go back and read my first post in April where it states, “Now automapper is one thing I'm not sure I'll benefit from yet.” and I go on to say, “I'm pretty confident that I will eventually slap myself in the face for posting this just because I'm sure it is an awesome tool that I will one day see as VERY cool, but right now...I don't”. Well, I’m slapping myself :)

So let’s dive into some awesomeness that is AutoMapper. If you haven’t read the AutoMapper – ASP.NET MVC post or downloaded Jimmy’s sample code or have any understanding of AutoMapper, you might want to read one of those items first because they will help you understand how to setup AutoMapper.

Okay, so I have this basic Domain Model:

image

I want to map it to this View Model:

image

Notice the view model is flattened out completely and ignores a few properties. Alright, let’s get to the code!

Here is my ViewToDomainProfile:

    public class ViewToDomainProfile : Profile
{
public const string NameOfProfile = "ViewToDomainProfile";
protected override string ProfileName
{
get { return NameOfProfile; }
}

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

private void CreateMaps()
{
CreateMap<
string, Gender>().ConvertUsing<GenderConverter>();

CreateMap<
PersonView, Demographics>()
.ForMember(dest => dest.NationalId, opts => opts.Ignore());

CreateMap<
PersonView, ContactInfo>()
.ForMember(dest => dest.MailingAddress, opts => opts.ResolveUsing<
AddressResolver>())
.ForMember(dest => dest.EmailAddress, opts =>
opts.MapFrom(src => src.ContactInfoEmailAddress));

CreateMap<
PersonView, Person>()
.ForMember(dest => dest.ContactInfo, opts =>
opts.MapFrom(
Mapper.Map<PersonView, ContactInfo>))
.ForMember(dest=>dest.Demographics, opts=>opts.MapFrom(
Mapper.Map<PersonView, Demographics>))
.ForMember(dest => dest.PersonName, opts => opts.ResolveUsing<
PersonNameResolver>());
}
}

There are a few new techniques in here that I’ve never gone over.


First this:

CreateMap<string, Gender>().ConvertUsing<GenderConverter>();

What this says is that anytime you try to go from a string to a Gender Enum, use this class to convert it. The GenderConverter class looks like this:

    internal class GenderConverter : ITypeConverter<string, Gender>
{
public Gender Convert(string source)
{
var ignorecase = true;
return (Gender)Enum.Parse(typeof(Gender), source, ignorecase);
}
}

I tend to only make things public when it becomes necessary, which is why this one is internal. In most the samples I’ve found, the converter classes are public. I put the ignorecase variable above so you’d know what the last bool meant in the Enum.Parse. So this is pretty cool and pretty powerful. Anytime you try to map string and Gender, this is called. You’ll also notice that I don’t have Gender mapped anywhere in any of the CreateMap<> definitions.


Okay, let’s keep going.


Second this:

            CreateMap<PersonView, Demographics>()
.ForMember(dest => dest.NationalId, opts => opts.Ignore());

This code is simply ignoring my NationalId property of Demographics. If I didn’t ignore the property, the mapping would still occur, but when you’re setting up your unit test, the Mapper.AssertConfigurationIsValid(ViewToDomainProfile.NameOfProfile); would fail. So AutoMapper likes you to tell it everything so it knows if you meant to ignore something or not. Everything else I didn’t have to map because the names match. Thank you reflection & AutoMapper!


Third this:

 CreateMap<PersonView, ContactInfo>()
.ForMember(dest => dest.MailingAddress, opts => opts.ResolveUsing<
AddressResolver>())
.ForMember(dest => dest.EmailAddress, opts => opts.MapFrom(src => src.ContactInfoEmailAddress));

So this one does something funky in that it has an AddressResolver, which means basically that MailingAddress has properties and AutoMapper can only map the top-level properties. So Jimmy gives us some cool ways to handle these things. Here’s what the AddressResolver looks like:

    internal class AddressResolver:ValueResolver<PersonView, Address>
{
protected override Address ResolveCore(PersonView source)
{
return new Address
{
City = source.MailingAddressCity,
PostalCode = source.MailingAddressPostalCode,
State = source.MailingAddressState,
StreetLine = source.MailingAddressStreetLine
};
}
}

Basically it instantiates a new Address class and sets the properties. Done and Next!


Fourth this:

 CreateMap<PersonView, Person>()
.ForMember(dest => dest.ContactInfo, opts => opts.MapFrom(
Mapper.Map<PersonView, ContactInfo>))
.ForMember(dest=>dest.Demographics, opts=>opts.MapFrom(
Mapper.Map<PersonView, Demographics>))
.ForMember(dest => dest.PersonName, opts => opts.ResolveUsing<
PersonNameResolver>());

Alrighty…so this one does a few things..two of the same things and then one thing the same as “third this”. So I’m actually waiting on a response from the AutoMapper-users group on whether or not this is a good practice. It passes all the tests and I think it looks clean and made sense to me. So, hopefully I’ll get their approval. I know Jimmy responds often, so hopefully I’ll hear somthing tomorrow. I’ll update the post if it’s not a good thing :)


So the above code simply calls the other two CreateMap definitions for ContactInfo & Demographics. It also resolves the PersonName like we did with Address above. This post is already pretty long, so I won’t put that code in here…mainly cause I want to post my unit tests.


Here are the tests:


First call the AutoMapperConfigurator in the setup like this:

  [TestFixture]
public class ViewToDomainProfileTests
{
[
TestFixtureSetUp]
public void SetupDemoTests()
{
AutoMapperConfigurator.Configure();
}

The first unit test I do is the AsserConfigurationIsValid that Jimmy gives us. It looks like this:

        [Test]
public void automapper_should_be_configured_correctly()
{
Mapper.AssertConfigurationIsValid(ViewToDomainProfile.NameOfProfile);
}

Okay, then I tested the demographics area on my person & personview. Please ignore my test names…they’re not very good.

        [Test]
public void demographics_should_equal_personview_demographics()
{
var personview = new PersonView();
personview.Gender =
"Male";
personview.BirthDate =
new DateTime(1990, 1, 1);
personview.Ethnicity =
"Klingon";
var person = Mapper.Map<PersonView, Person>(personview);

Assert.AreEqual(person.Demographics.Gender, Gender.Male);
Assert.AreEqual(person.Demographics.BirthDate, personview.BirthDate);
Assert.AreEqual(person.Demographics.Ethnicity, personview.Ethnicity);
}

Then I wanted to make sure my PersonNameResolver was working, so I did this:

        [Test]
public void person_name_should_equal_personview_name()
{
var personview = new PersonView();
personview.PersonName =
"John Test Smith";

var person = Mapper.Map<PersonView, Person>(personview);

Assert.AreEqual(person.PersonName.FirstName, "John");
Assert.AreEqual(person.PersonName.MiddleName, "Test");
Assert.AreEqual(person.PersonName.LastName, "Smith");
}

Finally I wanted to make sure my ContactInfo mapping was working, so I wrote this test:

 [Test]
public void person_address_should_equal_personview_address()
{
var personview = new PersonView();
personview.MailingAddressStreetLine =
"1234 Test St.";
personview.MailingAddressCity =
"Testville";
personview.MailingAddressState =
"TX";
personview.MailingAddressPostalCode =
"12345-1234";
personview.ContactInfoEmailAddress =
"test@test.com";
personview.HomePhoneNumber =
"123-456-7890";

var person = Mapper.Map<PersonView, Person>(personview);

Assert.AreEqual(person.ContactInfo.MailingAddress.StreetLine, personview.MailingAddressStreetLine);
Assert.AreEqual(person.ContactInfo.MailingAddress.City, personview.MailingAddressCity);
Assert.AreEqual(person.ContactInfo.MailingAddress.State, personview.MailingAddressState);
Assert.AreEqual(person.ContactInfo.MailingAddress.PostalCode, personview.MailingAddressPostalCode);
Assert.AreEqual(person.ContactInfo.EmailAddress, personview.ContactInfoEmailAddress);
Assert.AreEqual(person.ContactInfo.HomePhoneNumber, personview.HomePhoneNumber);
}

All done! Stay tuned for part 2 where I basically reverse this and go DomainToView and I talk about why some of the names in my ViewModel are weird…like ContactInfoEmailAddress.



Thanks for reading!

UPDATED: 1/20/2009 7:20PM
Please note that going from domain model to view model and back to domain model is NOT a recommended practice. I did hear back from the AutoMapper user group and they wanted to make sure to point that out. Also, all the AutoMapper code is valid, so I will leave it all as is for reference of how to map certain items. I think it’s a good example of mapping random things, which was the original purpose. I do not have any of this code in a production environment, it is simply a demo on how to use AutoMapper to map your objects.

Shout it

kick it on DotNetKicks.com

Friday, January 15, 2010

Validator Injection with C# and StructureMap




I recently had a need to setup validation rules for a registration system. I thought I would share how I was able to create a generic Validator with rules to pass through. Let’s get started.

So I had a rule that an email address couldn’t already exist in the database. So first I needed to define what a rule would look like and this is what I came up with:

    public interface IValidationRule<T>
{
bool IsValid(T model);
}

Here is the implementation:

 public class EmailAddressDoesNotExistRule : IValidationRule
{
private readonly string _connstring;

public EmailAddressDoesNotExistRule(string connstring)
{
_connstring = connstring;
}

public bool IsValid(User user)
{
using (var db = new DataContext(_connstring))
return !db.EmailAddress.Any(x => x.EmailAddress == user.EmailAddress);
}
}

So now do I pass in an IValidationRule to where I want to validate? No. Do I create an array of IValidationRule in the constructor of what I want to validate? Nope. Do I create an IValidator and pass that in? YEP! Let’s take a look at the IValidator and the implementation.


Here is the interface:

public interface IValidator<T>
{
bool IsValid(T model);
}

Here is the implementation:

public class Validator<TModel, TRule> : IValidator<TModel>
where TRule : IValidationRule<TModel>
{
private readonly TRule[] _validationRules;

public Validator(TRule[] validationRules)
{
_validationRules = validationRules;
}

public bool IsValid(TModel model)
{
var isValid = false;
foreach (TRule rule in _validationRules)
{
if (rule.IsValid(model))
isValid =
true;
else
{
isValid =
false;
break;
}
}

return isValid;
}
}

If you’re not familiar with .NET generics, you might want to do some research about them. They’re awesome!


Okay, so how do we tie it into our service? Well, we’re going to inject it into the constructor like so:

        private readonly IUserValidator _userValidator;

public UserRegistrationService(IUserValidator userValidator)
{
_userValidator = userValidator;
}

I’m sure you’re asking…where did the IUserValidator come from? Well, IUserValidator looks like this:

    public interface IUserValidator : IValidator<User>
{
}

Very simple and basically I only do this to make my code more readable. So the implementation of this IUserValidator looks like this:

public class UserValidator : Validator<User, IValidationRule>, IUserValidator
{
public UserValidator(IValidationRule[] validationRules)
:
base(validationRules)
{
}
}

So now back in our UserRegistrationService, we have a method that just calls the IsValid on the validator like this:

        public void CreateNewRegistration(User user)
{
if (_userValidator.IsValid(user))
//CreateAccountFor(user);
else
//throw new InvalidUserException();
}

Okay, so now for my FAVORITE part of this method for validating…the StructureMap code.


In my DependencyRegistry configure(), I added this code:

            ForRequestedType<IUserValidator>()
.TheDefault.Is.OfConcreteType<UserValidator>()
.TheArrayOf<IValidationRule>().Contains(x =>
{
x.OfConcreteType<EmailAddressDoesNotExistRule>()
.WithCtorArg(
"connstring")
.EqualTo(WebConfig.TeamsConnectionString);

//add more here like the line above
});

So as you add validation rules, you simply add them to your configure() and they’re lined up and ready to go! I’ve also seen this method used with formatting rules. I think it’s pretty awesome!


NOTE: If you have a lot of DB calls for validation, you may want to include some type of loader in the Validator and just pass in the items so you’re not making a ton of DB calls.


Let me know what you think and thanks for reading!


Shout it

kick it on DotNetKicks.com

Tuesday, January 12, 2010

ASP.NET MVC Sample Project Launched




Okay, after popular demand of I think 3 people, I’ve published the code for the wife’s website. If you haven’t read any of the posts on my wife’s project, check out this post. This project completely separates UI & C# code, so you only have 2 projects (Core & UI).

Basically, all I did was create a new MVC project with Microsoft’s default template and deleted everything except the following:

  • Views folder
  • Root Default.aspx
  • global.asax (I did delete the global.asax.cs)
  • both web.configs

I referenced my Core, setup my views that match my Core project, and inherited from my global.cs in the global.asax. That was it!

You can check it out via svn here: https://derans.googlecode.com/svn/trunk/

or

download it via zip here: http://code.google.com/p/derans/downloads/list

I feel like this project will act as a great stepping stone to understanding the Code Camp server, which is much more complex.

My unit tests are definitely the weakest part of the project, so there won’t be a need to run any coverage tests or anything like that because this project will not do well :)

The sample project was built with the following tools:

The best practices I mentioned above come straight from experience and the following people/resources:

You can see the exact same Core code in use at sweetandhappy.com. If you see any improvements that can be made or you’d just like to comment, please do so!

Thanks for reading!


Shout it

kick it on DotNetKicks.com

Friday, January 08, 2010

TekPub's Mastering LINQ Challenge

I have a subscription already to Tekpub, but I thought it’d be fun to participate in the challenge. Here is my solution:

 IEnumerable<int> primes = Enumerable
.Range(1, 100)
.Where(isPrime);
 private bool isPrime(int x)
{
return x==2 || (x!=1 && !Enumerable.Range(2, x/2).Any(y => x%y == 0));
}

So there you have it. I hope Justin Etheredge doesn’t consider the isPrime a custom LINQ method. If he does, then I guess my solution would look like this:

 IEnumerable<int> primes = Enumerable
.Range(1, 100)
.Where(x => x ==
2 || (x != 1 && !Enumerable.Range(2, x / 2).Any(y => x % y == 0)));

Check out the details of this challenge from Justin Etheredg’s Post.


Check out GREAT videos on Tekpub!


Here’s my test if you want to verify it’s working.

 [Test]
public void should_return_list_of_prime_numbers()
{
IEnumerable<int> primes = Enumerable
.Range(1, 100)
.Where(isPrime);

//2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97
Assert.AreEqual(25, primes.Count());
Assert.AreEqual(2, primes.ToArray()[0]);
Assert.AreEqual(31, primes.ToArray()[10]);
Assert.AreEqual(73, primes.ToArray()[20]);
Assert.AreEqual(97, primes.ToArray()[24]);
}

private bool isPrime(int x)
{
return x==2 || (x!=1 && !Enumerable.Range(2, x/2).Any(y => x%y == 0));
}

kick it on DotNetKicks.com

Thursday, January 07, 2010

ASP.NET MVC Bootstrapper




Thanks to a comment by thangchung in my last post about the global.asax, I’m going to write up a post using a bootstrapper in my global.cs. So what does that mean? Well basically it’s a technique to boot up your mvc app. Let’s get started!

Step 1: Create your task interface. Mine looks like this:

public interface IStartUpTask
{
void Configure();
}

Pretty simple right? Let’s keep on…


Step 2: Configure StructureMap, otherwise you’re going to have a mess. In my Scan() from my DependencyRegistry, I added x.AddAllTypesOf<IStartUpTask>(); and the completed Scan looks like this:

  Scan(x =>
{
x.TheCallingAssembly();
x.AddAllTypesOf<
IStartUpTask>();
x.WithDefaultConventions();
});

Step 3: Create the Bootstrapper class. Mine looks like this:

    public class Bootstrapper
{
static Bootstrapper()
{
DependencyResolution.
DependencyRegistrar.EnsureDependenciesRegistered();
}

public static void StartUp()
{
var startUpTasks = ObjectFactory.GetAllInstances<IStartUpTask>();

foreach (var task in startUpTasks)
task.Configure();
}
}

The DependencyRegistrar mentioned above, I basically stole from the sample code in the ASP.NET MVC in Action book. I made a few modifications, but not much.


Step 4: Configure your configuration files for all the junk you need to start up.



  • Routes - I took my RouteConfigurator and made it implement IStartUpTask and renamed RegisterRoutes to Configure.
  • MvcContrib InputBuilder – Just made a new class that looks like this:
public class MvcContribConfigurer : IStartUpTask
{
public void Configure()
{
MvcContrib.UI.InputBuilder.
InputBuilder.BootStrap();
}
}


  • Automapper - I already had a configure, so I just tacked on the : IStartUpTask like this:
    public class AutoMapperConfigurator : IStartUpTask
{
public void Configure()
{
Mapper.Initialize(x => x.AddProfile<MyProfile>());
}
}


  • ControllerFactory – I created a new class for it and it looks like this:
 public class ControllerConfigurer : IStartUpTask
{
public void Configure()
{
ControllerBuilder.Current.SetControllerFactory(new ControllerFactory());
}
}

That’s it! So essentially the Global.cs went from this:

protected void Application_Start()
{
MvcContrib.UI.InputBuilder.InputBuilder.BootStrap();
DependencyRegistrar.EnsureDependenciesRegistered();
new RouteConfigurator().RegisterRoutes();
AutoMapperConfigurator.Configure();
ControllerBuilder.Current.SetControllerFactory(new ControllerFactory());
}

to this:

        protected void Application_Start()
{
Bootstrapper.StartUp();
}

Pretty cool stuff! Thanks thangchung for bringing it up!


As always, please comment and thanks for reading!




Shout it

kick it on DotNetKicks.com

ASP.NET MVC Routing: Global.asax & Single Responsibility Principle




Okay, so let’s continue talking about ASP.NET MVC routing. Basically I wanted to talk about extracting the C# code from my global.asax in the UI project and putting it in my Core project. I also want to talk about removing the routing code from the global.asax.cs. We need to stick with the Single Responsibility Principle. You can see a basic approach to routing in this post.

Step 1: Copy everything between the namespace {} from the global.asax.cs and create a new class (I call mine Global) in your Core project and paste the code into it. You’ll probably need to add a reference to System.Web & System.Web.Mvc.

Step 2: Delete the global.asax.cs. Be sure not to delete the whole global.asax, you only want to delete the global.asax.cs.

Step 3: Open global.asax and delete the Codebehind="Global.asax.cs" and modify the inherits to inherit from your new class (Global.cs). Like this:

<%@ Application Inherits="Core.UI.Global" Language="C#" %>

Okay, now your global.asax doesn’t depend on any C# code in your UI project. This is a good thing!


Step 4: Let’s extract your routes from the new Global.cs and put them into a new class (I call mine RouteConfigurator). By the way, the naming and route extraction is in the ASP.NET MVC in Action sample code. To do so, follow these steps:



  1. Cut everything in the RegisterRoutes() method in the new Global.cs class and paste it into your new RouteConfigurator class so it will now look like this:
    public class RouteConfigurator
{
public virtual void RegisterRoutes()
{
var routes = RouteTable.Routes;
routes.IgnoreRoute(
"{resource}.axd/{*pathInfo}");

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

Notice I added a var routes = RouteTable.Routes; to the top of this method.



  1. Okay, so now we need to tie these things together and we just need to put one line of code in the Global.cs and that will look like this:
        protected void Application_Start()
{
new RouteConfigurator().RegisterRoutes();
//StructureMap Configuration Here
//AutoMapper Configuration Here
//etc
}

So now when Application_Start is called, it will call our RegisterRoutes in our extracted code.


Step 5: Enjoy having single responsibility classes and NO CODE in your UI!


As always, please comment if I can improve or you have questions and thanks for reading!

kick it on DotNetKicks.com

Monday, January 04, 2010

WCF – Authentication Service & Solution Structure




I realize that WCF has been out for quite some time now, but my team and I are getting ready to start using it now. So I started playing around with how I think we should setup the project. I thought I’d share it to see if I could get some feedback. I tweeted a question about it, but got no response, so I assume my idea is a good one and not going to lead me down a road of catastrophe…at least I hope!

Well let’s get started and you can let me know what you think. First off let me show you my structure, which is VERY similar to my MVC structure.

CropperCapture[10]

So I have my test projects in my Tests solution folder, my Core (has ALL code), and my WCF project at the bottom. I’m glad Jimmy Bogard had blogged about this setup because I’m REALLY liking it. Let’s start with the Core.Interfaces.

It does one thing and that is, checks the user’s password. Here’s the code:

    [ServiceContract]
public interface IAuthenticationService
{
[
OperationContract]
bool PasswordMatches(User user, string password);
}

Obviously the attributes make it into a WCF contract. The User class looks like this:

    [DataContract]
public class User
{
[
DataMember]
public string Username { get; set; }
[
DataMember]
public string DisplayName { get; set; }
[
DataMember]
public string EmailAddress { get; set; }
[
DataMember]
public string PasswordHash { get; set; }
[
DataMember]
public string PasswordSalt { get; set; }
}

Here you need to add the attributes to make them accessible for the service to use the class. You only need the [DataMember] on the properties that you want accessible. I’ve chosen to set it on all of them. Let’s get to the implementation of the IAuthenticationService.

    public class AuthenticationService : IAuthenticationService
{
public bool PasswordMatches(User user, string password)
{
if (password == "test")
return true;

return false;
}
}

Very simple example, eventually this will have my Active Directory authentication code in it. I also created an AuthenticationService decorated with Logging so I could log failed attempts. Here’s what it looks like:

    public class AuthenticationServiceWithLogging : IAuthenticationService
{
private readonly IAuthenticationService _authenticationService;
public AuthenticationServiceWithLogging() : this(DependencyRegistrar.Resolve<IAuthenticationService>())
{ }

public AuthenticationServiceWithLogging(IAuthenticationService authenticationService)
{
_authenticationService = authenticationService;
}

protected static readonly ILog log = LogManager.GetLogger(typeof(AuthenticationServiceWithLogging));
public bool PasswordMatches(User user, string password)
{
var isAuthenticated = _authenticationService.PasswordMatches(user, password);
if (isAuthenticated)
return true;

log.Warn(user.DisplayName +
" - Invalid Credentials.");
return false;
}
}

Notice I have the StructureMap code in the empty constructor. The reason I have to have an empty constructor is because of the way WCF works…at least it got rid of one of the errors I was receiving :) I may be missing something, if so, please let me know. I read Jimmy Bogard’s post on WCF with StructureMap and thought his solution was more than what I needed for the time being. Trying to stick with the YAGNI principle. So this implementation uses Log4net, which I have not wrapped in my own code yet, but I will! Since this isn’t a log4net or StructureMap post, I won’t go into any other details.


Okay, let’s look at the WCF project code, which is VERY simple indeed! Here’s the AuthenticationServiceWithLogging.svc code:

<%@ ServiceHost Language="C#" Service="Core.Services.AuthenticationServiceWithLogging" %>

Done!


Now for the Global.asax:

<%@ Application Inherits="Core.Global" Language="C#" %>

Done!


All done other than the web.config settings:

  <system.serviceModel>
<
bindings>
<
basicHttpBinding>
<
binding name="SecureBasicHttpBinding">
<
security mode="Transport">
<
transport clientCredentialType="None" />
</
security>
</
binding>
</
basicHttpBinding>
</
bindings>
<
behaviors>
<
serviceBehaviors>
<
behavior name="Core.Services.AuthenticationServiceWithLoggingBehavior">
<!--
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />-->
<
serviceMetadata httpGetEnabled="true" />
<
serviceDebug includeExceptionDetailInFaults="false" />
</
behavior>
</
serviceBehaviors>
</
behaviors>
<
services>
<
service behaviorConfiguration="Core.Services.AuthenticationServiceWithLoggingBehavior"
name="
Core.Services.AuthenticationServiceWithLogging">
<!--
<endpoint bindingConfiguration="SecureBasicHttpBinding" address="" binding="basicHttpBinding" contract="Core.Interfaces.IAuthenticationService"/>-->
<
endpoint address="" binding="basicHttpBinding" contract="Core.Interfaces.IAuthenticationService"/>
<
endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</
service>
</
services>
</
system.serviceModel>

You should notice the commented out code in gray. If you want to use your service via HTTPS, you’ll need to uncomment that code and delete the lines below it.


So that’s it! Pretty simple and clean I think. Please let me know what your thoughts are and whether I’m WAY off on WCF :)


As always, thanks for reading!

kick it on DotNetKicks.com

Saturday, January 02, 2010

Blogging Tips from a Newb




Since I really started blogging last month, I thought I’d share some of the things I’ve learned the past month. By no means am I an expert, but these few things have helped me. (Obviously I’m not an expert, I have 22 readers, not 49K+ like Mr. Scott Hanselman :) By the way, I recently downloaded his Baby Smash creation and my baby loves it! So if you have a kid, you might want to check it out. Anyhow…

1. I started using Windows Live Writer. It saves a TON of time and is really easy. Benefits I’ve found thus far:

  • Pings servers for you
  • Easily save drafts and publish later
  • Manage multiple blogs (not that I have more than one)
  • Download plugins
  • Setup auto linking
  • Spell check
  • Setup your tags/categories before publishing

2. I started pinging different services to let them know I posted. Below is a list of the services I’m currently pinging through Windows Live Writer.

CropperCapture[6]

3. I setup some plugins to help automate some things. Below are the plugins I’m using.

CropperCapture[9]

Quick run down of what each plugin does: (Note: all of the plugins were free)

4. I downloaded Cropper to grab screenshots. I found this tool last week thanks to Jeffrey Palermo’s post on it. I love it now! It makes doing screenshots A LOT easier.

5. I setup Feedburner recently too because it gives more statistics on who’s reading your blog. However, it gets discouraging to me. It topped out at 41 I think and now it’s at 22. I’m not sure why because I really haven’t read up on how it averages the “subscribers”.

6. I setup Google Analytics when I first started back in April and it’s helped a lot.

Again, I am by NO MEANS an expert NOT EVEN CLOSE! So, if you are an expert, please provide us with some comments of advice. I love learning new things and could definitely use the help!

As always, thanks for reading!

kick it on DotNetKicks.com

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

Related Posts Plugin for WordPress, Blogger...