Archive for the '.Net' Category


DataAnnotation Message Parameters 0

I’m adding custom validation messages to all my data annotation validation attributes. Simple stuff right. I started off with this.

Then added a customer message.

Then moved that message to a resource file

The problem is the resource file says something like “Less than 50”. If I change that 50 on the attribute, someone has to remember to go to the resource file and change it there too. Not very DRY.

Luckily the default message formatting will allow us to embed some tokens in the error message.  All we need to do is change our message to “Less than {1}” and the message is formatted to “Less than 50”….or whatever the argument value might be.

I haven’t found a good list of the parameters you pass, but {0} is the property name, and then I assume 1, 2, 3, etc are the parameters of the constructor in order.

You sneaky deferred execution! 0

As I’ve mentioned we have a series of Extension methods that help with some trivial, but isolated tasks. Here is an example.

public static IEnumerable<SelectListItem> CreatePaymentTypeDropDownListItems(
                                          this IQueryable<PaymentType> @this)
{
    return  @this
            .OrderBy(x => x.Description)
            .Select(x => new SelectListItem
                             {
                                 Value = x.Code,
                                 Text = x.Description,
                             })
            .MarkAsSelected(x=>x.Text == CreditCard);
}

Simple enough right? The MarkAsSelected is another extension method we have to help out. It’s not all that exciting, but here it is.

public static IEnumerable
 MarkAsSelected(this IEnumerable
 @this, Func
 where)
{
    var items = @this.Where(where);
    foreach (var item in items)
    {
        item.Selected = true;
    }
    return @this;

}

Simple enough right? But the credit card payment type was never getting defaulted with the select value. We have unit tests around MarkAsSelected and it works! What’s the problem? Let’s try something really quick.

public static IEnumerable<SelectListItem> CreatePaymentTypeDropDownListItems(
                                          this IQueryable<PaymentType> @this)
{
    return  @this
            .OrderBy(x => x.Description)
            .Select(x => new SelectListItem
                             {
                                 Value = x.Code,
                                 Text = x.Description,
                             })
            .ToArray()
            .MarkAsSelected(x=>x.Text == CreditCard);
}

That works! What’s up? Oh you sneaky deferred execution. I bet it’s you! I’m not an expert, but here is my best guess. When the MarkAsSelected does its foreach, it asks the @this to create an enumerator. It does, but since it is from an IQueryable<T>, it now executes all that deferred execution in the Select and OrderBy. Fair enough. The enumerator spits out all the SelectListItems we want/need.

We pass on the enumerable incase we want to do something after it, and actually we do. Down the road we want to enumerate again. The Select and OrderBy kick in again and we get all brand new SelectListItems.

Throwing that ToArray in there gets us out of operating on the IQueryable<T>, does the Select and OrderBy and lets us operate on a straight list. Makes sense, but not obviously apparent…at least to me.

But you know what? After all that, I think I just prefer this.

public static IEnumerable<SelectListItem> CreatePaymentTypeDropDownListItems(
                                          this IQueryable<PaymentType> @this)
{
    return  @this
            .OrderBy(x => x.Description)
            .Select(x => new SelectListItem
                             {
                                 Value = x.Code,
                                 Text = x.Description,
                                 Selected = (x.Description == CreditCard)
                             });
}

No need to overcomplicate the problem right?

Are extensive extension method an anti-pattern 0

I was explaining my dilemma to a Java friend and the e-mail ended up being fairly interesting, so I thought I would share it.

I’m sure Java has extension methods, but I’ll give it a once over just in case.  You can extend existing classes without sub-classing by extension methods.

