Does the concept of a Control make sense in MVC? - asp.net-mvc

I've started using MVC reccently, and one thing that occurs to me is whether its possible for the concept of a Control to exist in MVC?
From what I see the framework allows the application to be nicely factored into Models, Views and Controllers, but I can't think of a nice way to take a "vertical slice" of that application and reuse it in another application.
What I mean by that is it strikes me that any UI components I build with MVC maybe not very amenable to reuse, in the same way you can reuse a Contol in ASP.NET WebForms. Ok, there are HTML Helpers but I am thinking of something more modular. Something more like the control model in WPF.
Does this dichotomy go to the heart of MVC vs WebForms, or can reusable UI components work in an MVC world?

You can still use ascx files and other features in ASP.NET Web Forms. The only missing piece in MVC is the postback model and view state oriented state management. There is no <form runat="server"> anymore and no automatically generated hidden fields. Except these, all other features can be used in ASP.NET MVC. You can still write controls that post data using a REST based mechanism and use them in your views.
So, yes, as long as your controls don't rely on a server side form for postback, you can use them exactly the same way you'd use in ASP.NET Web Forms.

I was looking for the same thing - for reusable widgets with their own data paths and found this on Steve Sanderson's Blog:
http://blog.codeville.net/2008/10/14/partial-requests-in-aspnet-mvc/
From the article:
"You’ve heard of partial views, so how about partial requests? Within any MVC request, you can set up a collection of internal partial requests, each of which can set up its own internal partial requests and so on. Each partial request renders a plain old action method in any of your plain regular controllers, and each can produce an independent widget."
This article respectfully offers a alternative to The MVC Contrib Group's Sub Controller strategy (http://www.mvccontrib.org/) which is also a solution for what you are looking for.

I guess its harder in MVC to completely encapsulate rendering and post back handling in a single control you just drop on a page. It some ways this is because ASP.NET Webforms is very abstracted from HTTP semantics and that abstraction is a framework where its possible to create reusable user controls.
ASP.NET MVC doesn't have the abstraction of webforms so you can have a control the posts to three different controllers. While it may feel like your losing easy to use controls when you move to ASP.NET MVC, I think you have a better framework for separating and reusing domain logic.
In ASP.NET MVC you have partial views which can be reused. Rob Conery has a good post on this: ASP.NET MVC: Using UserControls Usefully

I think the closest thing you'll get to an old school controls are partial views, these are effectively just shared markup that you can drop on any page. However they don't have their own controllers out of the box so the code to power the shared UI component (the partial view) would need to exist in the controller of every page that used it. There are ways to reduce the duplication of code but without implementing partial view controllers and binding I don't think there is a way around it completely.

Related

are you still creating complex user controls in asp.net MVC?

Is there a new model or best-practise for creating complex controls in asp.net MVC?
Do you use code-behind or inline to mirror your view pages?
My model is this:
I tend to use Partial Views when there is a view element that I'll need to use more than once. Or if I need to display multiple complex object in a view.
I use RenderAction from the futures assembly when I need a "reusable widget" of sorts. It has it's own controller and is better at handling more complex logic than a Partial View.
Finally, I tend to write Html Helper methods for things I may use in other projects (like paging links, etc).
I would use a partial view for complex things. Check out this article
Controls in MVC don't generally have (any) code behind. You use PartialViews as ascx controls, you pass them a model and you display the contents of the model.
You can create custom controls in mvc and these compile to a dll which is moveable between projects etc and these are a little more complex but essentially they spit out html like the partial view does.
You can also create jQuery plugins that are pretty cool and again, they can spit out html based on a model.
So a typical mvc view may be comprised of several partial views each of which are dedicated to a model or hierarchy of models.
Partial views can also display partial views so you can send a complex model to a partial view which in turn renders other partial views each of which deal with a more atomic part of your model.
I've been writing a lot of my own HtmlHelper extension functions. The November meeting of http://www.c4mvc.net/ that was recorded today gives some great examples of control type code placed in HtmlHelper extension functions. The recording should be online soon.
You may also want to check out the Telerik Extensions for ASP.NET MVC. They're open source, so even if you don't use their controls, you can get some insight into controls in ASP.NET MVC by taking a look at how a commercial control vendor approached the problem.
Coming from a PHP turned webforms turned ASP.NET MVC background, I find myself relying a lot more on basic html/css/javascript.
I've never been a fan of controls, even with webforms because they always ended up being messy compared to js/html/css counterparts.

Using Code-Behind with ASP.NET MVC Views

