My group is working on a new web application and is considering using MVC. However, there are members who would rather include pages than use master pages. Is this possible to do in ASP.NET MVC? In the small amount of time that I've poked around with MVC I have not yet been able to figure out how one might accomplish that.
Why the preference?
Having used both in the past, Master Pages are much easier to use. You just have to get over the (very small) learning curve.
ASP.NET MVC doesn't force you to do either one though...
If you like the Include method, then you would probably feel most comfortable using Partial Views to provide the same functionality. You would just add the Partial Views to each page instead of including another page.
No. It does not force you in any way.
You should really avoid server-side includes with anything newer than classic ASP. They're more difficult to debug, IIS has a hard time finding correct line numbers when there's a problem, etc. Also, I haven't looked at the order in which SSIs are processed in the request pipeline - they may not work at all with ASP.NET.
If you're moving into MVC, use RenderPartial() or RenderAction() instead. These perform essentially the same function as a server-side include, but are more inline with the spirit of the framework and provide some additional benefits, like passing models without having to declare a global variable (which should also be avoided, and I'm not sure if it is even possible under .NET scope rules).
And, no, master pages are not required, but you really should use them. Using includes to build your page layout works, but only if you don't and won't need to radically change the layout of your site at any point in the future. I'm in that boat now with a 350k line classic ASP app which used very nicely structured code and #includes to create the page layout. That was the best solution available at the time, but it's causing me a lot of headaches now (10+ years later).
With a master page you can move your ContentPlaceHolder blocks anywhere you want, whereas with #includes the final page really determines the format by the order in which the includes are placed. This also makes it pretty straightforward to create a mobile version of your site - you can create a mobile-specific master page and use the same content views.
Its a matter of choice,but for consistent look and feel across the web application, master pages give you just that. You have to take the team through the learning curve of good master page design, not only would it be useful for the current project at hand but also future projects. Good luck!
I would rather opt to go for Master pages due to the ease of use and built in support in MVC for this.
If you want to know more about it check out this tutorial: Creating Page Layouts with View Master Pages.
Grz, Kris.
Related
I have a large asp.net-mvc web site . I recently upgraded to MVC 4 but one thing i am debating is it worth it to migrate to razor engine. I see there are tools to "auto" upgrade but i am trying to figure out if its worth the migration pain. I have about 100 total view (both regular and partial). If its a code base that i will have to live with for a while, is it worth the effort?
I know this may seem a bit subjective but given the size of my project I was looking for the expected cost of this migration effort versus the expected benefits.
Unless you have a specific reason, then IMHO no. Razor is a little, tiny bit (~5% according to most sources) slower than WebForms views however this may be old information. At best, they will render exactly the same speed. I have seen nothing to suggest razor is faster at rendering than webforms(ASP.NET MVC 3 Razor performance) and offers absolutely nothing additional that you cannot do with the WebForms markup.
Basically, its a more succinct markup language and can be a quicker to write and looks better than WebForms syntax. Lastly, if you organization has a legacy of writing WebForms code from back in the day, then all of the developers are already familiar with the WebForms syntax. No learning curve.
So - should you rewrite an entire application? No - you gain nothing. Going forward, should you use Razor? Depends, most 'seem' to be moving that way, it does look nicer and keeps the views a little cleaner.
If, however, you do decide to begin to update your views to razor, remember you can do this in steps. The ViewEngine will look for both types of views when determining what view to render. This does not have to be done in one fell swoop, but could be done gradually over time.
PS - This will probably be closed as a subjective question soon.
No, not unless you have a really compelling reason to.
The only real difference is the syntax on the views is a bit neater and there is an inherent "cool" factor working with a different view engine.
When razor first came out, we implemented a bit of a mixture, and so we're currently running a site with both razor and webforms views (this was implemented before razor became the default mvc viewengine).
We have written all new views in razor, and left the older views in webforms which we're slowly migrating across. But its for our benefit, not the customers or end users. So to migrate only the views across is a costly, timely affair that serves no real purpose...
If you've layered your app properly, what I would suggest (seriously) if you were looking at undertaking this, is to leave your existing website alone and create a separate stand alone site, using the new mvc infrastructure. There are definite gains from upgrading the site from an mvc 1 or 2 app to a new mvc 5 app.
We're currently doing this at my place of work, as our models, and logic are all in standalone dll' and we have very thin controllers. We're noticing a lot of changes and updates from the new mvc5 features that are now built in. Things like bundling, twitter-bootstrap etc are all things that we can use to ensure benefits that the customer notices.
Its the same old backend, but a shiny new face and thats worth doing.
I think your question is answered in past, if your objectives match with new features you should opt for upgrade, like mobile site support and more..
Old Post
this post gives details of MVC4 Release Notes and difference b/w MVC3 and MVC4 this both answer in this post will help you decide.
The MVC 4 improve those features(main points):
Refreshed and modernized default project templates
New mobile project template
Many new features to support mobile apps
Recipes to customize code generation
Enhanced support for asynchronous methods
For more details on MVC4, you can refer to: http://www.asp.net/mvc/mvc4
Edit: as the question is View specific,
The views works in the same manner in both version without any change,
you can try removing unwanted view engines
protected void Application_Start()
{
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new RazorViewEngine());
}
If you want rendering improvement, you must use the Partial View
<div class="news">
<h3>News</h3>
#Html.Partila("NewControl", Model.NewsItems)
</div>
Code Part:
public ActionResult News(){
NewItemViewModel vm = new NewItemViewModel();
vm.Items = repository.GetNews();
return PartialView("NewsControl",vm);
}
This will make the normal speed go increase by 10x
make sure the views are not combines and not passing any null models in view.
This should help in the performance issue.
If you'd ask me, since I've started using Razor, I'd never look back to the regular ASPX view engine. If you want to introduce fresh flavor to your application and the developers don't mind using the new Razor syntax (which is simpler and cleaner), go for it. If everyone is skeptical about that and application is doing well as it is, do not migrate. Since this question is inviting a personal comment, my opinion goes along with this, which (despite the fact Razor now seems to be negligibly slower than the equivalent ASPX) is obviously saying - migrate me, now.
Just to prefix this question, I've decided to take a look at moving our works old legacy systems (40+ programs from vb6, vba, vb.net to c#.net) into two separate systems using the same DAL (barcoding terminals and one web based system) as I spend most my day fixing crummy or non existant business logic in 15 year old vba programs. I've recently built an entity framework model complete with fluent validation and couldn't be happier with it after using it for a bit.
The small team is familiar with webforms (but not very) but the last few days I've explored MVC Razor. I was loving MVC Framework until I tried to start trying to add more functions onto the same page and then it seemed arbitrarily hard to replicate our a recent system I put in a webform. Before, I would eager load a customer and all it's child entities and then bind that to single page for the customer so they could access everything (which is what they wanted), it works okay and isn't slow. From this single page I could edit all their account details/contacts/emails/phones/jobs.
All the examples I've done and seen in MVC handle a single update, a single edit etc but surely you can't separate out every single action into a new view/page? I can pass a rich model through to the view in MVC, but then its a pain trying to update all the different child entities.
This is probably the exact design that MVC wasn't designed for maybe, which is okay, I'm willing to adapt it if MVC will be a better platform going forward, but how are you meant to handle adding this complexity in? Some methods I've seen:
Lots of partial views? passing child info to them (or the id and lazy loading it)?
I've seen methods that wrap multiple <forms> around everything and handle actions that way.
Separate pretty much every task out
If the solution is more lightweight and easier to maintain I'll go research whatever I need to I just wanted at an earlier stage to see if I'm wasting my time. Any pointers to the correct questions I should be asking would be greatly appreciated.
ASP.NET MVC is neither more or less better equipped to deal with complex pages than any other technology out there.
Certainly, MVC requires more low-level work than a Web Forms app, with no direct binding support, but in most cases this is a good thing and provides much more flexibility in how your page is rendered.
One of the whole ideas of MVC is to give you more control over things, but that control leads to requiring more knowledge and more effort on your part in most non-trivial cases. MVC provides a number of tooling functions to speed up trivial work (like creating standard table based CRUD) but when you have complex models, you will have to do much of the work yourself.
This is not that MVC is "ill suited" for it, but just that control and flexibility has a trade off with more responsibility on your part.
In your case, you simply create a view model with all the fields you want. Then, you create your form to edit those fields. In your controller, you will need to unflatten that view model and create or update the necessary records in the database. It's not difficult, but it's more work than WebForms databinding.
You could look into more advanced tools (commercial) for MVC, such as Telerik's tools, which have developed more of a databinding like interface, but MVC is not a drag-n-drop technology, and requires you to hook things up and write the various logic for what is done.
If you need drag-n-drop, databound functionality, then no.. MVC is not the correct technology. But then WebForms requires you to accept many compromises as well, and ties your hands in many ways.
You could use partial views, however I seldom use them. I prefer to instead use Editor/DisplayTemplates as these take care of naming your form fields correctly, even for collections and complex objects. PartialViews tend to have lots of gotchas if you aren't careful. I pretty much only use them as fancy includes, or when using Ajax.
I'm not sure what you meay by "wrap multiple <forms> around everything`. You cannot nest forms in HTML, it's not legal. If you mean place a form around each row of a table, that isn't valid html either in most cases (it's not legal to put a form in a between the table and the tr).
It would help if you had a specific problem that you could ask about, vague objections don't help us solve your issue.
You can accomplish anything in MVC that you can in WebForms. The difference is MVC will usually require you to write more code as it doesn't really offer you any "controls" to drop on your page.
In WebForms, it's easy to create a master/detail view with a GridView, FormView and then wrap everything in an UpdatePanel for automagical AJAX support.
In MVC, while you do have helpers like the WebGrid and AjaxHelpers extension methods, creating views and/or pages requires more understanding of how things work to get the desired functionality. When I start a new MVC project, here's what I include:
Backbone.js - client-side "ORM" that performs CRUD operations
against RESTful* APIs
Knockout.js - client-side view models and
real-time data-binding for your views
Knockback.js - wraps
Backbone models in Knockout view models
Using these three frameworks, you can quickly create powerful single-page apps using MVC and WebAPI.
We're building about 10 ASP.NET MVC sites which have a common set of features (and corresponding URLs, Routes, Controllers, Actions, and Views). The sites will also all share a base set of domain objects (e.g. users, companies) and base attributes on those objects (e.g. name, address, etc.).
But each site will also be highly customized and extended from the base. For example, our site for large, public companies will have "Subsidiary" and "Stock Symbol" fields on the Company domain object, while our site for startups will have a "Venture Firm" and and "Funding" attributes. Look and feel will also vary considerably, although we're trying to keep HTML as consistent as possible (modulo extra form fields for extra domain object attributes, etc.). We'll also be overriding images sparingly, so we can, for example, re-use the same button graphics across sites.
Anyway, we're trying to figure out how best to factor and architect things so that we can reuse as much code and as many tests as possible without limiting our freedom to add per-app attributes and vary the UI between apps.
I'm familiar with how to handle limited-customization multi-tenancy like you find in StackOverflow/SuperUser/ServerFault (or MSDN/TechNet for that matter), where the UI is a little different and the data model is more-or-less identical. But when the models and UI are very different (but inherit from a common base), I'm less sure how to proceed.
I'm less worried about operational issues, since we'll probably be running each site in a separate appdomain and hosting them on separate databases. I'm more worried about reducing long-term code maintenance costs, increasing agility (e.g. easy to add new features to the base without breaking derived apps), and realizing short-term dev-/test-cost savings as we build our 2nd, 3rd, 4th, etc. site.
I'm looking both for high-level guidance and suggestions, but also concrete suggestions for how to make that guidance real using modern ASP.NET MVC practices.
I realize this is a very general question, but for starters I'm looking for both high-level guidance as well as concrete tips-n-tricks for how to apply that guidance with ASP.NET MVC, including things like:
recommendations where to split base/derived across Visual Studio projects
source control tips to avoid forking
database schema tips (FWIW, our databases are all small-- under 10K rows per table, so dev/test cost is more of an issue than DB perf)
tips about re-using Controllers/Views/etc. corresponding to the "base" model attributes, especially re-using UI for things like "new customer" forms which will have a mix of base and derived attributes.
Anyone have good advice for how to architect a multi-tenant app like this?
Here's what we do, and it works pretty well for about 8 sites currently.
Define a core MVC project for your Controllers, ViewModels, HttpApplication, routes, etc. This will compile into a DLL and compromise the bulk of your site.
Create a basic set of default views, scripts, images, etc. for your site. These will server as defaults for your individual sites.
Per client, create any custom controllers, routes, etc that you'll need in a project that compiles to another dll.
Also per client, recreate any views, scripts, images that you'll want to use.
To make the above steps work together you'll need to write a little glue. The first piece of glue is a custom view engine. You'll want to customize the standard view engine to first look for views in your client-specific folder, and then the default folder. This lets you easily override the default layout per client.
The second method of getting everything working is to have your core application load the routes, controllers, etc from your client specific assembly. To do this I use the Managed Extensibility Framework (MEF) to expose a single Register method. Calling this method on my client assembly code registers the routes and any other client-specific needs.
Here's a general view of what my site folder structure looks like, with SiteContent being checked for views first:
- AppContent
- AppContent/Static
- AppContent/Static/Images
- AppContent/Static/Scripts
- AppContent/Static/Styles
- AppContent/Views
- AppContent/Views/Shared
- SiteContent
- SiteContent/Static
- SiteContent/Static/Images
- SiteContent/Static/Scripts
- SiteContent/Static/Styles
- SiteContent/Views
- SiteContent/Views/Shared
- web.config
- Global.asax
I have helpers that I can use like SiteImage and AppImage for use in my views. Also, I make each of my client sites use certain specific names for their master pages, that I don't ever define in my AppContent defaults.
I realize this is a rough overview, but it is working well enough for us right now.
I'm involved in a similar type of "suite" of projects currently which is focused on allowing customers to apply for products online but have very similar requirements for what information to collect, where the only differences are around product specific pieces of information or slightly different legislative requirements.
One thing that we have tried to do is create pages (model, view and controller combinations) that are reusable in themselves, so any application can use the page to capture information but redirect to the next page which may be different depending on what type of product is being applied for. To achieve this we are using abstract base controllers in the form of the template method pattern that contain basically all the required controller logic (including action methods with their applied action filters) but then use abstract methods to do the specific stuff such as redirecting to the next page in the process. This means that the concrete implementation of the controller used by specific application page flows may contain only one method which returns a RedirectToActionResult corresponding to the next page in the flow.
There is also quite a bit of other stuff that handles going backwards and those kinds of navigational things, but with the help of action filters you can get it set up that you don't have to worry about it once you get it up and working.
There are also base model objects which contains common functionality, be it validation logic or state persistence logic.
The data captured during the application process is persisted in database as xml serialized model objects which can then be pulled out and de-serialised once the application is completed and spat out in whatever format to whatever system the backend operations staff use to process applications.
The implications of this is that we have a project structure that consists of a base dll that contains top level abstract classes, interfaces and utility classes as well as html helpers, action filters etc. Then we have mvc projects which contain the concrete implementations of the base controllers, models etc as well as the views and masterpages.
The hardest thing is sharing views and I don't think we have properly got this sorted yet. Although with MVC 2.0 containing Areas I think this will become less of an issue but I haven't had a good play with it yet. (see Scott Gu's post on 2.0: http://weblogs.asp.net/scottgu/archive/2009/07/31/asp-net-mvc-v2-preview-1-released.aspx)
One thing I have POCed that looks like it will work is using a base MVC project to contain common views and then extending the default view engine to search that project on the web server when looking for a view to render (which is quite easy to do). Areas though is a far nicer solution.
As for source control, we are using svn and I think you are reasonable in being concerned about branches. It is not something that we have had to deal with yet, but we are probably going to go with git as it seems to make the process of branching and merging much less painful.
Not sure whether this helps you much but I would definitely recommend keep in mind abstract controllers and models, and also look at how you can use html helpers and and partial views to group similar pieces of functionality.
Mike Hadlow goes into good detail on how to accomplish this:
http://mikehadlow.blogspot.com/2008/11/multi-tenancy-part-1-strategy.html
One way to do this is to use branching in a source control system.
The main branch is for the common functionality. You then have a branch for customization and can merge changes out to the customization or back to the main branch.
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 is the best and cleanest way to implement A-B testing in asp.net mvc? That is, when we make new changes to an asp.net mvc web site, we want to test the new html/css/js with a certain subset of visitors (defined on cookie, login id, etc) and then analyze some metrics (page response time, number of pages visited, $$$ in sales, etc) afterwards to measure the level of success of the changes.
I am looking for a clean way to implement a way of choosing what view (html/css/js, etc...) to render using asp.net mvc.
Check out FairlyCertain (http://www.fairtutor.com/fairlycertain/) when you get a chance. It's a .NET A/B library that you can pretty much just drop into your project and start writing tests.
Unlike the Javascript libraries from Google and VisualWebsiteOptimizer, everything happens on the server so you don't suffer any performance, user experience or SEO issues. I've been using it in my stuff for a while now and it works quite well.
There is an A/B testing framework specifically for ASP.NET MVC. This is an open source software I wrote myself when, just like you, didn't find a free tool which works nicely with ASP.NET MVC and doesn't require much setup.
Google Content Experiments? It's a Javascript-based solution that doesn't require anything from your backend.
You include Google's Javascript on your page
The script randomly substitutes elements on your page as defined by your A/B test
Google's site shows you a nice breakdown of the results...
If you are using the spark view engine, you could probably do it with a variation of the theme filter (http://sparkviewengine.com/documentation/viewlocations#Extendingfilepatternswithdescriptorfilters). For each new visitor to the site, determine if you want them to see the existing or new version of the site and set a cookie. Wire up a descriptor filter that looks for the presence of the cookie and modify the view location to look in the folder containing the modified views. If an alternative view exists, the Spark engine will automatically render it in place of the "normal" view, otherwise it will render the normal view.
If you are using the normal WFVE, then the simplest way to manage this would be to define a folder under Views where your view alternatives live. When you want to provide an alternative view, you place it in a location that matches its position within the normal Views folder but rooted at the alternatives folder e.g. to provide an alternative to Views/Users/login.aspx place your new view at Views/Alternative/Users/login.aspx.
With a convention in place for locating your alternative views, you can extend the WebFormViewEngine and overload CreatePartialView / CreateView to inspect some aspect of the ControllerContext to determine whether to render the default or overloaded view and alter the path as appropriate e.g. changing .../Views/Users/login.aspx to .../Views/Alternative/Users/login.aspx.
I suggest you use Display Modes to achieve A/B testing.
But Display Modes just support simple problems by default.
If you already implement Display Modes in some other scenario. You can consider DisplayModeMatrix (just google it). It helps you use Display Modes more efficiency.
https://www.nuget.org/packages/DisplayModeMatrix/
Wth Display Modes you can simply delete/rename views after A/B testing to clean up your project.
I think there isn't a ready to use solution for this and you will have to improvise.
Try to override your current functionality in well defined points without breaking it. Explicitly draw a border where your regular code and A-B testing code lives.
Inversion of control principle might help a lot here too (i.e. - controller factory could provide derived controller instead of original one). For views&partialviews - you could change viewengine so it would try to look for 'MyPartialViewAB.ascx' instead of 'MyPartialView.ascx'.
And it might be a good idea to take a look what performance counters are (in case you haven't).