public static IEnumerable<SelectListItem>
                            AsSelectListItems( this IEnumerable<Person> listOfPeople){
   IList<SelectListItem> selectListItems = new List
();
   foreach(var person in listOfPeople){
      selecListItems.Add(new SelectListItem(person.ID,
					    string.Format("{0} {1} {2}",
                                                          person.First,
                                                          person.Middle,
                                                          person.Last));
   }
   return selectListItems;
}

Right. So the this operator tells the compiler to basically create this function:

public static IEnumerable<SelectListItem>
                           AsSelectListItems(IEnumerable<Person> listOfPeople);

And invoke it every time you see this:

IEnunerable<Person> p = myService.GetAllPeople();
IEnumerable<SelectListItem> s = p.AsSelectListItems();

You probably knew all this, but it explains how we are using them. We end up calling a lot of extension methods off other extension methods.

myViewData.PersonSelectListItems = myService.GetAllPeople()
                                                   .AsSelectListItems()
                                                   .OrderedByText()
                                                   .StartingWithAnEmptyItem();

In this example we have three extension method calls and I think it really makes the code much more readable, but it makes testing this code a little more difficult. Obviously, the myService is a mocked dependency which will return a fake list of people, but the other extension method calls cannot be mocked, and the scope of the test bleeds a bit.

I like the syntax it gives, but now I’m going to test potentially four classes when I should be testing only one.

This gets pretty pandemic in our code. Especially trying to make Selenium’s API and the assertion API of Nunit and xUnit more fluent.

Type Safe Unit Testing of Data Annotations Validations 0

We’re using the Data Annotations Validators in ASP.Net MVC 2.0, but there wasn’t a really great way to unit test them. I’ve read Brad Wilson’s blog post about how to set them up and unit test them, but I didn’t like how you relied on the name of the property as a string.

// Arrange
var propertyInfo = typeof(Contact).GetProperty("FirstName");

It would be nicer if that used lambda expressions to get the name of the property, so I set out to do just that. Before we begin, I need to remind you, as always, I don’t know what I’m doing. This is my first tiny venture into expression trees so it is possible isn’t the best way to do things, but so far, it’s working for me.

I created a base Specification to wrap up a lot of the messy bits of getting property names by lambdas. I took a look at how the ASP.Net MVC helpers did it and roughly followed their pattern.

public class DataAnnotationSpecification<T> : Specification
{

    public PropertyInfo Property(Expression<Func<T,object>> op)
    {
        return Property(GetInputName(op));
    }

    public PropertyInfo Property(string propertyName)
    {
        return typeof (T).GetProperty(propertyName);
    }

    public static string GetInputName<TProperty>(Expression<Func<T, TProperty>> expression)
    {
        // not sure I totally understand this
        if (expression.Body.NodeType == ExpressionType.Convert)
        {
            var ue = (UnaryExpression)expression.Body;
            return GetInputName((MemberExpression) ue.Operand );
        }

        if (expression.Body.NodeType == ExpressionType.MemberAccess)
        {
            return GetInputName((MemberExpression)expression.Body);
        }
        throw new NotImplementedException();
    }

    private static string GetInputName(MemberExpression memberExpression)
    {
        return memberExpression.Member.Name;
    }

}

I know this probably doesn’t cover an exhaustive list of expressions, but we’re only talking about Property access tests here so we’re probably in the clear.

To make things a bit nicer, I also created some extensions off PropertyInfo to help setup their assertions.

public static class AttributeAssertions
{

    public static void ShouldNotBeRequired(this PropertyInfo @this)
    {
        @this.ShouldNotHaveAttribute<RequiredAttribute>();
    }

    public static void ShouldBeRequired(this PropertyInfo @this)
    {
        @this.ShouldHaveAttribute<RequiredAttribute>();
    }

    private static T PropertyAttributeOn<T>(ICustomAttributeProvider propertyInfo)
    {
        return propertyInfo.GetCustomAttributes(typeof (T), false)
            .Cast<T>()
            .FirstOrDefault();
    }

    public static void ShouldHaveAttribute<T>(this PropertyInfo @this)
    {
        PropertyAttributeOn<T>(@this).ShouldNotBeNull();
    }
    public static void ShouldNotHaveAttribute<T>(this PropertyInfo @this)
    {
        PropertyAttributeOn<T>(@this).ShouldBeNull();
    }
}

We only have the ShouldBeRequired and ShouldNotBeRequired right now, but you could see it will be easy to extend upon them.  The finished spec looks something like this.

public class When_testing_the_state_of_the_CustomerViewData
    : DataAnnotationSpecification<CustomerViewData>
{
    [Then] public void the_customer_first_name_is_required()
    {
        Property(x => x.CustomerFirstName).ShouldBeRequired();
    }

    [Then] public void the_customer_middle_name_is_not_required()
    {
        Property(x => x.CustomerMiddleName).ShouldNotBeRequired();
    }

    [Then] public void the_customer_last_name_is_required()
    {
        Property(x=>x.CustomerLastName).ShouldBeRequired();
    }

    [Then] public void the_email_address_is_required()
    {
        Property(x=>x.CustomerEmailAddress).ShouldBeRequired();
    }

}

That’s not so bad, and it stands up to any refactoring we might do.

Testing when ModelState is invalid. 0

As a follow up to my previous post, testing when ModelState is relatively simple, but leaves me feelings a little uneasy about my tests.

Here is an example tests, stripped down to remove some of the unnecessary bits

public class When_submitting_lead_data_that_is_in_an_invalid_state : Specification
{
    // class fields...etc

    protected override void Given()
    {
        base.Given();
        _mockOrdersRepository = MockRepository.GenerateStub<IOrdersRepository>();
        _checkoutController = new CheckoutController(_mockOrdersRepository);

        _leadDataWithEmptyPlanName = new PreCheckoutViewData();

        // add an error to the model state
        _checkoutController.ModelState.AddModelError("", "");

        _exceptionWasThrown = false;
    }

    protected override void When()
    {
        base.When();
        try
        {
            _checkoutController.Checkout(_leadDataWithEmptyPlanName);
        } catch(ArgumentNullException)
        {
            _exceptionWasThrown = true;
        }
    }

    [Then] public void an_exception_is_thrown()
    {
        _exceptionWasThrown.ShouldBe(true);
    }
}

This feels pretty loose to me, but there can be another tests that tests which states the model will appear invalid.

ModelState.IsValid is always true 2

We ran into a snag with using the new default Data Annotations Validation in ASP.Net MVC 2.0 Preview 2. Maybe it isn’t a snag, but it is not the behavior I would have expected.

Take the following model:

public class Person
{
  public string ID { get; set; }

  public string FirstName { get; set; }
  public string LastName { get; set; }

  [Required (ErrorMessage = "Required")]
  public string EmailAddress { get; set; }
}

Pretty straight forward, but if you post this form:

    <form action="/person/edit" method="post">
        <input type=hidden name="id" id="id" value="" />
        <input type="text" id="firstname" name="firstname" /> 
        <input type="text" id="lastname" name="lastname" /> 
        <input type="submit" />
    </form> 

To this controller action:

[HttpPost] public virtual ActionResult Edit(Person data)
{
   if (!ModelState.IsValid) throw new ItBrokeException();
   return View();
}

Personally, I would expect every post of that form to show up as invalid, but infact, it is always true. Add the following input to the form and it works.

   <input type="text" id="emailaddress" name="emailaddress" /> <br/>

After that, the ModelState.IsValid returns false, like it should.

IIS 7, .Net 4.0 Beta 2 and 503 Service Unavailable…after Beta 1 8

After recently installing Visual Studio 2010 Beta 2 and creating a .Net 4.0 site, I tried to step out of Cassini and into IIS only to get “503 Service Unavailable” and a killed worker process. Checking the event viewer I found the following errors.

The worker process failed to initialize correctly and therefore could not be started.  The data is the error.

Followed by…

The worker process failed to pre-load .Net Runtime version v4.0.20506.

The Google was no help. It returned a handful of result that weren’t all that helpful, but one post was interesting. Someone had a similar problem with the  2.0 runtime when upgrading to the beta and found there were tiny bits of the other runtime sticking around.

I had .Net 4.0 Beta 1 installed before, so I did some digging and found I had the Beta framework:

C:\Windows\Microsoft.NET\Framework\v4.0.21006
C:\Windows\Microsoft.NET\Framework64\v4.0.21006

I also had folders from the Beta 1

C:\Windows\Microsoft.NET\Framework\v4.0.20506
C:\Windows\Microsoft.NET\Framework64\v4.0.20506

I deleted those folders, restarted the .Net 4.0 app pool’s and and hard restart just to be safe. Everything worked. Two hours on a Friday wasted, but we weekend free of worry.

Turning Off ASP.Net Validators 2

In true web forms style, what should be simple is more difficult than it should be, at least in my opinion. Today I needed the following simple UI.

image

Simple enough right? Pick something from the list or type your own text. The JavaScript to enable and disable the controls wasn’t too bad. It’s pretty un-interesting, so I’ll just skip over it. What I found surprising was the validators were still firing even though the controls were disabled. I wasn’t expecting it, but oh well. Now to turn off the control’s validators.

I found a lot of examples that looked like the following:

var myVal = document.getElementById('somevalidatorid');
ValidatorEnable(myVal, false); 

That’s nice, but I really don’t want to have to know each and every validator id for each control. It would also make the generic enable/disable code really tightly coupled to the controls we’re trying to disable.

Luckily, we can just find all the validators manually. jQuery can help us out, but isn’t really required.

function enableAllValidatorsFor(control,shouldEnable){
    var validators  = $.grep(Page_Validators,
				function(validator,i){
                                	return validator.controltovalidate == control.id;
                                });
    $.each(validators,  function(i,validator) {
                            ValidatorEnable(validator,shouldEnable);
                        });    

    // the validator callout leaves the error
    // class on the control after the validator gets
    // disabled, so we have to clean that up.
    if(!shouldEnable){
        $(control).removeClass("error");
    }
}        

The last little bit of code removes a CSS class that is set via a validator callout. It is tightly coupled with our pages, so you probably won’t need it, or will need a different class name. However, even though it is tightly coupled, it’s couple to all the pages and not the instance of the control it is disabling. We probably could find the validtor callouts used by the validator controls being disabled and remove any of the error classes they apply, but that didn’t seem necessary right now.

Something else interesting is the inconsistency of the jQuery API in this case. In the “grep” and “each” method the order of the arguments is reversed in the callback.

For grep you have:

function grepCallback(item, index){}

..and for each you have:

function eachCallback(index,item){}

jQuery Validation and ASP.Net Web Forms 0

I’ve been dark for a while, but there has been a lot in the works. Hopefully there will be a flood of posts coming, most with a happier outcome than this one; however, to get back in the swing of things, I’ll take make it short and sweet.

I get really frustrated with ASP.Net Web Forms

We all know and love jQuery. It is an amazing JavaScript framework. It’s made it possible, for even the staunchest back-end developers, to get excited about writing UI. ASP.Net is the bane of jQuery enjoyment. I’ve covered this in jQuery Selectors and ASP.Net Controls. I have a new frustration: the giant HTML Form ASP.Net puts in the Web Form page.

There is an amazing jQuery validation plugin. It can do just about any validation you’ll need with minimal effort. If you want to validate a single form, it’s great; however, if you need to validate only a portion of the form, it’s a pain.

Since ASP.Net sticks its own <form> tag on the page by default, you’re pretty much screwed. The only option I’ve found so far is to go through each element, running a validation on the individual elements.

Here is an example of what I’m doing:

$().ready(function(){

	$("form").validate();	

	$("#firstname").rules("add", {
	 	minlength: 2,
		required:  true
	});

	$("#submit").click(function(){
		var valid = true;
		valid = valid && $("form").validate().element("#firstname");
		alert(valid);
   	});
});

I hope to find a better solution soon, but this will do for now.

Animating Partial Postbacks and UpdatePanels with jQuery 4

Update panels make it really easy to do pseudo ajaxish stuff with little or no extra effort. Wrap your controls in a an UpdatePanel, pay for the entire page to post back and go through its life-cycle and you’re pretty much there. I’ve already written a bit on the extra steps you’ll need if you’re doing some jQuery magic inside that UpdatePanel. It’s not difficult and easy enough to either delegate up the chain to something outside the UpdatePanel (e.g. event delegation) or rinse and repeat the jQuery after the partial post back is complete (e.g. add_endRequest).

What would be really slick-o-matic is if we could do some animation to transition the partial postback so it wouldn’t just explode with new content in our face. Now granted, that may be an overstatement. The content changes usually aren’t drastic or very distracting to but let’s add a bit of polish.

Keep in mind this is a first draft, done in about 30 minutes after an idea landed in my head at 3am. It still needs some polishing, but the major hurdles are taken care of.

For our example, we’ll have a simple Div that will be worked upon in a partial postback. Our goal will be to gently transition the display of that work to the user. Something like this.

Original Video – More videos at TinyPic

We’ll start off with some basic styles to help illustrate the change. We’ll change the content of the Div and also the class.

	#mydiv{ width:200px; border:solid 1px black; font-size:xx-large; }
	.myclass0 { height:200px; background-color:Blue; }
	.myclass1 { height:100px; background-color:Red; }
	.myclass2 { height:150px; background-color:Lime; }
	.myclass3 { height:50px; background-color:Purple; color:White; }

Nothing too exciting, but our partial postback will give us some new dimensions and style. It’ll get the point across.

Next we need some HTML.

<form id="form1" runat="server">
	<asp:ScriptManager ID="ScriptManager1" runat="server">
	</asp:ScriptManager>
	<div>
		Original time: <%= DateTime.Now.ToLongTimeString() %> 
		<asp:UpdatePanel ID="UpdatePanel1" runat="server">
			<ContentTemplate>
				<asp:Button runat="server" Text="Button" ID="MyButton"
						OnClick="MyButtonClick"
					OnClientClick="return ClientClick(this,'#mydiv'); " />
				<div id="mydiv" runat="server">
					<asp:Label runat="server" Text="Label"
                                           ID="MyLabel"></asp:Label>
				</div>
			</ContentTemplate>
		</asp:UpdatePanel>
	</div>
</form>

The magic is going to live in the ClientClick event handler, but forget about that for now. The server side OnClick event will do some trivial work.

 protected void MyButtonClick(object sender, EventArgs e)
 {
	 MyLabel.Text = DateTime.Now.ToLongTimeString();
	 var c = "myclass" + DateTime.Now.Millisecond % 4;
	 mydiv.Attributes.Add("class",c);
 }

This could just as easily toggled a view from edit mode to read-only, expanded a detailed area, etc. Here, we are just picking one of four css classese to use on the div and also giving a label the current time. Like I said this isn’t the cool part.

The final steps are to do the following:

  • Get the jQuery animation to happen on the click of the button.
  • Get the partial postback to wait until the animation is done.
  • Get the DOM to appear in the pre-animation state when it comes back from the partial postback.
  • Get the animation to happen once we have the new page ready to go.

The function needs to know what needs to be animated upon. I’ve been using slide transitions, but the animation is something I think can very easily be abstracted out. We make some quick tests to see if we are in the process of animating or if the animation has been completed. I struggled with how to delay the button click’s post back from happening until the animation is complete and finally decided to just let it happen a second time, but to flag the second click to allow it to continue posting back. I’m using the jQuery data feature to keep some state about the button.

If we are currently sliding, then there is nothing left to do, and if we are done sliding then we can skip the other steps and continue the postback.

if (d.data("isSliding")) return false;
if (d.data("doneSliding")) return true;

If we don’t meet those conditions, we need to slide. We set our flag, wire up the end request handler and the callback to the slide method and kick off the slide.

The slide method is the simplest.

d.slideUp(500,
	function() {
		d.data("isSliding", false);
		d.data("doneSliding", true);
		$(sender).click();
	});

Slide our control up, and when we’re done, set some flags and kick off the click a second time. With the flags set, we’ll fire off the postback. Nothing really fancy here either. Notice we can still reference d here. We don’t need to find it again.

The endRequest handler looks a bit more involved.

var prm = Sys.WebForms.PageRequestManager.getInstance();

var f = function(s, e) {
	d = $(whatToSlideDown);
	d.css("display", "none");
	d.slideUp(0);
	d.slideDown(500);
	prm.remove_endRequest(f);
}

prm.add_endRequest(f);

Here, inside the function we do need to ask jQuery to find what we want again. The DOM has been changed and the old d we created from $(whatToSlideUp) probably isn’t there anymore. In addition, we need to set the element in the state we left the old element. In this case, we want the display to be set to “none”. This allows the slideDown to work just like we would expect following a slideUp.

This is part of the setup that I don’t like. I’ve tried quickly running a slideUp(0) on the the new elements, but I was seeing a flash of the default state before getting the slide up. This is something that I would like to factor out. The animation, including this default state should be a parameter to the function.

Here is a look at the function as a whole. It’s a stupid function name I know, but that is easily changed.

function ClientClick(sender,whatToSlideUp,whatToSlideDown) {

	if (!whatToSlideDown)
		whatToSlideDown = whatToSlideUp;

	var d = $(whatToSlideUp);

	if (d.data("isSliding")) return false;
	if (d.data("doneSliding")) return true;

	d.data("isSliding", true);

	var prm = Sys.WebForms.PageRequestManager.getInstance();

	var f = function(s, e) {
		d = $(whatToSlideDown);
		d.css("display", "none");
		d.slideUp(0);
		d.slideDown(500);
		prm.remove_endRequest(f);
	}

	prm.add_endRequest(f);

	d.slideUp(500,
		function() {
			d.data("isSliding", false);
			d.data("doneSliding", true);
			$(sender).click();
		});
	return false;
}

That’s it. There is definitely room to polish this up and make it more flexible. I’ll post back when I get it up and running in a real application so it looks more useful.

Next Page »