Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encapsulating User Controls in ASP.NET MVC

Sorry if this is a basic question - I'm having some trouble making the mental transition to ASP.NET MVC from the page framework.

In the page framework, I often use ASCX files to create small, encapsulated chunks of functionality which get inclded in various places throughout a site. If I'm building a page and I need one of these controls - I just add a reference and everything just works.

As far as I can tell, in MVC, the ASCX file is just a partial view. Does this mean that wherever I want to add one of these units of functionality I also have to add some code to the controller's action method to make sure the relevant ViewData is available to the ASCX?

If this is the case, it seems like a bit of a step backwards to me. It means, for example, that I couldn't just 'drop' a control into a master page without having to add code to every controller whose views use that master page!

I suspect I'm missing something - any help would be appreciated.

Thanks, - Chris

like image 992
Chris Roberts Avatar asked Nov 07 '09 00:11

Chris Roberts


3 Answers

As far as I can tell, in MVC, the ASCX file is just a partial view. Does this mean that wherever I want to add one of these units of functionality I also have to add some code to the controller's action method to make sure the relevant ViewData is available to the ASCX?

Yes.

However, you can use a RenderAction method in your view instead of RenderPartial, and all of your functionality (including the data being passed to the sub-view) will be encapsulated.

In other words, this will create a little package that incorporates a controller method, view data, and a partial view, which can be called with one line of code from within your main view.

like image 51
Robert Harvey Avatar answered Oct 22 '22 09:10

Robert Harvey


Your question has been answered already, but just for sake of completeness, there's another option you might find attractive sometimes.

Have you seen how "controls" are masked on ASP.NET MVC? They are methods of the "HtmlHelper". If you want a textbox bound to "FirstName", for example, you can do:

<%= Html.Textbox("FirstName") %>

And you have things like that for many standard controls.

What you can do is create your own methods like that. To create your own method, you have to create an extension method on the HtmlHelper class, like this:

public static class HtmlHelperExtensions
{
    public static string Bold(this HtmlHelper html, string text)
    {
        return "<b>" + text + "</b>\n";
    }
}

Then in your view, after opening the namespace containing this class definition, you can use it like this:

<%= Html.Bold("This text will be in bold-face!") %>

Well, this is not particularly useful. But you can do very interesting things. One I use quite often is a method that takes an enumeration and created a Drop Down List with the values from this enumeration (ex: enum Gender { Male, Female }, and in the view something like Gender: <%= Html.EnumDropDown(Model.Gender) %>).

Good luck!

like image 38
Bruno Reis Avatar answered Oct 22 '22 07:10

Bruno Reis


You can render a partial view and pass a model object to.

<% Html.RenderPartial("MyPartial", ViewData["SomeObject"]);

In your partial view (.ascx) file, you can then use the "Model" object (assuming you've inherited the proper object in your @ Control deceleration) to do whatever you need to with that object.

You can, ofcourse, not pass and Model and just take the partial view's text and place it where you want it.

In your main view (.aspx file), you will need to define the proper object in the ViewData that you're passing to the partial view.

Another method you can do is use:

<% Html.RenderAction("MyAction", "MyController", new { Parameter1="Value1"}) %>

What the previous method does is call a controller Action, take its response, and place it where you called the "RenderAction()" method. Its the equivalent of running a request against a controller action and reading the response, except you place the response in another file.

Google "renderaction and renderpartial" for some more information.

like image 1
Omar Avatar answered Oct 22 '22 07:10

Omar