Wednesday, April 22, 2009

When using strongly typed views, don't name the controller action arguments with the same name as another form value!

I've been working with ASP.NET MVC for a couple of months now.  It is really pretty awesome.  It's worked so well, I haven't had much to blog about!  The other day I ran into an issue so I'm sharing the solution.   MVC will "automagically" bind the parameters of a controller action based on the values in the form.  And if your View is strongly typed and your controller action has a parameter of that same type, it will bind it too.  But in my case, the parameter was null.  MVC wasn't loading it. And there was no exception to help me out.

Here's a simple demo, I'm not showing every line of code...

 

Typical for an MVC application, I have a view that is strongly typed:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<OrganizationRole>" %>

 

The View has a simple form which includes two text boxes:

<p>
    <label for="OrganizationName">OrganizationName:</label>
    <%= Html.TextBox("OrganizationName") %>
    <%= Html.ValidationMessage("OrganizationName", "*") %>
</p>
<p>
    <label for="Role">Role:</label>
    <%= Html.TextBox("Role") %>
    <%= Html.ValidationMessage("Role", "*") %>
</p>

 

A button on the form posts back to the controller, calling the Create Action.  Here is Action Code:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(OrganizationRole role)
{
    // Do Something Here...
    return View();
}

In the screenshot below, you can see that when I debug the app, the role parameter has not been loaded.

image

The fix was simple but it took a while to figure it out!  All I had to do was re-name the parameter from "role" to "organizationRole":

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(OrganizationRole organizationRole)
{
    // Do Something Here...
    return View();
}

You see, I was being lazy and abbreviated the argument's name.  That is ok, you can name the parameter almost anything you want.  But I gave the parameter the same name as one of the other form variables!  Notice above that my form has a text box named "Role"!  MVC tried to load the values of my parameters - it takes each of the posted values from the form ("OrganizationName" and "Role") and tries to match them up with arguments with the same names (it is not case sensitive) if they exist.  It also tries to load the entire form value (strongly typed as the class OrganizationRole) to the argument of type OrganizationRole, if one exists.  But an argument of type OrganizationRole with the name "Role" screws the who thing up!  The only problem is that it doesn't throw any exceptions.  Anyway, I changed the name and presto, it works.

Wednesday, April 22, 2009 9:01:18 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [1]  |  Trackback
 Saturday, April 04, 2009

It's hard to keep up with posting these photos of Ben.  Time flies.  Lots more news since my last blog post.  First of all, Ben had his 1st birthday!  His grandma made him an awesome cake (and cupcakes) and they were a big hit. 

