The SitePoint Forums have moved.

You can now find them here.
This forum is now closed to new posts, but you can browse existing content.
You can find out more information about the move and how to open a new account (if necessary) here.
If you get stuck you can get support by emailing forums@sitepoint.com

If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

<!-- set runAllManagedModulesForAllRequests="true" to persist FormsAuthentication after routing --><modulesrunAllManagedModulesForAllRequests="true">

The second thing you will want to do is set up the aspnetdb database. Use the ASP.NET Configuration tool to do this. Enabled roles and add one. Then add a user, adding him to the role. Make note of the username and password. We will use this later.

This sets a decimal value as the constraint for the id parameter and defaults for all, then adds the route. In addition, we add a route to ignore requests for axd resource files. Why do we not add constraints for the command and action parameters? You'll see shortly.

Now add a code file name RequestController.vb to your code base and use this code:

Here is where we create our command object based off of the command and action parameters. If it cannot be created, we use a known command instead. In this case, the home page. This is why we didn't add constraints earlier. We want all typos in user typed urls to actually go somewhere.

Now here are the two abstract classes in our sysem. The CommandAbstract and ViewAbstract. You can add as much as you want to these and persist just about anything you wish between command and view.

You should now be ready to compile and run.If you try this sample and have problems, let me know.

Ideally, you will want to store your html templates externally and read them in, whether they be in static files, xml, or database. This leave a very clean system, in that there are NO aspx files whatsoever in the application (yes, this means you can delete the Default.aspx now). I store my localized phrases and templates in a db as bits and pieces are pull them in when needed, but that's beyond the scope of this little tutorial.

I hope this was useful, or at least, insightful, to somebody.

Thanks for your contribution and you have added a huge code and i want to salute you for this effort and your tips are very helpful, i have saved all of you codes in my note pad.
Thanks.

While we are talking MVC, I might as well kick a question to the crowd: What is the best practice vis-a-vis WebFormViews. Being a bit of an old webform head, I start thinking about how I can subclass MvcView and stuff all sorts of neat stuff in there, but I suspect that isn't the Mvc way. So, questions are:

1) How should one model shared functionality across views.
2) On viewdata--I can see this having some application-specific stuff as well as some view management stuff. How should one attack this?

For the record, the app in question is a completely custom aspnetmvc CMS system. Well, half-mvc at least; admin tools will likely be webforms.

My first suggestion is to go to the link below and download the file I listed. This is the source for MVC. You can learn a lot just by looking it over.

I would say this though. Subsclassing ViewPage is a bit more involved than some of the classes. There is also the ViewPage(Of TModel) to worry about, and subsclassing that causes problems with 'Context not a member of...' errors on pages that inherit from that, like the Error.aspx page that comes with the package.

You can of course extend mvc.controller if you'd like, since that's where most of your active code will be. You really want to keep as much code out of the view as possible, save for some simple collection looping and things like that.

One of the things I've saw related to MVC and liked a lot was the "Html Helpers" when combined with lambda expression, and to be able to define your form from the model.

Code Csharp:

Html.InputFor(m => m.Name)// Name being a string outputs regular input field with length restrictions and so on.
Html.InputFor(m => m.DataOfBirth)// DataOfBirth being a date outputs a Calendar UI wiget.

What I'm looking at now is how to keep the controller action clean, with focus on the action it self and move all the other suff you have to show in the view out of the controller action.

dhtmlgod... you mentioned action filters... aren't these used has attributes? Is there another way to attatch them?

Thanks. Not sure how reviewing the source is going to help with a more philosophical architecture question; I'm not trying to rewrite the controller system, just avoid repetition and centralize functionality in the view engine.

The HTML helpers look neat. Still not a huge fan of extension methods, really feels like monkeypatching to me.

The big drawback I see with the reliance upon attributes for alot of things is that you must know many things at compile time. So stuff like making these filters configuration driven isn't easy without a little voodoo.

IE:

Code:

[OutputCacheFilter(Duration = ConfigRepository.GetConfig().CacheTime)]
public ActionResult PenguinsSuck()
{
//Prove how the Pittsburg Penguins do suck, and that Sidney Crosby tortures small furry animals for fun
}

Won't work because the compiler can't really resolve the configuration driven bit at compile time. And I really don't think adjusting the cache times on an app should be something that requires a developer, a recompile and a redeploy.

1) How should one model shared functionality across views.
2) On viewdata--I can see this having some application-specific stuff as well as some view management stuff. How should one attack this?

1) We use IPresentationModel<ViewModel> and anything that is shared across views are properties on IPresentationModel. We attach anything we need to that using ActionFlters

2) I would strongly recommend not using ViewDat["string"]. Magic strings can quickly become a pain and have poor refactoring support. Using a combination of IPresentation and ViewMode, we always send everything to the view strongly typed.

Oh, I definitely agree on magic strings. I'm in the lunatic fringe that uses constants for nearly anything possible. And that is if I'm too lazy to write up a strongly-typed config section <g>.

