I'm new to using the MVP pattern and I just want to make sure on the best way to call a presenter from within a user control.
MyPage.aspx has a presenter MyPresenter
The page contains a user control which accepts MyPage's Presenter via a property which I setup from MyPage
MyUserControl.Presenter = this.Presenter
I'm now trying to call Method1 within the presenter which retrieves some config and sets it on the view from the user control.
Presenter.Method1(); // calls method and sets config to the view
My question is firstly
should I be using the presenter in the user control in this way?
If so, is it valid to be accessing the view value via the user control as shown below.
Presenter.View.MyData
I just want to make sure I'm not going off down the completely wrong path with this!
What I use to do is to have one presenter for each user control which is responsible only for the user control presentation and one presenter for each page (.aspx).
I think keeping things separated helps also for maintaining as you will have "skinny" presenter which are responsible only of a small section of the UI.
The user control will be also "self-contained" in the way that you can reuse them as the presentation logic is kept separated from the page presentation logic.
have a look at the following post:
MVP and UserControls and invocation
Related
What are the conventions used in ASP.NET WebForm for passing data to view from code behind?
In ASP.NET MVC for example ViewData is a key value collection or a strongly typed class object. So what do people do in case of ASP.NET WebForm.
I know we can create a property or member of a class or add stuff to Page.Items but what else besides that?
I think all the concepts of ASP.NET MVC do not map to ASP.NET Forms since they are two different paradigms of building web app.
In WebForms people mostly deal with controls and set their properties, they don't have to pass data to view as such. However if they do have to do so they use Page.Items or HttpContext.Current.Items or create Page properties that they access in views.
There is no direct equivalent of ViewData or ViewModel in WebForms that is used in practice. Page.Items is the closest thing.
I'm not sure there is a direct equivalent, but the "HttpContext.Current.Items" collection can be accessed from anywhere without having to pass the context (though it does make assemblies dependent on System.Web).
You can use ViewState.
View state is a repository in an ASP.NET page that can store values that need to be retained during postback. View state is typically used for page variables that must be retained rather than user or session data. For example, you can store information in view state that will be accessed during the page load event the next time the page is sent to the server
Please see details at: https://msdn.microsoft.com/ro-ro/library/ms227551(v=vs.85).aspx
What feature(s) of ASP.Net MVC can replace the way events can be used in Webforms to support loosely coupled components?
For example, take a simple pager control in Webforms:
A page number is clicked
Pager fires off a "PageChange" event with the new page number
This subscribing page/control received the event and handles initiating a call to fetch and bind new data.
What tools are available in ASP.Net MVC to similarly support
Loose coupling
Component re-usability
Separation of logic for a single page/view (such a very complex "portal" type page).
ASP.NET MVC, and the Model-View-Controller in general, support loose coupling and separation of concerns by keeping the data and code that supports an application separate from the visual "Presentation-layer" markup that is seen by users.
Designed properly, Controllers and Views in MVC can be reused so that the Edit View for an entity can be "embedded" into a related View with no modification.
For example: an Orders View might include an OrdersDetail partial view. That partial view could be replaced with the OrderDetail Edit View that is also available elsewhere within the application.
Separating the Model from the View makes unit testing more effective and less cumbersome by splitting the code from the context of the presentation layer. You don't want to have to reference System.Web to unit test code that fetches data from a database.
MVC does away with events because events for the most part are just an unnecessary layer between what the client is trying to tell the server to do and the server actually doing it.
In the paging example for webforms the client clicks the button, the browser sends the event/viewstate, and the engine fires the ButtonClicked event. You examine the event, determine the client is intending to page, and you execute the paging logic.
In the MVC paradigm the user clicks a button that makes a request directly to the code that executes the paging logic. Since you know what action the button is supposed to invoke when you put it there why go through all machinations of the event firing? In your controller you certainly could fire an event when you get the command but I honestly can't imagine the use case for doing so.
Both methods accomplish the same thing but MVC just removes a layer of complexity.
First post so please be gentle :)
When creating user controls in ASP.NET MVC, what is the best way to structure the code so that the controllers that invoke views that use the user controls do not all have to know so much about the controls? I would like to know a good way to maintain DRY while using user controls in ASP.NET MVC.
Please note, this question only pertain to user controls that require special handling and logic on a postback. I have no problem creating nice DRY code for user controls that are either view only (using RenderPartial) or that require some pre-processing to create the appropriate ViewModel (using RenderAction).
Also, this question pertains only to achieving reusable controls within an application. I am not worried about reusability between applications at this point.
To give a specific example, let's say I would like to create a 'Quick Add' user control which contains three entry fields, First Name, Last Name and Company Name and a submit button. When the QuickAdd functionality is used, the following steps should be performed independent of what page the control is on:
Validate that the fields were not empty, if they are, show an indicator.
Perform a lookup to a repository to see if the Company already exists, if not; create it.
Create a new contact associated to either the existing company or the newly created company
Re-render the existing page. If no validation errors, the user would see the exact same page again, otherwise the same page with validation errors.
My main problem with achieving DRY has to do with all the controllers that invoke views that contain the partial view end up having to have an Action Method to process the form submission from the Quick Add. Even if I break out the logic for processing the information into a separate controller and invoke that method from each of the other controllers it seems like a burden that each and every controller that invoke views that have reusable controls have to have that knowledge.
The other option I looked at was to have the reusable control always submit to a specific action method / controller but then there is no way for that controller to know how to re-populate the model appropriately for the specific controller that invoked the view that contained the reusable control (in step 4).
I am aware that there is talk of subcontrollers in MVC 2 (from this question ASP.NET MVC - Contained User Controls) but since it is not there yet, what is the best way to structure the code to achieve maximum reusability while maintaining DRY?
Is there an alternative to having to have all the controllers that invoke views that use a reusable control (with the characteristics of the one described above), having to have an Action Method to process the information from the control?
At the end of your post, you ask "Is there an alternative to having to have all the controllers... having to have an Action Method to process the information from the control"
The answer for that question is to write a custom model binder. Your custom model binder can be responsible for the populating the values from the incoming form control(s) into model or properties used by all of the controllers. Normally, you want to separate the validation from the model binding, but there is no reason that you couldn't combine them as well.
I highly recommend 6 Tips for ASP.NET MVC Model Binding for a deeper discussion of the topic along with some good references.
I'm not sure why you say the Quick Add form has to have an action method in each controller that uses it; if you wrap the Quick add functionality in a Html.BeginForm(); Html.EndForm() combo, you can have the beginform method specify the name of the action and controller, so you only need one controller.
I understand where you are coming from; it's something I have been thinking about to. While I don't know all the answers, I have some ideas for you to consider. Every controller action method is invoked via a ControllerActionInvoker class, which you can customize. This class handles invoking all of the action methods, so here you could embed certain aspects of reusable code across all or certain action methods.
Look into filters too, as there are a variety of filters that you can use or customize that fire for action methods that implement it. This way, code can run before and after the action method execution and result execution.
For validation, there is already validation components built in that will prevent page submission... you could also consider XVAL which has some other nice features. The Unity framework is an IOC container framework, which dynamic injection keeps things loosely coupled and DRY, as you can inject all kinds of references.
Also, you mentioned subcontrollers; the MVC preview has additional features you may be interested in... for instance, it has a RenderAction method that can render an action method within another action's view.
Hopefully that helps... so what am I missing?
Have a look at RenderAction and RenderPartial. Those are the canonical ways to arbitrarily inject a common control into a view.
Use RenderPartial when you want to include the data as part of your ViewData infrastructure.
Use RenderAction when you want the data to be separate from the ViewData infrastructure. The data will come from the controller method you specify in RenderAction.
Check out the NerdDinner tutorials, if you haven't done so already.
I'm writing my first app with ASP.NET MVP (attempting Supervisory Controller) and Unit Testing (better late than never!), and I've run into a bit of a dilemma. I've written 3 User Controls, all tested and Interfaced up, Presenters in tow. Now I have come to a Page which takes these three User Controls and encountered the following problem:
User Control 1 is DateSelector, it's a Calendar control with a couple of other buttons/lists. Nothing real exciting.
User Control 2 is DailyList. Guess what it is. Anyway, you can select/delete etc.. if you select an item from the gridview, it needs to populate User Control 3.
User Control 3 is ItemDetail. Here are the DropDownLists, TextBoxes, etc... some with existing dependencies on others (selecting an option in DropDown one affects the options in DropDown 2).
If I select a new Date from my DateSelector, do I raise the event from the DateSelector Presenter? I have to somehow let the other User Controls know that a new date was selected, so that they can rebind their data, but how? If I use the Page's Presenter to subscribe to the Presenters of the User Control Views, will I not be blatantly breaking the Law of Demeter (exposing the Presenters as Properties through their Views)? Mustn't I use the Page's Presenter as the All-Knowing Controller of the page? Is there something I am missing?
Everything I've read so far says, "MVP is great, even with User Controls", but the use of User Controls is conveniently forgotten about when it comes to examples. It appears to me MVC would more closely match my pattern of thinking on this one, but currently, MVC is not an option. Any help would be great here. Thanks in advance.
The Page Presenter has to be the one to coordinate the interactions between the controls on the page. Who else would do it? I'd have the page presenter listen in on the event of the DateSelector user control. From the page presenter's perspective, it probably doesn't need to know who raised the event (view or presenter) as it looks at the DateSelector as a fully encapsulated control. The internal workings should be hidden from the page's presenter.
All it knows is that the DateSelector user control raised an event, and now it needs to notify the other controls on the page, either by raising its own event, or by explicitly calling methods on the presenter.
I am working on an ASP.NET MVC application that contains a header and menu on each page. The menu and header are dynamic. In other words, the menu items and header information are determined at runtime.
My initial thought is to build a base Controller from which all other controllers derive. In the base controller, I will obtain the menu and header data and insert the required information into the ViewData. Finally, I will use a ViewUserControl to display the header and menu through a master page template.
So, I'm trying to determine the best practice for building such functionality. Also, if this is the recommended approach, which method should I override (I'm guessing Execute) when obtaining the data for insertion into the ViewData.
I'm sure this is a common scenario, so any advice/best-practices would be appreciated! Thanks in advance!
EDIT:
I did find the following resources after posting this (of course), but any additional anecdotes would be awesome!
http://www.singingeels.com/Blogs/Nullable/2008/08/14/How_to_Handle_Side_Content_in_ASPNET_MVC.aspx
How do you use usercontrols in asp.net mvc that display an "island" of data?
Depends on where your information is coming from. We have standard view data that we use to generate some of the information we have on screen that we create in just this fashion. It works well and is easily maintained. We override the View method to implement strongly typed view names and use this information to retrieve some of the data that the master page requires as well.
You could write a helper extension to render the header/menu
That way you could have it show in different places in the view should you need to, but only one place for maintenance.
public static HtmlString MainMenu(this HtmlHelper helper)
Use a base controller class to implement generell filter methods. The controller class implements some filter interfaces IActionFilter, IAuthorizationFilter, IExceptionFilter and IResultFilter which are usefull to implement some common behavior for all controllers.
If the menu data is the same on all pages but different for each unique user.
Generate the menudata in an OnAuthorization or Initialize method of your controller base class. First will be called on authorization. Initialize will be called before every action method. You have access to ViewData Context. Generate the menudata there.
Put the view content for menu and header into the master page and access generated ViewData there.
I tackled a similar design challenge a couple months ago - implementing a breadcrumb feature that changes as user navigates from page to page.
I overrided the OnActionExecuting method to gather the breadcrumbs and store them in ViewData (I use the name of the action as the breadCrumb of the view). Then I updated the Master page to include a user control that takes the ViewData and renders the breadcrumbs.
One thing to be aware is that if you were using the default ASP.NET MVC error handling attribute [HandleError] and your error page is using the same Master page that attempts to read the ViewData, you will soon find out that you can't access ViewData from your error page and it will raise an exception. Depending on whether you need the ViewData for failure scenarios, the viable solution is to use a separate Master page or do this: How do I pass ViewData to a HandleError View?
I'll answer your question with another question. Will the base controller have to determine what type it really is in order to generate the proper menu data? If so, then you're defeating the purpose of polymorphism and the code to generate the data should go in each controller, perhaps in OnActionExecuting if the menu is the same for all actions. Pushing it back down into a parent class seems likely to end up with some switch statement in the parent class doing what each derived controller really ought to take care of.