Ben is really trying to gain some weight (he's a on the small side).  The Dr. put him on a "butter" diet, telling us to put butter on everything he eats.  Somehow he got the message.  All of a sudden he started eating everything in sight.  He gained 1 lb in 6 weeks.  Then he stopped eating again and got really finicky and cranky.  After a few days Rebecca took him to the Dr. to find out that he had an ear infection!  After a day or 2 of antibiotics, he was back to eating again.  He's a pretty funny eater.  One day he'll be eating Brussels sprout (yes, spelled with an "s" at the end, I looked it up), broccoli, meatloaf, spaghetti and meat sauce, salmon, and more.  It's like he loves all different flavor foods.  And the next day, he's bored of it all and won't eat anything!

Right around the time of the ear infection Benny developed another ailment, much to our dismay.  He's become a bit of a "momma's boy"!  All he wants is for his mommy to hold him.  It's pretty funny too because if it's just me and him hanging out, it's all good. He laughs and plays and is perfectly content.  But when Rebecca comes in the room, he starts to get cranky and he just wants her.  I'm sure this is pretty typical behavior for a kid his age.  For me, it's a little insulting - "what, I'm not good enough for you?".  But for Rebecca it is just plain annoying because she can't get anything done when he is around.  This too shall pass.

We've had a few other big achievements lately.  Ben started taking some steps on his own.  Still just 2 or 3 at a time, but people say once it starts, he'll be walking soon enough.  He also has increased his vast vocabulary to 3 words.  In addition to "momma" and "dadda", he now says "dog".  Well, more like "daw daw" but we are impressed.  It's funny too because we don't have a dog.  But he gets excited when he sees them on TV or out walking around, or at friends' houses.

OK, as usual, here are some recent photos...

No, that first one isn't Ben, but a classic just the same.  Big Steve eating Chicken Holiday!  Below are pictures of ben playing, at the park with Grandma, and showing off his new "Vail" shirt (he wants to go skiing there next year!).  Also, three classic "messy face" pictures.  The first is Ben eating his 1st Birthday Cake (his first sugar fix ever).  I think he liked it because you can see him eating his friend Ricky's cake too (with the red icing).  Think he enjoyed it?  And there's another with him covered in Oreo cookie!  Don't worry, he eats a lot of veggies and fruit too!

 DSC03995 DSC04006 DSC04023 DSC04036 DSC04037 DSC04045 DSC04062 DSC04072

 | 
Saturday, April 04, 2009 9:48:13 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, April 02, 2009

My blog has been pretty quiet lately.  Things got a little hectic in mid February. 

More new technology:

After struggling to get the hang of Silverlight for a while, I was really starting to get comfortable with it.  Development on my project was moving along, the client was liking the results, and I was learning a lot!  Just when things were going well, my client informed me that he'd be dropping the project (hopefully temporarily) due to financial issues.  I was disappointed for many reasons.  I felt bad for the client (this economy is hurting a lot of people) and I felt bad for me, I had to find another client without much notice.

Lucky for me, I was able to get started on a new project pretty quickly.  I was very excited to dive into ASP.Net MVC too!  But from a blogging perspective, it meant another shift in direction.  I had been trying to focus on one thing and blog about it a lot.  I like the fact that my blog isn't tied to a particular technology, but it is fun to get good at something and share information.  Oh well.  The fact is, I have been very lucky lately regarding new technology.  I was fortunate to start using VS2008/.Net 3.5 during the Beta at Orbius (lots of LINQ to SQL), then Silverlight 2 for my next client (and lots more LINQ to SQL) and now I'm doing ASP.Net MVC with jQuery, Dependency Injection, and other related stuff (and still lots more LINQ to SQL!) in my current situation.

What to blog about?

So now, no more Silverlight posts (unless I find some time to play around with Silverlight 3 which I am very excited about).  But I hope to continue blogging about what I am learning now.  There is one problem.  I typically try to blog about something that I struggled with and then resolved, hoping to spare others the frustration.  That was easy with Silverlight 2 which I thought was sort of painful to use (but I enjoyed it and liked the result).  But MVC doesn't seem to be like that.  The switch to ASP.Net MVC was pretty easy for me.  And it seems to work pretty well.  The basics are pretty simple, in many ways less confusing that ASP.Net web forms, and I haven't had too many issues yet.  Could it be that MVC really is the right way to go?  So far, it seems that way.  As I dig in more, I'm sure I'll find plenty of blog worthy material.  As a matter of fact, I already have one, to be posted soon.

Business Update:

I've been pretty busy and haven't been focusing on the "business side" of business.  A lot of independent consultants aren't sure how to set up a business and I promised to write about it.  Here's a quick update... I had debated back and forth about incorporating by forming an LLC or S-Corp.  I spoke with a lot of people including some accountants.  In the end, it seemed that there was no need to rush.  I had a client that didn't care.  So I started to operate as a sole proprietor.  However, as a sole proprietor you can operate in several ways.  You can just mix up all of your personal and business money and confuse everything.  Or you can be a sole proprietor and act like a business.  That is what I am doing.  I have separate bank accounts and check books, I got a business credit card, and I record all of my income and expenses in QuickBooks.  Also, being a sole proprietor, I learned that you can also "do business as" some other name. It's called DBA (not like a database).  This is a good idea for someone like me, since I do already have the my web site, blog and email on the domain IngenuityNow.net.  You don't need to actually be incorporated to use a business name!

I also looked into insurance and learned about liability and E and O (Errors and Omissions) insurance.  You need liability so you can't get sued if you knock over a server rack at a client, or a client falls walking into your house (nope, personal insurance doesn't cover that).  E and O is to cover you if you screw up an application, trash a database, or find some other way to ruin a client's business.  From talking to a lot of people, it seems that E and O isn't so popular and most people only get it if the client insists.  It is also pretty expensive.  Liability insurance is much cheaper and seems like a good idea.

I also set up a web site and got business cards.  A little marketing goes a long way towards professionalism!  The web site is pretty simple so far but it will grow in time.  Please let me know what you think.

So what is next on the business front?  I've got to keep the networking up.  There are lots of clients out there, we just need to find them!  I also plan to get the incorporation thing going.  There are some good benefits to it (for taxes and liability) and I have spoken with a few clients that won't work with you without being incorporated (although I know many consultants who never incorporate).  My only pain point so far on all of this is the accounting stuff.  QuickBooks helps, but it isn't that easy to use if you don't grok all of the accounting concepts, so I have a lot to learn