Is it considered a bad practice to use code-behind with ASP.NET MVC Views? Got into a bit of a debate about this with my colleagues today and I was wondering the community's thoughts.
Obviously, this isn't an option when using another MVC like Rails, which makes me think it's relied on more as a crutch for those accustom to working with traditional ASP.NET Web Forms applications.
I would say that it's a bad practice to use code-behinds with ASP.NET MVC. MVC allows separation of concern where presentation logic (in Views) are separated from application logic (in Controllers). Using code-behinds will mix presentation logic and application logic inside the code-behinds, whereby defeating some of the benefits of MVC.
Certainly the authors of ASP.NET MVC In Action advise against it, and I agree. It isn't necessary, so why do it? In the early betas a code-behind file was included, but this was removed at RTM (or shortly before).
Typically, it simply encourages you to do more non-view work than you should in the view, as it is out of sight / out of mind.
I used code-behind extensively on my first ASP.NET MVC (Preview 3!) project - primarily for doing stuff like casting ViewData["foo"] into strongly-typed data objects, gathering view data into IEnumerables so I could loop across it, that kind of thing.
With the introduction of strongly-typed views, and pragmatic use of the (horrifically-named) Model-View-ViewModel pattern, I haven't missed code-behind at all since it was removed from the project framework just before the final release.
I now strongly feel that whatever processing you're doing in your view's code-behind, you are far better off modelling the result of that processing in your ViewModel, allowing the controller to perform the actual processing, and keep the view as simple and lightweight as you can. That'll let you test the processing logic, it makes the views easier to modify, and creates - I think - a much more elegant separation between transforming your data for display, and actually displaying it.
Yes the codebehind has long been the secret hiding place of business logic which as we all know should not be at the View level.
Code behind has been removed to stop naughty developers from being tempted.
I would recommend avoiding the codebehind in an MVC app at all costs. Using the code behind negates some of the values you get by using the MVC Framework such as separation of concerns, etc. You want to have your data access, business rules, type conversion and that sort of thing applied in the Model. If you find you need to convert your data types like Dylan mentioned, you may want to make ViewModels. The ViewModel would basically be the data from the actual Model you would like to display, in the format you wish to display it in.
Its probably best to avoid putting anything in the code behind when using MVC.
I would be interested to hear which part was being debated about, to go in the codebehind?
If you new to Asp.Net MVC, I really recommend spending some time going through the Nerd dinner example. There's a free EBook and source available here http://nerddinner.codeplex.com/.
Creating the simple demo from scratch is a great way to learn.
After doing this, it may shed some light on where the code you have in the codebehind, could alternatively go.
Note: If you do follow the EBook, grab the latest site.css file from codeplex, otherwise the virtual earth maps won't be aligned properly.
HTH
Ralph
It should be noted that "Code Behind" is a feature of the Web Forms view engine. It really has nothing to do with ASP.NET MVC itself.
For example, the Razor view engine in MVC3 does not even support it.
I would answer your question this way: If you cannot switch view engines without rewriting your controllers (or even your models) then you are not using the MVC pattern correctly.
Probably most of what you are doing in the .aspx.cs file should really be done before the model (or View Model) gets passed to the view. That said, in projects that I have migrated from ASP.NET Web Forms to ASP.NET MVC, I left a lot of the Code Behind in place. For example, I find it cleaner and more pleasing to use a Repeater control than to try to use a 'for' loop in Web Forms. I am still just iterating over View Model data after all. So why not? Separation of concerns is preserved (perhaps to a greater degree in fact).
I mean, why should "best practice" for Web Forms suddenly be the wrong way to do a Web Forms View? As a simple example, consider a Repeater that assigns a different CSS class to every second row of a table. Why should my controller (or even my model) care? Trying to put this kind of logic inline in Web Forms quickly devolves into tag soup and complete spaghetti. Now imagine something more complicated.
I have left Master pages in place that build the menus in the code behind. Again, all data comes from the View Model. I do not see why using GridView or other controls in this way should be a problem either.
I usually disabled ViewState in Web Forms anyway and did the data binding in "Init". Still, there would often be a small ViewState that I could not get rid of. I put some code in "Render" that moves this to after the form (it defaults to before). When moving to MVC, I sometimes left this code in. So, I have ASP.MVC sites that do indeed use Code Behind. I am just careful that it code that is specific to the view.
On new projects, I generally have found less of a need for Code Behind on most pages. Thankfully, view engines like Razor have made mixing code and mark-up in-line a lot less painful to write, read, and maintain.

What place for server controls in ASP.Net MVC?

