On Web Forms we have UserControls. These controls have a code-behind and can be used in different projects/solutions not depending on other things.
I want to create a control that renders some controls and would have some links that would "trigger an event". I want them not to be attached on my website, I want to be able to use the same "control" on another website. What is the equivalent in MVC? Is it possible to compile a view with a controller and use the DLL elsewhere?
The closest functional equivalent to WebForms-style reusable user controls in MVC are html helpers. An html helper is a method that returns some markup. The recommended approach is to implement them in the form of extension methods off HtmlHelper or some other property of an MVC page:
public static IHtmlString MyControl(this HtmlHelper helper, string value) {
return new HtmlString("<p>" + value + "</p>");
}
You can add this method to your MVC project directly or you can add it to a seperate class library. The only thing that the class library needs to reference is System.Web.Mvc.dll for the HtmlHelper reference (it might also need System.Web.dll if you use more types).
You usually call them from your view like so (this example uses the Razor syntax that's new in MVC 3)
#Html.MyControl("my value")
While superficially html helpers emit markup just like User Controls, there are significant differences. The most important one is that MVC views don't have the concept of the WebForms page lifecycle. This means that unlike user controls, html helpers are rendered in a single pass. There are no mulitple phases like Init, Load, Render etc in WebForms where you can hook up server-side events to interact with other controls on the page.
Depending on what specific kinds of events you are talking about there might be appropriate MVC-centric techniques to solve your task. Could you provide more detail on what you want to do? Html helpers can be quite powerful. For example the built in MVC input controls like TextBoxFor can hook up client-side validation etc.
Since "events" don't exist in the same sense in MVC as they do in WebForms, meeting all your requirements will be quite tricky.
For the UI layer of the UserControl equivalent, you should use a PartialView, possibly located in the Views/Shared/Templates folder depending on if you want it to be associated with a certain Model type or not.
For the back end (the "event"), you should probably implement a Controller that you could send the requests to from your links, and that supports all the behavior you need.
To use these features in various projects, you then have to copy both the controller and the template/partial view. Admittedly, it might not be as simple to re-use as a do-it-all user control from WebForms, but that is a limitation that comes with a clear separation of concerns, and that would be apparent in a well designed, layer based WebForms application as well.
Update in response to a comment on the "limitation" of separation of concerns I mentioned:
The controller can of course be distributed in a separate assembly, with it's own test assembly etc. However, including the controller assembly (or assemblies) and the partial view/template with the front end code is arguably one more thing to do (i.e. possibly fail to do) than just copying a user control with it's code-behind (that are stored next to each other).
Related
I just started out with Umbraco for my own projects because it is cheap in comparison to Episerver. Coming from the Episerver paradigm of strongly typed Page/block types and doing everything programmatically, i now find it hard to get into Umbraco in the way i hoped to.
I know how to create simple applications but i was hoping to define my Page Types like classes with properties that Umbraco then treats as Pages. My goal is to be able to create a hierarchy of page types where certain pages inherits properties from its parent page etc.
If I have a ArticleListingPage I want to inside of it's controller list all types of article pages. For example if I have a ArticleBasePage with the properties MainBody, Heading, Introduction then I want these to be inherited by ArticlePage and ArticleLongReadPage. Whenever I want to list these I want to search for pages of type <ArticleBasePage> and loop through the collection and render these. I don't like working in the UI I simply want to create a hierarchy of classes(that are pages) just like I would do in Episerver.
Is there any way to do this? Or a guide maybe? I don't like the approach of creating pages in the UI, I want my pages to be of a certain class so I can get the benefits that comes with that
Umbraco is vastly different from current Episerver versions (7+) in terms of managing the content model, but you can achieve somewhat similar code-first features to enable inheritance.
You may want to have a look at uSiteBuilder (available as a NuGet package).
Some more information available on Jon Jones' blog.
I am going to be purchasing an MVC theme from WrapBootstrap https://wrapbootstrap.com/theme/inspinia-responsive-admin-theme-WB0R5L90S for a personal project.
There are alot of things that I like about it design wise, but it has brought up a question about the best way to load notifications in the header (really any sort of dynamic data that needs to load into the common Layout view).
I know there are a great number of ways to do this, but I am at the point in my development experience where I am trying to break my bad design habits (hacking things together so they "just work"), and look for elegant solutions where I can.
The things that make the most sense so far is to either:
1) Create a global ActionFilter that will filter all requests and throw a "LayoutViewModel" into the ViewBag, and just use the ViewBag in the _Layout view.
I'd rather do something strongly typed, but I don't see a way.
This is nice because it is available, does not require my controllers to inherit any functionality from a base class that might be cludgy, or even know that it is happening.
2) Load the page and onLoad, just do an Ajax Calls to the server to load any dynamic data I need.
This may have some disadvantages if your layout needs to change based on the data. I dislike with things snap all over the page after loading.
Is there a design pattern or MVC feature that I may be missing top accomplish this?
I may in the future I may implement something liks SignalR(or a simple timed ajax call to look for updates) to get updated data/notifications, but for now I am just looking at the initial page load.
Thank you for any ideas that you may have.
Most likely, what you're looking for is a child action. These are pretty much just like normal actions, except they'll return partial views and generally are decorated with [ChildActionOnly] to prevent routing to them via the URL bar.
[ChildActionOnly]
public ActionResult Notifications()
{
var notifications = // get the notifications;
return PartialView("_Notifications", notifications);
}
Then, in your layout, you just add the following where you want it to appear:
#Html.Action("Notifications", "Foo")
Where "Foo" is the name of the controller you put this child action in. I have a post on my blog that gives a primer on the Razor templating system that may be of use to you as well.
We are in the process of moving our application to .NET. One of the main goals is to allow modifications to the application, per client, but not to the source code. We resolved this in the core framework by programming to interfaces and using a Dependency Resolver (having an option to override the base registration) and MEF.
Now when it comes to views (the UI the client sees) the templates seem static and if the client wants to add a new field to the screen it seems they would need to modify the view itself.
The only two things that I can think of is modifying the search path of viewengine. This would allow a copy of the base and changes to it would be picked up. Not really liking this as it's a copy of the code.
The other way, what we are doing now, is that we create a class that is a container to other objects that output HTML. Basically we have a PageObject, LabelObject, InputObject..ect that we can call render on and output HTML. Since they are classes we can use the same methodology as for the rest of the application of giving slice in points. Going this route we really are not using the viewengine for rendering but just for combining all the partial views. Seems kind of clunky.
Is there a different way to accomplish this goal or a different viewengine that I can use to meet the goal of allowing customization for clients without touching the base view? I know HTML is not an object but seems there has to be something in between ASP.NET WebForms and ASP.NET MVC when dealing with HTML and allowing for customizations.
I would create a strongly typed partial view or template (DisplayTemplate or EditorTemplate based on requirements) whose #model is a collection of things that are rendered as inputs and labels. Allow the client to add/remove items from the persisted collection (i.e. in a database) and your problem is solved using the built in ViewEngine.
when we search Google for difference between MVC and MVP then thousand of article is available but i read few but they are not showing difference in terms of coding sample. so if anyone knows any url from where i can see a sample code for both MVC & MVP implementation then please tell me the url. i want basically small sample code by which shown the difference through coding flow in c#. i hope i am very much clear what i am looking for.....i need code same code one with mvc coding flow and another with MVP. i am not asking for theoretical explanation.
I also don't have sample code on my blog post "MVVM vs MVP vs MVC: The differences explained" but I do have a section for each architecture that discusses how to implement them using words. I will describe it here.
MVP requires a few implementation details
Each view must implement an interface for the view (eg IUserEditView for editing users). This interface contains functions for things that the presenter might need to do (eg, showUsers(IList users), displayMessage(String errorMsg)
A presenter is created for each view. It contains functions that the view will need to call (eg, saveNewUser(User user), selectedUserChanged(User user))
An instance of the presenter is created in the view's codebehind. When view events occur, appropriate messages are forwarded to the the instance of the presenter. eg, when the save button is clicked, all the user details are forwarded to the presenter in the form of a new user....myPresenter.saveNewUser(new User(txtUserName.text, txtPassword.text))
When the instance of the presenter is created in (3), the view is passed as an argument to the constructor. This way, the presenter can reference the IUserEditView from (1)
That is the meat of MVP. You will probably need to implement the mediator pattern and have all the presenters inherit from base presenter. This way, presenters can send messages to each other without having to reference each other explicitly which is important (eg, if a new user is added, maybe you need to update a related view like users online).
MVC is a bit more tricky.
The controllers have a method of selecting which view is displayed. This could be referencing just a dictionary of instances of all the views but a better way is to have some class outside the controller manage the details and then the controller can just select the view with something like ShowView("UsersView", listOfUsers). Note the separate class can be a base class, or a factory, helper
A method of forwarding actions from the views to appropriate controllers. With the web, you just can determine the controller & method from the request url (eg, http://www.mysite.com/mycontroller/method, www.mysite.com/Users/AddNew/). For other systems, you will have to implement a class to manage the messages, or just directly forward them to an instance of the controller in the view. I've only used MVC with the web so I'm not so sure about the last point.
Because of (2), the view is now able to trigger actions in the controller. When it does so, the controller modifies the model (the implementation of this will depend on the details of your model).
Updates to the model get sent to the view (usually via an observer pattern). Check out INotifyPropertyChanged if using .net
Word of caution: Although I have described how to implement both methods, they should not really be considered interchangeable. There are cases when you want MVC, MVP, and MVVM. I think if you don't have technology limitations around using MVVM, then it is your best choice. I am biased but I think maybe people are moving away from MVC and towards MVVM (or MVP) except for very specific cases like ASP.NET MVC. My article describes this in more detail if you need clarification.
Short summary for when to use each in terms of C#
WinForms -> MVP
WPF -> MVVM
ASP -> MVC (if you can't use ASP.NET
MVC, then MVP will work too)
I am primary a web developer but I do have a very good understanding of C++ and C#. However, recently I have writing a GUI application and I have started to get lost in how to handle the relationship between my controller and view logic. In PHP it was very easy - and I could write my own MVC pattern with my eyes closed - mainly because of how PHP is stateless and you regenerate the entire form per request. But in application programming languages I get lost very quickly.
My question is: how would I separate my controller from view? Should the view attach to events from the controller - or should the view implement an interface that the controller interacts with?
If I was you I would expose events from an interface of your view. This would allow you to make the controller central to the entire interaction.
The controller would load first and instantiate the view, I would use dependency injection so that you don't create a dependency on the view itself but only on the interface.
The controller would access the model and load data into the view.
The controller would bind to events defined on the view interface.
The controller would then handle saving of data back to the model via an event.
If you wanted to you could also use an event broker which would void the need to declare an interface per view. This way you could bind to events through attributes.
This would leave you with the Controller being dependent on the model and the view interface, the view being dependent on the data only and the model having no dependencies.
Some examples of the above design thinking can be found in CAB and the Smart Client Software Factory Link To Smart Client. They use the MVP pattern but it could equally easily be applied to the MVC pattern.
Most every GUI framework (from MFC to SWT to whatever) is already MVC based. In fact, the MVC pattern was first created by Smalltalk-80 and later first really used for GUI development.
Double check and look at the standards and suggested practices for your GUI toolkit of choice. Sometimes MVC won't be a good pattern to work with when solving a certain problem or working with a particular toolkit.
Remember: MVC is a great pattern but isn't a one size fits all solution, don't try and force a problem into MVC when event-based or functional style programming will make your life easier.
Imagine this GUI:
The Zergling unit is presented to the user as an alien icon. You can see that it is in its idle animation. Call this the View.
The player moves the unit by clicking on it and a target location. You can subtitute the player for an AI if you want. Call this the Controller.
The HP and attack range of the unit is calculated every game frame when the unit is in combat. You can change this data to make the Zergling into a range unit. Call this the Model.
Keep this analogy in mind and extend it for your MVC designs.
The imortant thing for you to remember, is that in your MVC setup the Controller must know which View to call, but the View must know nothing of the Controller.
So your View must provide a generalized way for Controllers to interact with it, so that you can have several different Controllers call the same View (a standardized graphical output of some data provided as parameter, for example).
This gives you flexibility:
If your customer wants PDF output of
something you only provide HTML
output for, you can get away with
writing a new PDF View to be called
from the Controller with the same
parameters as the HTML View.
If your customer wants similar HTML output of a different data source (say), you can get away with coding a new Controller that provides a different data set to the same old HTML View, which gives the same HTML report just with other data.
If you keep your View detached from specific Controllers, and put the knowledge about which View to call from your Controller, you're well on your way.
Your controller should definately bind to events defined on an interface the view implements.
How you go about doing this can be the tricky part. Dependency injection? A view factory? Have the view instantiate the controller it wants? It really depends on how complex the application is going to be.
For something really quick and simple I would start with having each view construct it's controller and then look at other options if it needed to get bigger. Personally I think a full dependency injection framework is overkill for half a dozen forms :]