Thursday, April 02, 2009 8:45:44 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, February 19, 2009

If you are looking to learn about Silverlight development, here is your chance.  Our local Microsoft Developer Evangelists are running a free full day event this Saturday featuring a good variety of information. 

To learn more or register, click here.

If you are a beginner or haven't gotten started yet, this is a great opportunity.  I'm not a beginner and my weekends are pretty busy these days.  So initially, I was going to skip this event.  But from my conversation with Dani Diaz last night, it sounds like there will be a decent range of information here, so I think I will attend too. 

I don't know the full agenda but some of the speakers include Dani, Lindsay Rutter, Bill Wolff and Pete Brown.  That's a good line up but to be perfectly honest, Pete Brown is the big draw for me.  I've been reading his blog since I started doing Silverlight development, this guy really knows his stuff.  One thing I've learned over time is that if a good speaker if giving a talk, even on a topic that I think I know fairly well, it is worth attending.  You never know what kind of tidbit you may pick up from them!

Hope to see you there.

Thursday, February 19, 2009 9:42:51 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [2]  |  Trackback
 Friday, February 13, 2009

One thing I really hate about doing Silverlight development is trying to search for good information on the Internet.  When I look for a solution to a problem I am having, I always run into a lot of "noise" in the form of outdated posts that aren't relevant anymore.  There are a ton of questions, answers, and sample solutions on the web from developers working with the Silverlight 2 Beta release.  I know this was all helpful information to share at the time, but a lot of it is useless now.  The problem is, sometimes you have to read the post a bit in order to figure out that the developer was on the Beta.  I've gotten to the point where the first thing I do is look at the date on the post before I read on.  What makes this even more complicated, is sometimes the information in these posts is still relevant and very helpful! 

Oh well, at least we are lucky to be developers in an age where so much information is shared among members of the community.  Can you imaging having to read manuals for all your information ;) ?  I don't mean to discourage anyone from posting.  Don't take me too seriously, I'm just ranting.

Friday, February 13, 2009 8:45:17 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [4]  |  Trackback
 Tuesday, February 10, 2009

The other day I was working on a Silverlight app when I got this error:  Layout Cycle Detected.  The good news is that Silverlight actually gave me an error message that meant something.  That is unusual for Silverlight.  Of course the message didn't tell me what caused it, or how to fix it!  Luckily, there is this thing called the Internet ;-).  I found some information on David Yack's blog (I don't know him) that helped.

It turns out that Silverlight doesn't like it if you put too many TextBoxes in a ListBox (or possibly any other "repeater" kind of list control).  I'm not sure why it only applies to TextBoxes and not other controls, but here is my understanding of the problem...  Each time you add a TextBox to a ListBox it needs to figure out how much space to give the control, as well as all the other controls around it.  It figures that out, and then sizes all of the controls that don't have specific sizes set, and then lays everything out for you.  But I guess in a list, it needs to do this over and over and over again and Silverlight thinks it has gone into an endless loop, so at a certain point it cuts it off and says "Layout Cycle Detected".  Each time a control gets resized, the controls around it get resized, and that goes on and on until you get to the top level control.  I guess I can understand that it could be a problem, but I think the developers at Microsoft have got to come up with a better way to resolve this.  If I want to put a lot of TextBoxes in a list, I should be allowed to do so!  Also, the limit is supposedly 250 TextBoxes, but I am pretty sure I had less than that.

There are a few ways to get around the problem, as far as I know.  In my case there are a bunch of controls that made up the DataTemplate for my ListBox.  Since they are in a StackPanel, I put a fixed size on the StackPanel.  That prevents the "bubble up" of resizing going all the way to the page level.  That seemed to fix my problem most of the time, but not all of the time.  I could probably have kept playing with the layout and putting fixed sizes on more panels.  Instead, I gave in. 

I didn't want to fight with Silverlight any more so I changed all of my TextBoxes to TextBlocks.  Then I set the the ListBox items up so that you can switch them into "Edit Mode".  The problem here is that the ListBox doesn't have built in support for that.  So here is how I did it.  By the way, this is not dependent upon the "SelectedItem" in the ListBox, so you can have multiple items in EditMode at the same time.

The purpose of my list is to display a list of Services to the user.  My ListBox is bound to a collection: ObservableCollection<ServiceListItem>.  ServiceListItem is just a class that represents my data.  Among it's other properties, the ServiceListItem has a property for IsInEditMode.  It is nothing fancy:

            public bool IsInEditMode
            {
                get { return _isInEditMode; }
                set
                {
                    if (_isInEditMode == value)
                        return;
                    _isInEditMode = value;
                    NotifyPropertyChanged("IsInEditMode");
                }
            }
            private bool _isInEditMode;

In my DataTemplate for the ListBox I have two StackPanels, one for ReadOnly mode and one for Edit Mode.  The ReadOnly template has a button to switch to EditMode.  The EditMode template has two buttons.  The Cancel button reverts the data to it's original state and switched to ReadOnly mode.  The Save button saves the data and switched to ReadOnly Mode.  Here is the one that puts the template into Edit Mode (nothing fancy here):

<Button x:Name="EditService" Click="EditService_Click">
    <Button.Template>
        <ControlTemplate>
            <Image Source="../images/pencil.png" 
                   Height="10" 
                   Width="10" 
                   Cursor="Hand" 
                   VerticalAlignment="Center" 
                   HorizontalAlignment="Center"/>
        </ControlTemplate>
    </Button.Template>
</Button>

The code for the button click is pretty simple too:

        private void EditService_Click(object sender, RoutedEventArgs e)
        {
            ServiceListItem item = (ServiceListItem)((Button)sender).DataContext;
            item.IsInEditMode = true;
        }

Actually, the only cool part of this is how the control figures out which StackPanel to display.  Each one has it's Visibility Property bound to the IsInEditMode property!

                           <StackPanel x:Name="EditPanel"
                                       Visibility="{Binding IsInEditMode, Converter={StaticResource BoolVisibilityConverter}}" 
                                       Orientation="Horizontal" Height="20" >

The trick is the Converter.  We're using a Converter that converts a boolean value into a value from the Visibility Enumeration:

 

    public class BoolVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null || string.IsNullOrEmpty(value.ToString()) || !(bool)value)
                return Visibility.Collapsed;

            return Visibility.Visible;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            // we don't need it to convert back but we could implement that later.
            return value;
        }
    }