That approach is awesome. I was looking at Nerd Dinner when you wrote it, and I hit upon the concepts of making ViewModel wrapper classes. But wrapping the whole thing in an interface makes a whole lotta sense.

Next question--how would one go about dynamically changing MasterPages? We have some scenarios where this would make alot of sense. Or at least this *sort* of capability would make alot of sense.

One of the things I've saw related to MVC and liked a lot was the "Html Helpers" when combined with lambda expression, and to be able to define your form from the model.

Code Csharp:

Html.InputFor(m => m.Name)// Name being a string outputs regular input field with length restrictions and so on.
Html.InputFor(m => m.DataOfBirth)// DataOfBirth being a date outputs a Calendar UI wiget.

What I'm looking at now is how to keep the controller action clean, with focus on the action it self and move all the other suff you have to show in the view out of the controller action.

dhtmlgod... you mentioned action filters... aren't these used has attributes? Is there another way to attatch them?

How do you test this behavior?

Last thing... Resharper rocks (no affiliation... just happy customer)

cheers,
Rui

Extension methods are the way to go with UI stuff. We use and have extended the FluentHtml that comes with MvcContrib.

We don't have any if statements or foreach loops in our views. We remove if statements bu having one view model for each view, with the view model type deciding the view. UserRegsterModel will always result in a UserRegisterModelView.

To get around foreach loops, we do this:

Code Csharp:

<%this.RenderEach(m => m.Navigation);%>

RenderEach will use the Navigation type (say NavigationModel) to render a user controler called NavigationModelView for each item.

We also don't use ActionFilters as attributes. We use an internal Dsl to configure out application and resolve the filters through our container transparently. To do this, I have started an open source project called FluentMvc that allows use to do this:

This allows us to centralise our filter configuration and use dependency injection in our filters and develop them using TDD like any other class. We also overcome the other limitations of attributes.

This with a combination of an external Dsl for Castle in the form of Binsor means we can change injected dependencies (like cache duration, etc.) without having to recompile and deal with Xml hell

Although we use FluentMvc in production, I wouldn't say it was production ready, but you can get the source here: http://code.google.com/p/fluentmvc/ It needs a large refactoring, but it will deliver the above no problem, but you need to add a class to your project to work with Windsor. I am considering using the CommonServiceLocator to abstract the IoC container out instead of our own interface.

That approach is awesome. I was looking at Nerd Dinner when you wrote it, and I hit upon the concepts of making ViewModel wrapper classes. But wrapping the whole thing in an interface makes a whole lotta sense.

I highly recommend checking out AutoMapper, it really helps with the pain of mapping between your entity and view model.

Originally Posted by wwb_99

Next question--how would one go about dynamically changing MasterPages? We have some scenarios where this would make alot of sense. Or at least this *sort* of capability would make alot of sense.

Your own viewengine would be the way to go for this. You could prolly take the quick and dirty viewengine I posted and add it there.

Check out Oxite for a good example of how to write an Mvx application, it blows Nerd Dinner out of the water and they have taken a lot of input from the community about the direction they should take. And use alot of th stuff I've mentioned

I just want to make the point that to a hardcore WebForms guy, Mvc is in some ways going to feel like a step backwards. No user controllers, less in the box, more code, etc. But from a SoC and testibility POV, it's amazing, and as an old ASP head, I love having 100% control of the UI again

While I like MVC I have to say I took 100% control of the UI a long time ago. Repeater instead of gridview, not using other controls like the link button or any control that outputs bad html/inline javascript, avoiding asp.net ajax and the control toolkit at all costs. Building a site that that works without script and adding unobtrusive script on top. Aside from MVC I like the routing stuff a lot which allows you to do the same friendly urls in a non-mvc app. Now if hosting companies could all just move to IIS7.

wwb, master pages can be changes using the View() function as is, as far as I know. It has several overloads, one of which takes two params, the view and the master to load with it. It works.

One thing I'm having a problem with at the moment is localization at the web.config level. I have my own view engine that works locale and theme into the url ({locale}/{theme}/{controller}/{action}/{id}) and restructured my View folder to suit. I then stuck a web.config with <globalization uiCulture="? culture="?" /> in it within the theme folder. It's supposed to set the culture for the aspx pages under it so I don't have to update each and every aspx files @Page directives. It's still falling back to the locale.resx rather than using the locale specific ones (locale.en.resx, locale.en-US.resx, locale.en-CA.resx etc).

I highly recommend checking out AutoMapper, it really helps with the pain of mapping between your entity and view model.

Your own viewengine would be the way to go for this. You could prolly take the quick and dirty viewengine I posted and add it there.

Just tried AutoMapper. I'd be willing to argue that it actually is the best thing since sliced bread at the moment.

Check out Oxite for a good example of how to write an Mvx application, it blows Nerd Dinner out of the water and they have taken a lot of input from the community about the direction they should take. And use alot of th stuff I've mentioned