What is the recommended replacement of ASP.Net server controls in the bright new world of ASP.Net MVC?
In my opinion, one of the best features of ASP.Net is the ability to write server controls (although, admittedly, the event model is horrendous to deal with). If these controls are self-populating, then they can be shared between different projects with the minimum of fuss - you simply reference the assembly where the server control lives, and drop it on to the aspx. The control does the rest. This fits very nicely in the World of Widgets and provides efficient code reuse. How is one meant to achieve the same thing in MVC?
I am most interested in self-populating controls that do not post back, as I appreciate that the postback model definitely does not fit with MVC. Can they still be encapsulated in a class that can be shared between a number of different MVC web projects? Or does this require a whole different mindset where controls shouldn't populate themselves, and one should use partial views? Is there a way of sharing partial views between projects?
Finally, can I use my old (non-postback) server controls, in an MVC projects?
You can mimic the behavior of non-post back controls with Html helper extension methods. Just like Html.TextBox(), etc, you can write your own and encapsulate them in their own project if you like.
If you've written controls that just output HTML, it shouldn't be that hard to convert them to Html helpers.
The closest Asp.Net MVC comes to server controls is partial requests. In a partial request an MVC action method is called, and its output is appended to the current view. Unfortunately, the official support for this (Html.RenderAction) is in the futures assembly at the moment.
If using the futures assembly is not possible for you, a blogger named Steve Sanderson has written an article on implementing similar functionality:
http://blog.codeville.net/2008/10/14/partial-requests-in-aspnet-mvc/

What Is ASP.Net MVC?

When I first heard about StackOverflow, and heard that it was being built in ASP.Net MVC, I was a little confused. I thought ASP.Net was always an example of an MVC architecture. You have the .aspx page that provides the view, the .aspx.vb page that provides the controller, and you can create another class to be the model. The process for using MVC in ASP.Net is described in this Microsoft article.
So my question is. What Does ASP.Net MVC provide that you wouldn't be able to do with regular ASP.Net (even as far back as ASP.Net 1.1)? It is just fancy URLs? Is it just for bragging rights for MS to be able to compare themselves with new technologies like Ruby On Rails, and say, "We can do that too"? Is there something more that ASP.Net MVC actually provides, rather than a couple extra templates in the File->New menu?
I'm probably sounding really skeptical and negative right now, so I'll just stop. But I really want to know what ASP.Net MVC actually provides. Also, if anybody can tell me why it's Model-View-Controller and not in order of the layers of View-Controller-Model or Model-Control-View depending on whether you are going top to bottom, or vice versa, I'd really appreciate that too.
EDIT
Also, it's probably worth pointing out that I've never really cared for the web forms (AKA server controls) model either. I've only used it minimally, and never on the job.
.aspx doesn't fulfill the MVC pattern because the aspx page (the 'view') is called before the code behind (the 'controller').
This means that the controller has a 'hard dependency' on the view, which is very much against MVC principles.
One of the core benefits of MVC is that it allows you to test your controller (which contains a lot of logic) without instantiating a real view. You simply can't do this in the .aspx world.
Testing the controller all by itself is much faster than having to instantiate an entire asp.net pipeline (application, request, response, view state, session state etc).
Scott Guthrie explained it in this post "ASP.NET MVC Framework"
It enables clean separation of concerns, testability, and TDD by
default. All core contracts within
the MVC framework are interface based
and easily mockable (it includes
interface based
IHttpRequest/IHttpResponse
intrinsics). You can unit test the
application without having to run the
Controllers within an ASP.NET process
(making unit testing fast). You can
use any unit testing framework you
want to-do this testing (including
NUnit, MBUnit, MS Test, etc).
It is highly extensible and pluggable. Everything in the MVC
framework is designed so that it can
be easily replaced/customized (for
example: you can optionally plug-in
your own view engine, routing policy,
parameter serialization, etc). It
also supports using existing
dependency injection and IOC container
models (Windsor, Spring.Net,
NHibernate, etc).
It includes a very powerful URL mapping component that enables you to
build applications with clean URLs.
URLs do not need to have extensions
within them, and are designed to
easily support SEO and REST-friendly
naming patterns. For example, I could
easily map the /products/edit/4 URL to
the "Edit" action of the
ProductsController class in my project
above, or map the
/Blogs/scottgu/10-10-2007/SomeTopic/
URL to a "DisplayPost" action of a
BlogEngineController class.
The MVC framework supports using the existing ASP.NET .ASPX, .ASCX, and
.Master markup files as "view
templates" (meaning you can easily use
existing ASP.NET features like nested
master pages, <%= %> snippets,
declarative server controls,
templates, data-binding, localization,
etc). It does not, however, use the
existing post-back model for
interactions back to the server.
Instead, you'll route all end-user
interactions to a Controller class
instead - which helps ensure clean
separation of concerns and testability
(it also means no viewstate or page
lifecycle with MVC based views).
The ASP.NET MVC framework fully supports existing ASP.NET features
like forms/windows authentication, URL
authorization, membership/roles,
output and data caching,
session/profile state management,
health monitoring, configuration
system, the provider architecture,
etc.
Primarily, it makes it very easy to create testable websites with well defined separations of responsibility. Its also much easier to create valid XHTML UIs using the new MVC framework.
I've used the 2nd CTP (I think they're on five now) to start work on a website and, having created a few web applications before, I have to say its hundreds of times better than using the server control model.
Server controls are fine when you don't know what you're doing. As you start to learn about how web applications should function, you start fighting them. Eventually, you have to write your own to get past the shortcomings of current controls. Its at this point where the MVC starts to shine. And that's not even considering the testability of your website...
No more auto-generated html IDs!!! Anyone doing any sort of javascript appreciates this fact.
ASP.Net with it's code behind is almost MVC - but not - the one big thing that makes it not is that the codebehinds are tied directly to the aspx's - which is a big component of MVC. If you are thinking of the codebehinds as the controller - the should be completely decoupled from the view. The new .NET MVC rounds this out - and brings a complete MVC framework. Though there are existing ones for .NET already (see Spring.NET).
I looked through a couple simple examples such as this one. I can kind of see the difference. However, I don't really see how MVC uncouples the view from the controller. The view still references stuff that's in the controller. I do see how it makes it much easier to test, and that at least in MVC the controller doesn't have any knowledge of the view. And you wouldn't have to process the view to call methods in the controller. I can see that's quite a leap, even though at first glance it may not seem like much.
I do agree with #Will about fighting server controls. I've never worked in a situation where they were actually used, but many people I know who have, have run into quite a few limitations with them.
Article about ASP.net MVC Vs ASP.net Web form
http://weblogs.asp.net/shijuvarghese/archive/2008/07/09/asp-net-mvc-vs-asp-net-web-form.aspx

