UserControl equivalent in MVC3?

2019-02-05 21:26发布

问题:

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?

回答1:

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.



回答2:

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).