Definitely a step beyond NerdDinner, and lots of good stuff. Really a bit much for a first serious dive into MVC--so much going on, and the downloadable source package won't even build. Would be really awesome if someone [who doesn't work for MSFT] could put together a NerdDinner-scale demo app showing the "community" ways, etc.

I just want to make the point that to a hardcore WebForms guy, Mvc is in some ways going to feel like a step backwards. No user controllers, less in the box, more code, etc. But from a SoC and testibility POV, it's amazing, and as an old ASP head, I love having 100% control of the UI again

I, like Brian, am a naked databinding and literals type of guy. That and lots of user controls. If you knew what you were doing, you could keep pretty effective control of the html in web forms land.

And Url Routing solves another major issue. Really feels like a sideways step to me to some extent. There are definitely things I miss about web forms, especially since I had so much seat time with them. In fact, on the current project, I'm really still debating using web forms for the admin half of the app and then MVC for the public facing bits. You loose a bit of testability at the top of the stack, but if you keep discipline in said forms, you can still have a pretty solid coverage. That said, doing it all in MVC makes alot of sense as well from a patterns perspective.

The big problems I'm trying to solve via MVC basically revolve around giving the html types a bit more leeway to do more interactive stuff. No way they could hang with web forms, but all the dinky little "this is how you post an ajax form using jquery" tutorials work well with MVC.

wwb, master pages can be changes using the View() function as is, as far as I know. It has several overloads, one of which takes two params, the view and the master to load with it. It works.

One thing I'm having a problem with at the moment is localization at the web.config level. I have my own view engine that works locale and theme into the url ({locale}/{theme}/{controller}/{action}/{id}) and restructured my View folder to suit. I then stuck a web.config with <globalization uiCulture="? culture="?" /> in it within the theme folder. It's supposed to set the culture for the aspx pages under it so I don't have to update each and every aspx files @Page directives. It's still falling back to the locale.resx rather than using the locale specific ones (locale.en.resx, locale.en-US.resx, locale.en-CA.resx etc).

Ideas?

Thanks, I missed that overload. Could come in handy for some stuff. Otoh, architecturally, pushing such functions into a custom view engine probably is a better long-term solution. Keep controllers lean and services fat. As for your question, not sure and honestly I rarely have to deal with localization here. I'd guess that the Url Routing and general funkschwea of ASP.NET Mvc breaks alot of the <location> based bits of ASP.NET. Also, I think it might make more sense to incorporate that key bit into your presentation model data rather than relying upon configuration. It's much more testable that way.

Now for the dumb questions portion of this program:

1) Query string parameters: how should one deal with them, especially optional stuff. I did a bit of searching and didn't find any good nor extant examples on the intertron. For the simple "one optional parameter" scenario, I landed upon using controllers with method signatures like:

Code:

public ActionResult List(int? groupingConstructId)

But what about fun scenarios where you have a half-dozen or more potential optional parameters?

2) Are there any good guides to writing tests for controllers that test the HTTP bits. For example, I'd really like to assure myself that all my controller actions are responding to the right HTTP verbs and requesting authorization as appropriate and such.

3) Kind of 2a here, but are there any guides to make the model data go "through the lifecycle." IE--my tests now call the ModelState.IsValid property, but it is pretty apparent that ModelState isn't getting built so it is always valid.

1) Query string parameters: how should one deal with them, especially optional stuff. I did a bit of searching and didn't find any good nor extant examples on the intertron. For the simple "one optional parameter" scenario, I landed upon using controllers with method signatures like:

If I have an action that takes more than 2 parameters, I will change that to a parameter object, which makes dealing with optionals alot easier

2) Are there any good guides to writing tests for controllers that test the HTTP bits. For example, I'd really like to assure myself that all my controller actions are responding to the right HTTP verbs and requesting authorization as appropriate and such.

My guideline is that a controller should not know about Http. The abstractions on System.Web.Abstractions, IMO, don't go far enough. I prefer to add abstractions over any http stuff. I find this easier to work with and test. While it does mean a more classes, they are usually thin delegating wrappers. Things like authorization and HTTP verbs are applied with ActionFilters and as attributes with an OOB version. From a testing perpective, you just want to ensure that the attribute is present. When we used attribute based filter, we used a little extension method that uses from reflection thats tests a certain attribute is present.

3) Kind of 2a here, but are there any guides to make the model data go "through the lifecycle." IE--my tests now call the ModelState.IsValid property, but it is pretty apparent that ModelState isn't getting built so it is always valid.

Adding a errror using controllerinstance.ModelState.AddModelError() will cause the ModelState to become invalid (lets just ignore that poor design choice here) and causees the IsValid property to become false.

4) How are the cool kids doing validation these days anyhow?

We use Castle validators with xVal. We attribute our view model like this:

The end result is that jQuery validation is automatically added on the client, and the ModelState is automatically filled by the time you hit your controller action. It also works with Data Annotations that was added with .NET 3.5, but I've never used them.