What's the best way to implement user controls in ASP.NET MVC?

Like many others on this site I am considering a move to ASP.NET MVC for future projects. Currently my sites are running the traditional ASP.NET 2.0 Web Forms, and it works OK for us, so my other option is just to stick with what I know and make the move to ASP.NET 3.5 with the integrated AJAX stuff.
I'm wondering about how user controls work in ASP.NET MVC. We have tons of .ASCX controls, and a few composite controls. When I work with web designers it is very easy to get them to use ASCX controls effectively, even without any programming knowledge, so that's a definite plus. But then of course the downsides are the page life cycle, which can be maddening, and the fact that ASCX controls are hard to share between different projects. Composite controls are share-able, but basically a black box to a designer.
What's the model in ASP.NET MVC? Is there a way to create controls that solves the problems we've dealt with using ASCX and composite controls? Allowing easy access for web designers without having to worry about code being broken is an important consideration.
To implement a user control you do the following call:
<% Html.RenderPartial("~/Views/Shared/MyControl.ascx", {data model object}) %>
You may also see the older syntax which as of PR5 is not valid anymore
<%= Html.RenderUserControl("~/Views/Shared/MyControl.ascx", {data model object}) %>
You will always have to worry about code breaking when moving from Web Forms to MVC, however the ASP.NET MVC team has done a great job to minimize the problems.
As Nick suggested, you will indeed be able to render your user controls, but obviously the page-cycle, pagestate and postback from traditional ASP Webforms won't work anymore, thus making your controls most likely useless.
I think you'll have to rewrite most of your complex controls to port your website to MVC, while simple controls which, for instance, provide only formatting and have no postback status, should simply work.
The code provided by Nick will simply work in this case.
And about sharing between more projects: I think controls will be more like "reusable HTML-rendering components" that can be shared across a website, rather than "reusable code components" with logic (like WebForms controls). Your web logic will/should be in the pages controllers and not in the HTML controls. Therefore sharing controls across more projects won't be so useful as in the WebForms case.
MVC has different page life cycle compare to your user control.
You may consider this to re-write.
The aspx is the view. You still need a re-write, the syntax is different.
JavaScript will work. But I hardly find the WebControls will work. Because MVC does not have viewstate and postback anymore.
For the code behind (aspx.cs) you need to convert that to be a Controller class.
Page_Load method will no longer works. You probable leave it to Index() method.
Model is simply the entity classes that your code behind consume.
Conclusion, it's a total rewrite. Cheers. Happy coding.
Yeah, you can do RenderPartial. That's a good start. But eventually these guys will need logic and other controller type stuff. Be on the lookout for a subcontroller implementation from the framework team. There should also be something in MvcContrib soon. Or roll your own.
Edit: I just posted about this here: http://mhinze.com/subcontrollers-in-aspnet-mvc/

Resources