Friday, April 29, 2011

Set facepalm levels to 'Picard'

Well, I figured out my problem.  Naturally, it was me being an idiot.  I forgot to change my strongly typed view to accept a view model instead of a string.  The way the exception appeared, I thought it was telling me that RouteData.Values was throwing it.  Turns out it was the internal dictionary of the view itself.


SO link: http://stackoverflow.com/questions/5808554/asp-net-mvc-2-route-errors-problems-when-using-cottsaks-solution/5838686#5838686

Wednesday, April 27, 2011

Same as it ever was

So, I've made a bit of progress with my 404 implementation, but I'm encountering a NotImplementedException that I'm not sure how to solve.

I'm trying to implement the solution found here: http://stackoverflow.com/questions/619895/how-can-i-properly-handle-404s-in-asp-net-mvc/2577095#2577095  The difference being, I'm using vanilla Ninject 2.0 as my DI container.

Details of my current problem: http://stackoverflow.com/questions/5808554/asp-net-mvc-2-route-errors-problems-when-using-cottsaks-solution

RequestContext is telling me it needs a string somewhere in its internal dictionary.  I don't see where I'm not supplying it a string.

Tuesday, April 26, 2011

Crisis averted

Turns out my SQLEXPRESS service was turned off for some reason.  No idea why, as it's set to automatically run.  Sorry for jumping the gun.

If it's not one thing, it's another

No attempt at a witty title tonight.  I made some minor changes in attempt to get my bad route handling squared away, and now all of a sudden I'm getting an EntityException, specifically that the underlying provider failed on Open.

FFFFFFFFFFFFFFFFFFUUUUUUUUUUUUUUUUUUUUUU

I haven't touched my domain code in days - neither my repositories nor my connection string - and, yes, I'm sure my connection string is in my Web.config.  It was working just last Friday, and the only changes I've made tonight have been removing [HandleError] from an action method and using named parameters when calling a view.  That's it.

As always, more detail on SO: http://stackoverflow.com/questions/5798047/ef4-entityexception-the-underlying-provider-failed-on-open

Monday, April 25, 2011

And now something to lighten the mood

Since I was diagnosed with diabetes at Christmas, this has become one of my favorite things:

While my keyboard gently weeps

As I wait for the ability to offer a bounty on my route error/500/404 problem on Stack Overflow, I figured I might as well write a letter to Microsoft about what I feel they can do better for newbies, like myself, attempting to jump into using their stack for web development.

1. Don't assume anything.  This has to be the biggest area of frustration for me.  There seems to be an underlying assumption that a lot of incoming MVC devs are former web forms devs.  Similarly, there's an assumption that we're comfortable using Visual Studio.  From my personal experience, I do know a little bit of web forms, mostly how horrible the Page object's life cycle is.  I also know what Web.config is used for in an abstract sense, but am certainly not comfortable mucking around in there.  I'm barely competent with VS, having learned the hard way when to build/rebuild a project so it will work right when debugging.  I'm sure others aren't even at that level when they start down this rabbit hole.

2. Ignored or glossed-over info.  This really should be considered 1A.  Again, there's an assumption being made that people are familiar with ASP.NET and are mostly just migrating to MVC and/or EF4.  Look at the model binding validation fiasco I went through earlier.  Even better, look at the route problem I'm currently facing. 

I own what could likely be considered the tome on MVC 2 - Steven Sanderson's Pro ASP.NET MVC 2 Framework.  It is a great book which explains every part of the framework.  In fact, there's an excellent chapter (Chapter 8) which describes, in detail, MVC's routing mechanism.  What it doesn't explain is how to handle malformed routes.  Web.config's customErrors tag is mentioned just once, in passing, on page 612 in Chapter 17, which is dedicated to deploying MVC 2 projects.  That's it.  No description about what customErrors is, nothing about bad routes at all, no hints on making route errors fit into the rest of the routing system, or anything else.  I can't fault the book for not addressing my EF4 issue, as it works with LINQ to SQL instead, but shouldn't malformed routes at least be addressed briefly?

I'm not trying to crap on the book or its author.  I've found, that aside from the bad route issue, it's a great book, and recommend it to anyone looking to join in the MVC 'fun'.  What I'm trying to illustrate is a pattern.  If one of the framework's best books neglects to mention something that is fairly important like handling bad routes, then how are we beginners supposed to know what the hell to do?  It's certainly not addressed (at least, not addressed well) in the demoware, which is where most newbies start.