Don't forget to add the Converter to your user control's resources:
    <UserControl.Resources>
        <ClientUtilties:BoolVisibilityConverter x:Key="BoolVisibilityConverter" />
        <ClientUtilties:BoolInverseVisibilityConverter x:Key="BoolInverseVisibilityConverter" />
    </UserControl.Resources>
And it all just works!
From this, you should be able to figure out the other end of this, switching back to Read Only Mode. 
I hope this helps.  
Tuesday, February 10, 2009 10:01:36 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [1]  |  Trackback

If you read my last post about Ben, you'll know that the winter wasn't going so well.  It seemed like Ben was always sick and in a "bad mood".  Well not anymore!  The little guy that we love is back and crazier than ever.  One day he just changed completely back to his old self.  These days he is sleeping great, eating great, playful as can be and all about having fun!

Ben is loving "real" food.  He really wants to feed himself so we let him do that most of the time.  He eats pasta, scrambled eggs, sweet potatoes and regular potatoes, chicken nuggets, fish sticks, pears, turkey meatloaf, veggie burgers, pizza (crust), peas, broccoli, carrots, mac and cheese and a bunch of other stuff.  He watches what Mommy and Daddy eat and always wants food off of our plates.  Plus, he is taking his bottles more too.  So all that is going well.

Play time is completely different these days.  Benny really seems to "get" the game.  I don't know what goes on in his mind but he is really starting to learn things.  The little gears are really turning in his head.  He loves to play with his Fisher Price "House".  He plays peek-a-boo by lifting the window up and down.  He also loves his "Little People".  And he has car that he can ride on and walk behind.  We are noticing more hand coordination too as he can put balls into a slot or put his blocks together (sometimes).  He's very proud of himself too, especially when he is walking (with our help), standing - yes on his own for a few seconds at a time, and other fun stuff.  Yesterday I said "How big is Benny" and up went his hands.  I had been trying that for a while with him with no result.  But it just clicked and how he does it all the time. 

Ben is really looking forward to turning 1 year old.  He had a lot of fun with his cousin Grace at her Birthday party.  She's older by 10 days!  Check out the picture of them together, it is pretty funny because Grace is big for her age, while Ben is pretty small.

OK, here are some of my favorite pictures from the last few weeks.  Oh, by the way, Benny got his first haircut too.

