问题
I'm using ASP.NET MVC to separate my HTML views from my Models. However there's a specific situation that is confusing me slightly.
I have several commonly used small panels of information, which themselves are comprised of a number of smaller panels of information. these get their data from a subclass contained within the various models, sometimes single instances, sometimes lists of objects.
At present this is done using Partial views, passing the appropriate piece of data via the model parameter, as such:
@Html.Partial("UserInfo", this.Model.CurrentUser);
@Html.Partial("UserInfo", reply.PostedBy);
And so on. This all works fine.
I've recently hit a requirement which feels like it stretches sensible limits for this model however - it will involve a very large number of partial views with a TINY amount of HTML in each, nested numerous times. The page resolution time seems to be starting to get a little out of hand, and I suspect the amount of searching for and reflecting partial views might have something to do with it.
Please note: I'm assuming duplicating HTML which is supposed to be the same is still to be avoided. I could simplify the nest by having copies of HTML in some of the higher level controls, but it strikes me this damages maintainability.
For the inner most ones it would seem to make more sense to me to create static helper classes which generate and return the required HTML - however, despite the fact MVC itself does it with the Html
helper class, it feels like this goes against the MVC pattern.
- Is it OK to use static helper classes to generate small HTML snippets?
- Where should the static
UserInfo
class go? Views? Controllers? Elsewhere?
Obviously this approach still separates the helper method from the model, but as it takes a model in to work with, I don't really see how uncoupled it really is.
A static helper is a hairs breadth away from an extension method, consumable in a userInstance.InfoHtml()
type of way, which just seems to make the whole approach really similar to just adding the helper method to the model. This is of course what MVC is trying to get away from in the first place!
Please note: I'm not trying to sneak around the rules or complain! I just want to approach this as "on pattern" as possible. If lots and lots of partial views is the way, I'll stick with that and performance tune as best I can.
回答1:
I believe there are four common solutions to reuse html as you want in the question.
- Partial views (
@Html.Partial
); - Child Actions (
@Html.Action
); - Custom static helpers (
@Html.Whatever
,@Url.Whatever
, extension methods to your models, etc); - Razor helpers. (
@helper
)
Is it OK to use static helper classes to generate small HTML snippets?
Is it absolutely OK to use static helper classes to generate small HTML snippets. I don't like the idea to add them as methods to the models, extension methods are OK.
I would say the difference between the approaches lies mostly in coding style and personal preferences. I would use partial views just to break a large view into consumable pieces, child actions for really common and independent parts of the application (like a widget or a login box), so I don't have to populate all my view models with the data for common things. I would go static helpers or razor helpers for very small html fragments (a field in a form) with static helpers for more code and razor helpers for more html.
Where should the static UserInfo class go? Views? Controllers? Elsewhere?
These things belong to View from the pattern perspective. If you ask which folders should you populate in the solution, I would recommend a special folder for them (maybe HtmlHelpers
). There is probably a restriction for shared razor helpers to reside in App_Code
folder.
I think the following questions will give you more on how to choose between them:
- Creating reusable HTML view components using Razor in ASP.NET MVC;
- How to create reusable control in ASP.NET MVC;
- How to create a reusable piece of HTML with dynamic contents;
- ASP.NET MVC: Razor @helper vs extension methods to HtmlHelper - which is preferred?.
UPDATE
There may be a fifth solution in the new ASP.NET MVC: View Components. As far as I read you can use them instead of child actions.
回答2:
It's hard to say what your best path is based on what you've provided here. A lot of it depends on what you're working with and what you're trying to achieve.
For example, the user info stuff you're currently including via partial views, sounds like it would be better served by a child action:
[Authorize]
public class AccountController : Controller
{
...
[ChildActionOnly]
[AllowAnonymous]
public ActionResult UserInfo()
{
// get your user info here
return PartialView("UserInfo", userInfo);
}
}
And then in your view/layout:
@Html.Action("UserInfo", "Account")
Then, you don't need to make sure that there's a user object populated on whatever view model you're working with.
Next, the Razor helper methods like Html.Partial
, etc. are themselves simply extensions to either HtmlHelper
or UrlHelper
for the Url.*
helpers. There's nothing wrong with adding your own extension methods. It was quite common to extend HtmlHelper
with a custom EnumDropDownListFor
, for example, before it got baked into MVC 5 out of the box. However, extensions are really best suited to small bits of HTML, which seems to be what you want to work with here. For large blocks of HTML it just makes better sense to use partials. Either works, though. It's largely up to you to just decide what makes the most sense for your application.
来源:https://stackoverflow.com/questions/28725037/helper-methods-to-generate-small-html-snippets