3. Smaller gripe: where's the at-a-glance info?  I want to know what kind of debugging errors I can step through compared to those I can't.  I want to know what those step-through errors would mean in a live, release environment.  I want to see the differences between Entity Framework 4.0 vs. 4.1, and how the common patterns have changed.  I'm sure this info exists somewhere, but its spread throughout the ether, buried in articles and blog posts.

So, now that I've vented a bit, I have some constructive suggestions on how to make the newbie experience better.

1. Don't assume we come from web forms country.  My background is in PHP.  I've used a grand total of 1 MVC framework in that environment - Kohana 2.something - and it doesn't exhibit any of the Microsoft idiosyncrasies like Web.config.  My IDE of choice back then was Notepad++.  A lot of other wannabe MVC devs comes from similar, or even NO web development backgrounds.  Keep this in mind.  I'm sure a lot of us are willing to skip over the bare-bones basic info we already know if it means you're actually covering all the basics.  I'd rather be inundated with the "No shit, can we move on?" stuff than not.

2. With that said, maybe create a newbie starter pack filled with the info we need to know before diving into MVC as a whole.  Topics could include basic Visual Studio usage (ex: knowing which errors can be stepped through, those that can't, and the differences between them), the basics of ASP.NET (things that are shared between web forms and MVC, like Web.config), and basic C# (ex: LINQ, lambdas, etc.).  If there's a minimum requirement or some prerequisite we need to know before getting into MVC for real, as there seems to be, then why not provide it in a centralized manner?

3. Be thorough.  Books, at least, shouldn't gloss over anything.  I'd rather have the option to dig through the innards of the framework than not.  Again, more information, not less.

In closing, I like the idea behind MVC, and I'm trying to buy, literally, into the platform.  I'd like it if it didn't seem like Microsoft and supporters of the framework made it easier for me to do so.  I'm not looking for anyone to hold my hand or write my code.  I just want the tools in order to do it on my own.

Friday, April 22, 2011

I would write 500 lines, and I would write 500 more

So, I've made a smidgen of progress regarding custom errors.  Some success, mostly failure, but the failure is a different kind of failure, which gives me hope.

The details can be seen at: http://stackoverflow.com/questions/5761573/a-couple-of-errors-when-trying-to-use-custom-errors-in-mvc-2

Paperboy

Routes.  They're one of the key features of MVC, and custom routes are fairly simple to implement.  Just go into Global.asax, and pay attention to how the default route is set up.  The only caveat is that routes must be placed in a particular order - most specific first - in order to work.  Any gamers in the audience who have played either Final Fantasy XII or the Dragon Age games will understand when I say that routes work like Gambits and Tactics, respectively (nerd high five!).

But what if a route fails?  Welcome to my current situation.

From where I sit, route failure happens when one of two things happen:

1. The path is legit, but the parameter(s) is/are wrong, so no data can be retrieved, which results in a view error when the view attempts to display model data that doesn't exist.

2. There's a general flaw with the path, so either the controller or action name is screwed up and the routing system can't find a matching controller-action pair.

In both cases, something is 'not found'.  Sounds like a 404 to me.

Now, maybe it's because I'm still in debug-mode development at this stage, but both kinds of route failure result in a YSOD for me, neither of which mention a 404 not found error.  The first gives me a NullReferenceException, which makes sense as the view is attempting to display properties a a null object.  The second gives me a Ninject exception (I forgot what it was, exactly, and won't be able to get on my development machine until later tonight, so I apologize for the lack of detail), which again makes sense as the controller-action pair is invalid, and Ninject can't find anything which would match it.

What is odd to me is that neither throws a 404.  Again, maybe that's because I'm in debug-mode, and it's showing me errors rather than a useless (for development) 404.  That said, when I apply the [HandleError] attribute to an action, it still doesn't give me the default MVC Error view, which is a bit disconcerting.

So, I'm left wondering what to do.  I've found a variety of answers, ranging from simply turning on custom errors in Web.config to things a bit more... robust, like this: http://stackoverflow.com/questions/619895/how-can-i-properly-handle-404s-in-asp-net-mvc/2577095#2577095  I'm not sure what I should try, or if I'll even see a difference while still in debug-mode.

I'd love to hear how the pros address this, or if it even needs to be addressed at all.

Model binder? I hardly even know her!

The biggest stumbling block I've encountered, so far, was regarding incoming model validation.  Like a good boy, I was (and still am) using Entity Framework 4 for my ORM needs.  Following the examples in the various tutorials I found, my HttpPost method was binding its data straight onto an EF4 entity.  The entity was simple, so simple that I didn't use a view model.  It had a total of four properties, two of which didn't need to be handled by the form (its ID and its LastModified DateTime, which I was originally going to supply in the controller).  I was attempting to test MVC's form validation with Data Annotations when the problem came up - I was getting a ConstraintException from the bowels of EF4.

The exception itself was easy to decipher.  My backing db columns were all set to 'NOT NULL', which was done purposely (I want all articles to have titles, and an article cannot exist without an ID or text.  LastModified is for my own book keeping).  What was odd to me, at the time, was that EF4's entity validation was firing before I even attempted to call SaveChanges().  This validation was triggered right when MVC attempted to bind the incoming form data to an entity.  Since some of the values were purposely empty, they were received as null values, and that, in turn, violated the contract between entity and db.

For a look at the particulars, go here: http://stackoverflow.com/questions/4703085/entity-framework-4-w-mvc-2-fighting-against-ef4s-inability-to-allow-empty-str

This drove me nuts.  Nothing was mentioned about EF4 validation being triggered by MVC model binding.  I scoured over the MVC Music Store demo, and, at the time, there was no mention of it.  I asked Julie Lerman through Twitter, where she was more than gracious with her time and effort, but we couldn't figure out the problem.  I found a workaround on Stack Overflow - there's a Data Annotation attribute which does the trick: [DisplayFormat(ConvertEmptyStringToNull = false].  It worked, but it felt sloppy.  It also didn't address why this was happening.

I eventually found something of an answer here: http://mvcmusicstore.codeplex.com/workitem/6604  The problem for me was that I couldn't step through the error as Jon Galloway claimed.  I'd get the ConstraintException, then a YSOD.  In fact, the YSOD was what alerted me to the error.

I'm still wondering why validation would/should care whether or not an entity in memory has null properties, especially when that entity is not attached to an ObjectContext.  Shouldn't that kind of exception only be raised when one attempts to store the entity back in the db after it's been (re)attached to the ObjectContext?  Seems a bit restrictive to me.

So, the workaround works, but I'm going to change over to custom edit models for incoming data, then transfer that data to an entity.  It will allow me to apply Data Annotations for simple UI layer validation without forcing me to add it to my domain layer entities.  I also don't like relying on the [DisplayFormat] attribute in general.  It has a bad code smell to me.

The beginning of the end is the middle... or something

The first post is always the hardest, so forgive me if this is a bit rambling.

In short, I'm an amateur web developer trying to become a professional.  I'm self-taught (aren't we all?), and certainly not a natural at it.  I'm the guy who has to read, then re-read, then re-re-read code, then try it myself, inevitably cursing the person/people who wrote the example code before seeing that, no it really was my mistake after all.  And even after all that, I'm still barely confident in what I know.  Yeah, I'm that guy.

I'm also, technically, a company.  That's right, I have my LLC, even though it's really just me.  Saying I'm the CEO of a company is a hell of a lot more impressive than the reality of the situation.  It's also easier to put on business cards.

I'm sort of caught between a rock and a hard place at the moment.  I can't really work an 8 hr/day, 40/hr (or more) a week job due to my physical disability.  There's a whole bunch of logistical stuff that comes along with it (like, say, eating and going to the bathroom), and there are also issues with pressure sores.  So, my best bet is with freelancing.  And therein lies the rub.

Freelancing is all about reputation.  I have none.  Most of the work I have done is small, and most of it lies behind the scenes.  PHP stuff here, JavaScript stuff there, but nothing to hang my hat on, and certainly nothing to brag about.  So, I've come up with a foolproof plan.  I think.

I'm going to make two ASP.NET MVC sites.  I'm already halfway or so done with the first (hence my oh-so-clever title), which is written in MVC 2, and its sister site will immediately follow and be written in MVC 3.  These sites will be content-driven, with the content coming from myself and one other person who wishes to be anonymous (yes, she exists.  no, she's not one of the voices in my head.  or a sock puppet).

With this plan, I'm hedging my bets.  I'm creating tangible projects to showcase in my portfolio, which will greatly enhance my ability to get some real work my way.  I'm also hoping I can make some money, even if it's just towards hosting costs, from them.  Finally, I'm forcing myself to learn things I should know.

So, where does this blog fit into the whole thing?  I've found that writing my first MVC 2 site hasn't been nearly as easy as the various resources I've found on the subject led me to believe.  A lot of things are either ignored or glossed over, even in the books I've read/own.  I hope that charting my own successes and failures will help others who have stumbled into the same gaps.  At the very least, this blog may provide some anthropological interest.