I'm working on a web application. One of my co-workers has written some asp.net forms pages. The page classes all inherit from BasePageClass, which of course inherits from the Page class. I wish to add some MVC controllers that I've been told need to use the same logic implemented in the BasePageClass. Ordinarily, I would want to inherit the functions in the BasePageClass in the controller classes, but this breaks the inheritance hierarchy.
What is the best practice for solving this problem?
If there is common functionality, I would suspect that this functionality should be separated out from the page/controller anyway. This is better OOP/D. Then both your controller base page and your System.Web.UI.Page base can both have properties returning classes that contain this common functionality.
(I've seen a lot of cases where stuff is crammed into the base page that should be elsewhere. Your need for this functionality to be in both the Pages and Controllers is likely just bringing this poor design to light, rather than being a problem in itself.)
Less likely to be what you want, but still a possibility:
You could also put your common functionality in a series of overloaded extension methods, where the first parameter is (a) System.Web.UI.Page and on the other overload (b) System.Web.Mvc.Controller.
Both your base page and base controller could implement a common interface, wrapping functionality stored in a common place.
Pull this functionality out altogether and do it as needed in your controler-logic and code-behinds.
Related
I have inherited a legacy system (asp.net vb) which has several (about 6) pairs of similar web pages. I would like to refactor each pair into a common class and keep the differences in their original classes and aspx files. I found that I need some advice.
I tried creating a common class that inherited from System.Web.UI.Page and inheriting from that common class in my pair of similar pages. That didn't work out well because the aspx controls in the similar pages weren't available to my top-level class. Passing the controls or their values to the common class didn't seem efficient since controls would have to be passed every time a method of the common class was called. Since there are usually more than 30 controls involved, this seemed more confusing than the original situation.
I also tried creating a helper class for the common code. In this case I put the common code in the helper and left all the code that that worked with the aspx controls in the similar pages. I instantiated the helper class from each of the similar pages at run time. What I wound up with are similar pages that are shorter than the originals, but even more similar than they were before - because they do similar things with similar controls. Very unsatisfying!
This seems like it should be a common refactoring situation, but I can't find any guidance. Does anyone have any advice?
Thanks for your help.
I look more tutorial about MVC. But I didn't understand, people are using "BaseController" for what? In one project someone use it forcommunication between all controller. In other project someone use for get logs. Can you explain to me completely?
It is a very common practice for some developers to create a "BaseController" or really, a BaseAnything class to use for common functionality, and then derive other things from that BaseWhatever in order to reuse that functionality. This is just basic Object Oriented Programming techniques, and have nothing specific to do with MVC (other than the fact we're talking specifically about a BaseController in this instance).
There are some, and I happen to be among them, who believe that explicit Base classes are often a code smell, and are often severely abused as "catch alls". All too often, people put all kinds of stuff in these base classes for convenience, because it's easier than creating some other mechanism to share code or data in a better way.
I avoid Base classes unless absolutely necessary. I tend to prefer other methods to achieve the functionality that is often achieved this way (I call it lazy reuse). Examples of alternatives are:
Extension Methods
Html.Action methods
Attribute Frameworks, such as AOP
Dependency Injection
and many more..
You may create a base class with the best of intentions, and claim it will only be used for a very limited function... but before you know it, others that are developing in your project are stuffing all kinds of stuff in there.
My rules is, Just don't do it. Avoid creating a base class at all costs, unless there really is no other good way to do it.
*NOTE: I'm referring to concrete base classes used for the sole purpose of sharing implementation/data. Generic and abstract base classes are a bit of a different story, as are base classes used for Taxonomy (ie is-a relationships) and hierarchical purposes. In general, if you have called something FooBase or BaseFoo, it's probably of this type.
There are also other exceptions to this rule, such as when wrapping an untestable class for testing purposes, you often create a base class for this purpose, or in frameworks you sometimes deliberately build a base class that is intended to be inherited, but isn't generic or abstract. It's there to provide functionality to fit within the framework. But, these are not things you often have control over when using those frameworks.
this is not compulsory to use basecontroller in application but its like same you using master page for your all pages in application where you can keep your common functionality for your pages same applying here. while calling action method from each controller you require different common functionality like
exception handling
master page level settings
common custom authorization.
common custom caching
common model on master page level
so everytime if you call for different controller and its action, you need to regenerate same and this you can rebuild or handle through basecontroller.
Hope this will help to resolve your question.
I am about to segregate my MVC3 app into areas, but some controllers and views are common to multiple areas. How can I share these?
I have considered some options here, but would rather take some advice first. I can locate shared controllers/views in the core app, i.e. no in any area, and route and or redirect to actions on these controllers. I can also place controllers in a shared library, and use derived controllers in my areas. Then, similar to my first option, I can use custom controller factories in my areas and use these to target shared controllers in the core app.
How should I go about this?
It really depends on what is common.
Is the HTML common? Then use editor templates or partials and place them in the Shared folders.
Is the controller code common? Then use child actions with the action itself placed in a controller in the root (e.g not in an area).
It's a matter of preference. I'm a big fan of keeping my controllers DRY, so i like use child actions for rendering of common content (think the RHS modules on this page, they would each be a child action for me).
My colleague on the other hand prefers to use abstractions on the view models and duplicate the data access/setup logic in the controllers.
try this.. I think it will help you. http://lostechies.com/erichexter/2009/11/01/asp-net-mvc-portable-areas-via-mvccontrib/
This may be a broad question because part of the problem is that I actually don’t know what the question is. What I would like to know is how you commonly organise ASP.NET applications in terms of placement of pages (aspx), user controls (ascx), server controls and other support classes and utility functions etc. First, let’s assume that there is already some data layer somewhere (perhaps in a different project). This is the not issue.
The issue I frequently face is that create several pages and realize that they need to share some common rendering logic or some utility function, class etc. Another typical case is that some pages become too large so that it seems handy to split them (say into some user controls). What is the best place to put these utility classes, share classes, user controls, server control etc.? Here are several possibilities.
Don’t really care about any organisation and place all types of files next to each other. So in one directory, you may have an aspx files, some cs files etc. This is not really an option probably.
Organize files by types. Let’s say you create a directory for user controls and put all user controls there. OK, but what about server controls and other regular classes? Should they be in special directories as well? It does not sound right. What I dislike most on this is that when you work on a feature (logically related piece of code), you must hunt it all over the place. I think that features and logical sections of your applications should be also grouped on the file system level in some way.
What I would like to have is to have the pages (aspx), user controls (ascx) and handlers (ashx) basically as dummy placeholders sitting in the directory structure organized from the logically according to the point of view of the outside visitor while the actual code (page, user controls implementations, serve control and utility classes) should be placed in s different folder structured into logical namespaces (organized by the modules or features of the application). It seems to me that the only way to achieve this is to manipulate the <%# Page ... %> directive manually.
Does it sound crazy? Am I asking too much? Is there a better way? What are your best practices? Do you know some good examples?
Edit: Another idea. This does not mess up with the generated aspx, aspx.cs and aspx.designer.cs files. One on my original requirements was that I wanted to place the code driving aspx pages to my own location and put it to a custom namespace hierarchy. So what if I simply subclass the aspx classes generated by VS? Let’s say I have a project called MyApp and MyPage.aspx page in it. VS then creates MyApp.MyPage inherited from System.Web.UI.Page. I leave this class be (no code will go there), but create a subclass, say in MyApp.SomeNamespace.SomeSubNamespace.MyPage, inherited from MyApp.MyPage. This way MyApp.SomeNamespace.SomeSubNamespace.MyPage will get access to the autogenerated protected fields corresponding to the server controls of MyApp.MyPage and I’ll get an entire "private" namespace for all the support classes which are related to this page. Any major disadvantages? Another related problem which bothers me is where should this new cs file be physically placed? In web projects, there is a standard folder for it called App_Code, but I’m interested in web applications. Creating a directory in the root of the application (such as Code) does not sound right.
Remember that you can create page classes that don't actually correspond to any markup. We often create base pages that our actual UI pages inherit from. This is a simple way of organizing "base" page functionality. Then when you create your .aspx pages, make them inherit from the base page class, rather than System.Web.UI.Page.
We usually place our base page .cs files into the top level directory if it's a small project, or for slightly larger projects we'll create a "Shared" or similar directory where they live.
However, we also have a huge enterprise web project, and we simply build our webcontrols and base pages into a class library called CompanyName.Web.UI, with a couple sub-namespaces to that. All our actual web site projects import that assembly and all the code for the controls, etc. is elsewhere. This sounds like it might be a good option for you.
If you remember that your .aspx codebehinds can inherit from any class file, it should make it easier for you to organize.
I have an ASP.NET web site dedicated to reporting on PBX extension stats. It comprises many report pages, with HTML generated almost purely by code-behind (setting a Label control's Text property instead of using Response.Write), using un-parameterised string literal SQL queries that populate By Reference DataTable parameters.
Maintenance pages at least comprise DataGrids and detail forms, but use the same DAL, on e thing for which can be said is that it supports multiple DB servers, with sub-classes each overriding these access methods with their own string literal queries.
What do I need to consider cleaning up this mess? I've already made an almost obvious decision to use a third party reporting solution, and move the queries to stored procs in their respective DB languages, narrowing the diversity of the different DAL classes, and to separate CSS out to shared files, as lots of it is very hidden in C# files!
For your back-end design, I suggest having a class to represent each main table of your database (i.e. a Report class and a User class, for example). Anything that's not an event handler should go in the back-end class files / namespace.
For your GUI, looks like you're on the right track using ASP.NET controls instead of just streaming your data out to the user. However, you may consider objectifying the areas of the page. For example, one of my favorite tricks is to open semitransparent "popup" panels when requiring user input or a something like the Information Bar when displaying a short message.
Consider AJAX and the AJAX Control Toolkit. It's easy to implement (especially in the case of a rewrite) and provides great flexibility. Specifically, I've found Accordions - sometimes even nested within other Accordions - are excellent at organizing overabundances of information.
Edit:
Note that if you were to use AJAX, you basically can't even consider using response.write anymore.
As far as having too much content on the screen, remember Panels have a "Scrollbar" property and DIVs don't without some heavy changes.
Also, I tend to separate my code files by Namespace; but the popular trend is to do so by Class. This is a better option if you have many Developers or if it's likely several classes within a namespace will be checked out or simultaneously modified by different people.
I would consider ditching any custom written DAL and use one of:
iBATIS.NET
NHibernate
SubSonic
You might even end up dropping sprocs entirely.
If you're daring you could try the redesign using Microsoft's MVC implementation.
Whatever approach you take, make sure you write unit tests prior to refactoring any code, verify the tests pass before and after refactoring.