Is it my understanding that Helper methods are really the place where you can do the hard core logic that we would have done in lets say custom controls in ASP.NET? For instance I work for a .com which uses classic ASP.NET. The nature of our site is VERY complex, so we reuse and render different forms for thousands of products. Every product could have a different configuration form. We have a very complext RenderForm.cs custom server control that performs all the logic. Based on some configuration settings from a table in the DB, it says ok, for Product 1123 it reads the setup (that our users confugure form our internal admin system) and takes that and spits out the dynamic form (using literal controls and what not) to the p age.
So I'm thinking MVC now. Yea yea, it's all done in the View. Well partially. You're still going to have a need to have some custom logic in some .cs where it's not all embeded in your view. That would be foolish to think you're not going to have some class that will spit out some HTML..like some very hard core extensive helper methods.
So my question is, are helper methods or class where you now do your custom server control type of logic? it's basically kind of the same concept in that you need a place to put your "hard core" HTML rendering logic in some class other than a controller. Your controller is not responsible for rendering. So helper methods I guess are the so-called custom server controls in a way that I have in classic ASP.NET, figuratively speaking. I just need a yes or now on is the consensus that helper methods is the place to do all my hard core reusable logic that spits out html to the page and where I can embed custom controls into my view? Looks like it.
"Helpers are essentially static classes, designed to contain the UI logic that otherwise clutters up your UI. Think of these as UI utilities." link text
Yes, that is right on. If you do it right, you will start with the HTML helpers that MVC gives you, and you will gradually build up your own set of helpers that do even more and more for your specific project. You can get to the point where your view has only a few lines of code, which say something like, "Render entire view for Product 1123". The helpers will become your own "language" of renderers specific to your project, and you will be applying configuration, validation and everything else in a very DRY (Don-t Repeat Yourself) manner. It's phenomenal.
Update: Of course, only presentation stuff should go in your helpers. The goal is to stay DRY in your views. You still need to be careful to put into your ViewModels the things that belong in the ViewModels.
I would say "no"... or rather "only where you have to". More often than not, you can instead do the logic in the Controller (or a Service) and end up passing all the data required back to the View in ViewData. Somtimes this will mean multiple Views from one ControllerAction, less often it will mean logic in your View, and occasionally it means HtmlHelpers.
When you decide to use Helpers, it should be with the consideration that this means generated markup that won't be... well, in your markup. If you have (or later hire) a designer, that can be a problem. Or if you need to make a minor change to your layout, where do you go first? Your View or your Helpers?
[Edit] Also should ask yourself this: where is my code more easily unit tested? In a Service class which is just handing back View Data, or in a class that builds entire chunks of HTML and returns them as a String? If you're using TagBuilder, as you probably should be, then any change in the implementation of TagBuilder (even a change of whitespace handling) will break tests on a Helper without your code changing.
I'm not saying "don't use Helpers", I'm saying "don't abuse Helpers".
Related
I am currently working on multiple ASP.NET MVC web apps.
All of these web apps have the same navigation bars/menus.
Some of the menu items are app specific, so they can be passed from the respective app.
Some of the menu items are not app-specific, such as whether user is admin or not, based on which I show an admin link on the nav bar. The logic for getting the admin property is available in the business layer.
Is it possible to make this html helper such that I don't have to pass the non-app specific parameters from the respective apps ?
Can I call the business layer from the html helper ?
Is it advisable ?
I want this html helper or any other solution easily distributable...
Thanks
HTML helpers are extension methods on the System.Web.Mvc.HtmlHelper type that return an System.Web.Mvc.MvcHtmlString object. If you want "easily distributable", then you can create a library project with the helper extensions that you need. Then add the project in as a reference on the MVC project.
#using statements can bring in the extensions to the Razor view. The helper object that you bring in through the extension method in the library will give you access to most of the information available to the Razor view at the time the helper is called (with the ViewContext property).
The extensions can be overloaded as much as needed to account for variations in the projects. Common menu options can be added to the library as a static collection that can be accessed by both the MVC project and the extension methods.
update
MVC is set up such that you can do what you want. You have a lot of control. Your helper can include as much code as you need. It's not like you are "breaking the rules". But best practice dictates that you keep your business logic in the controller. By putting that into the helper, which gets called by the Razor view, you are in effect moving the business logic into the Razor view.
HTML Helpers in general are a lightweight way to create HTML code. Thus they are easy to reuse any you can have dozens or hundreds on a single Razor view. That idea gets broken when you move a bunch of business logic into the helper. Then you have a potential of slowing things down if the helper is to be reused a lot.
Good rule of thumb for MVC, if your helper starts getting complicated, create a partial view. I would probably create a model to represent the menu, then create a partial view in the Shared folder that uses that model, then call it from the parent view. I think that would give you more flexibility, and be more in keeping with the MVC best practices.
What are the disadvantages to using webparts in asp.net? Are they losing their popularity?
I was planning on creating a user defined Dashboard and was thinking of using Webparts, is this the way to go or is there another way of doing customisable dashboards these days? I would prefer not to have to use a 3rd party product.
To me, webparts are more of a sharepoint thing these days.
Other than that, with some design you can get all you need with user controls and some classes of your own to get common functionality and layout sorted out.
Say you have a base class called DashboardWidget that inherits from WebControl here you could define a overridable method
ProcessDataSource -> executes a query to a database or service and formats the results for presentation
And in the prerender method (or something similar along the asp.net lifecycle) you call ProcessDataSource (you could use the DataSource property most controls already have).
Then you inherit from DashboardWidget to make your controls and in the render method you override ProcessDataSource to get the info the way you need and the Render method to setup what to display.
Ideally you should define your own data source class to have a single place to define where to connect, how, credentials, etc..
As for the layout, newer versions of asp.net include several layout option you may use (and there is always pure html if you want)
I'm shooting from the hip a bit here, but that's a way to do it without involving webparts, that to me, are not that popular outside of sharepoint.
Hope anything of this helps
I've developed an ASP.NET user control, instances of which may appear several times on a single page. Without getting into too much application detail, when the value of any one of the instances changes, all of the other instances need to be refreshed. Currently, in order to accomplish this, I'm requiring that the consuming page implement a couple of methods which iterate through each control on the form, find all the instances of my user control, and call a Refresh method in each one.
Functionally, it's working perfectly. However, I'd like to force the developer of the consuming page to implement these two methods exactly as per my requirements. I could have them implement an interface, but that doesn't provide the functionality in each method. Or I could have them extend an abstract class, but in either case (interface or abstract class) how can I force them to inherit? I need something that will trigger a compiler error if the necessary abstract class is not extended by the consuming page. Any ideas?
Thanks.
You can enforce implementation by using 'abstract methods' in C# or using the 'MustInherit' keyword in VB.NET.
In your particular case, you're expecting the developer to essentially implement 'your' code to force the refreshing and this is something I wouldn't want delegate. Without knowing too many details I would be tempted to utilise the 'Observer' design pattern or possibly the 'Mediator' using either a separate object as a controller or even applying the controlling / publishing code to the webpage. Here's a practical example of the 'Observer' in ASP.NET.
HTH
I am getting confused between domain/application logic and User Interface logic. To illustrate what I am trying to nail down, I will describe an imaginary program below for illustration purposes:
(1)
Imagine a small application with a set of 3 cascading drop-downs. As you select one dropdown it triggers a jQuery Ajax GET which ends up hitting a MVC controller, supplying the selected value of the previously selected drop-down. The controller returns the allowable choices for the next drop-down. The javacript (in the view) arranges these results into a drop-down. and so on. So each time you select a drop-down, the next one gets populated.
(2)
Now throwing in a wrench.. There are some exceptions. Lets say if the user selects "FOO" or "BAR" in the first dropdown, then the behavor changes, so that the second dropdown is disabled, and the thrid dropdown will show a texbox instead.
My questions is, in the context of MVC, what is the appropriate place for this "decision" logic? Such as the code that is responsible for making these decisions like I explained in (2). The most convenient place that I have been putting this was right in the javascript of the view. I simply wrote javascript to test if the first box is "FOO" or "BAR" then, disable the second dropwdown, and swap out the third dropdown for a textbox. But this does not feel quite right to me. Because It seems like it should be business logic therefore the code should belong in a domain layer some place. But that does not feel quite right either.
And so I feel like I am going in circles. Can some one shed some light on this little design?
Let's start at the Domain Model. A Domain Model is an API the models the Domain in technology-neutral ways. It knows nothing about View technologies such as JQuery, HTML or (for that matter) XAML or Windows Forms.
The Domain Model contains classes and interfaces that describe the Domain and lets you model the Domain Concepts in a rich and expressive way - no matter what type of application you are developing.
With that in mind, it's fairly easy to see that the display logic you describe doesn't belong in the Domain Model. It must, therefore, belong in a UI-specific layer.
You can put that in a separate UI Logic module or together with your UI application - in your case an ASP.NET MVC application. Whether you express the desired UI logic in JavaScript or server-side is less important.
Personally, I would define this logic server-side in Partial Views, but that's because I care a lot about testability, and I know how I would unit test such behavior (I've been told it's possible to unit test JQuery code as well, but I have no idea whether that's true or not).
If you ever end up writing another application based on the same Domain Model, it is very likely that the display logic turns out to be very different, because different technologies imply different paradigms.
Without splitting too many hairs or getting too fanatical on WHAT MUST BE DONE TO KEEP THE PATTERN PURE...
Obviously the Controller knows that this change must occur, as it will be handling both resulting cases (drop down selections or text entry). So putting logic relating to this in the Controller is not a sin.
It is also equally as obvious that the View must change how it displays depending on the contents of the first dropdown. While this mixing of behaviors isn't exactly the best UI experience I could imagine, if requirements must, then the logic for this must exist to some extent in the UI. But, jeez guys, this is a website we're talking about here. Do you really want to remove all logic from javascript and move it into a controller method? The View is deciding on how to display data, which is its job, and so cannot be a sin.
The real way to avoid getting burnt at the stake is to redesign to avoid the controversy in the first place. Or, just code it and bitch about your lousy design requirements over a beer.
In that situation where you have very specialized actions happening you need to put it in the logic in the js like you have been doing in your drop down example. You will also always want to put the validation on the server side as well to ensure your data is clean.
With the MVC 2 stuff coming out they have some really great validation server/client side validation going on. Check out Scott Gu's post more insight on this: MVC 2 Blog Post
Given your example I wouldn't mind this logic in the controller, it definitly doesn't belong in the domain model. I would personally feel better grabbing the ajax GET request in the controller and deciding what to output from there with JSON instead of doing all that logic in jQuery (I just feel more comfortable in C# then in javascript). With that being said, I like to keep my action methods skinny so what I would do is put the logic involved with figuring out what to populate the dropdowns in a method on the conroller and decorate it with [NonAction].
In traditional ASP.NET Web Form applications, UserControls are a great way to encapsulate functionality so that it can be reused. However, UserControls don't fit well into the MVC model. They often make heavy use of ViewState and they blur the seperation of concerns that MVC promotes.
My question is, how do you best bundle a piece of functionality so it can be shared across MVC applications?
As an example, consider a from/to date-selector UserControl that:
allows a user to select two dates, either using a javascript overlay or by typing in day, month and year into seperate fields
can be configured to default to either today and tomorrow's dates or to dates of the developer's choosing
validates the dates that comes back from the user to ensure the from date is before the to date
exposes From and To properties that can be accessed by code-behind
How would I best build something like this in .NET MVC so that I can easily reuse it?
Note that to fully emulate User Control's functionality the MVC component would have to manage the submitted form data and validation - not just the presentation.
In general I would agree that user controls are nice in terms of encapsulating UI stuff, but I don't think too much has really changed in MVC. If I remember right re-using user controls across classic Asp.net projects was a pain and was never really the best way to truly create reusable components. Most UI toolkits that you bought for classic ASP.net didn't give you user controls, they gave you essentially server controls and javascript controls.
In your example, I would probably create or find a jquery (or ur framework of choice) plugin that did what you wanted on the client side. You could also build a C# wrapper around it similar to what Telerik did with some of the jquery UI controls. I do think that the word code-behind and even viewstate will disappear from your vocabulary the more you get into MVC.
If you look at what open source projects are out there for MVC you will get your answer in terms of what you should be doing.
The MVC Contrib app adds a lot of features by creating extension methods and helpers. Their grid control is a typical way to create a reusable component that you could use across projects
Telerik, created some extensions that wrap jquery controls and do asset management.
Finally I think if you look to the future, MVC has areas, which if I interpret it right will give you the ability to break your project apart into multiple smaller projects.
Besides what is already suggested, ASP.NET MVC v2 will have generic templated input controls, see here. You can read how other people do similar techniques, for example, here:
We have
exactly 1 method call for generating a
form element, “Html.InputFor”. As
part of that “InputFor”, it examines
an input specification, that collects
the PropertyInfo, any attributes, the
type, any modifiers called, and
selects an appropriate InputBuilder.
Call InputFor(p => p.Id) and Id is a
GUID? That creates a hidden input
element. Call InputFor(p =>
p.Customer.Address) and Address is a
complex type? That looks for a
partial with the same name of the type
Having considered the helpful answers from others, I will have a go at answering my own question.
It seems to me that the key difficulty with emulating UserControls in MVC is that they crosscut the concerns that MVC aims to seperate. The from/to date selector UserControl in my example incorporates elements of Model, View, Control and interation. UserControls' ability to bundle all this together is exactly the reason that they don't fit well into MVC.
That means that to create a psuedo-UserControl in MVC requires four seperate pieces:
A Model class - in this case an Interval class or similar
A PartialView that knows how to render the Model to HTML
A jQuery script to layer interactivity on top of the PartialView's HTML
A ModelBinder that can deserialise postdata into an instance of the Model class.
The ModelBinder is important because it deals with data coming back from the user. Without it, every Controller that wanted to display a to/from date selector in any of its Views would have to know how to assemble the six postdata fields - and how to cope if they were invalid or some were missing.
Two ways that I can think of. A partial view though this doesn't really transfer well from app to app because you are moving around ascx files. Not a big pain but not my flavour.
I prefer to use WebControls. They are super easy in mvc and all you need to do is reference the library in the project and possibly in your config file and there you go.
I think some of the answers have missed out on the postback functionality of controls. One way you could handle that is to pass any generic information via ViewData when rendering your partial view. That could then post back to its own control, which in turn could redirect to the UrlReferrer.
Its a little messy and use of UrlReferrer poses a security risk. But it is one way around the problem
You can create a jQuery plugin.
As user-controls provided in ASP.NET Webforms, MVC provide a lot of ways to make the controls and code that can be reused in other app.
Using Partials If your partial code have some C# logic and render the html using Razor/aspx code then it's bst to maintain them in razor file.
Write JavaScript Functionality as plugin If you maintain your code and write it as better as it can be used in other app then it would be a huge advantage for you. Next time when you work on other app just open this solution copy it and modify it. Write JavaScript code that can be used as plugin maybe take some more brainstorming.
Write Code As a Separate C# library If some code is too common for every app you make.for example you write a member authentication system or some global function (C#) that are used in every app you made then maintain them in a separate solution so it can be used in other app you made whenever you trying to make a new app in future.