DSC03884 DSC03915 DSC03922 DSC03967 DSC03976 DSC03982 DSC03983

 | 
Tuesday, February 10, 2009 8:35:26 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, January 27, 2009

If you are working with LINQ to SQL, you may be familiar with this exception message:

"Cannot add an entity with a key that is already in use."

This typically comes up when you are working with LINQ to SQL, as I am, in a "disconnected " situation.  In my case, I am working with a Silverlight Application, so I get some data with one DataContext, then pass it out to my Silverlight application (this is the same with any other web application), make changes to it, pass it back to the server where it gets updated using a different instance of my DataContext.

The interesting thing in my case is that I thought I fixed the problem but I still got the exception.  I'll explain why.  But first, there are several ways you can resolve this issue.  How you choose to fix this will have to do with how your database is set up initially.  I am working with an existing database and there are limits to how I can change the db.  So I have my all of the properties in my LINQ to SQL Entities set as "UpdateCheck = UpdateCheck.Never".  Next I'll "Attach" my entity to my DataContext  but before I do that, I'll "Detach" it  My Detach() method "resets" all of the EntitySets and EntityRefs connected to my entity so that LINQ to SQL doesn't think I am trying to insert them into the database.  Sorry, I'm not going into details on this process in this blog post but you can easily find details on the web.  Now I can attach my disconnected entity to my DataContext like this: 

            using (ABCDataContext db = new ABCDataContext())
            {
                foo.Detach();
                db.Foos.Attach(foo, true);
                db.SubmitChanges();
            }

This should work fine.  But it wasn't working in my case.  Why?  It is a typical case of how various steps I took to resolve the a different problem ended up causing new problems.  I was debugging and trying a bunch of stuff because my calls to Attach were throwing exceptions.  There is an overload to the Attach() method that would look like this -- db.Attach(newEntity, originalEntity)  -- so that LINQ to SQL can compare the two items.  I had been playing around with it but when I commented out my code, I forgot to comment out one line, so it looked like this:

            using (ABCDataContext db = new ABCDataContext())
            {
                foo.Detach();
                Foo oldFoo = db.Foos.SingleOrDefault(f => f.FooId == foo.FooId);  // NOT REMOVING THIS LINE CAUSED THE EXCEPTION!
                //db.Foos.Attach(foo, oldFoo);
                db.Foos.Attach(foo, true);
                db.SubmitChanges();
            }

When I run this, I get the exception "Cannot add an entity with a key that is already in use".  For some reason, even though I wasn't working with "oldFoo", LINQ to SQL didn't like the fact that I requested it from the database.  So I commented out that line (Foo oldFoo = db.Foos.SingleOrDefault...) and everything just started working fine. 

It was a pain but it is over now.  Now it is time to solve more problems...

Tuesday, January 27, 2009 10:10:34 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Saturday, January 24, 2009

It's been a while since my last entry of The Ben Chronicles.  As I look through my collection of photos I see why.  I have taken very few photos of Ben since Thanksgiving.  There's a few reasons for that.  One is that my camera is on the fritz.  But hopefully some new rechargeable batteries will solve the problem.  The bigger issue is that Ben was sick a lot.  In December I think he was sick more days than he was healthy.  First a stomach bug (no details but that was fun), then  a cold, than another cold, than another, etc.  Most of these weren't anything major but one time he gave us a scare when his hole throat puffed out.  Turns out it was just really bad swollen glands due to all of the colds he has had.  Anyway, he was sick during Rebecca's entire winter break which was really a bummer.  Each time he goes back to daycare and then a few days later he is home sick again.  But he seems to be pretty healthy these days (or should I say, today).  People warned me that the first year at school or daycare is when kids get sick the most. 

When he is feeling good, Ben is a bundle of fun.  He's really curious and he is really stubborn.  He loves to crawl around and play with stuff.  He loves being tickled and laughs a lot!  He's not so interested in baby food any more and wants to eat "real" food.  He really likes to feed himself.  I think all of those sick days made him a little more needy because he wants to be held more than ever.  Or maybe it is just a phase he is going through.  He isn't gaining a lot of weight these days, and all those sick days didn't help, but he still seems to be looking a lot bigger.  As he gets close to 1 year old, he really is changing into less of a baby and more of a little boy.  But we still have a long way to go.

 

DSC03868 DSC03873 DSC03875 DSC03877 Baby Smash2

 | 
Saturday, January 24, 2009 1:15:39 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |  Trackback