Archive for January, 2008

RenderUserControl from Controller

15 Jan

Ran into a situation today where I wanted to render a ViewUserControl from my controller.  I had a couple of hard times getting this done with the Microsoft MVC CTP1, but finally have it working.  We did this to support using the Prototype observe to get behavior similar to a cascading drop down.

ASPX View Page

 <% using (Html.Form<Web.Controllers.PlaqueOrderController>
          (action => action.Create())) { %>  
       <%= Html.Select("SeasonId", ViewData.Seasons, "Name", "Id")%>  
  <div name="statistic" id="statistic"> 
      <select disabled="disabled">
        <option>Select Sport</option>

 <% } %>
 <script type="text/javascript"> 
   Event.observe("SeasonId", "change", function() { 
          new Ajax.Updater('statistic', '/PlaqueOrder/GetStatistics/'
                           + $F("SeasonId")) }); 


This will observe the season drop down and when it is changed call the PlaqueOrder controller’s GetStatistics action passing the selected SeasonId to the action. The action in the controller then looks like this.  I should mention that I’m using LLBLGen for the ORMapper here.



public void GetStatistics(int id) 
   SeasonEntity season = new SeasonEntity(id); 
   HtmlHelper helper = new HtmlHelper(
                             new ViewContext(this.ControllerContext, 
   string html = helper.RenderUserControl(
                       "/Views/PlaqueOrder/Statistic.ascx", season);


We had to give the absolute path to the RenderUserControl because we kept getting The relative virtual path ‘Statistic’ is not allowed here when we used helper.RenderUserControl("Statistic").  We also had to use Response.Write to get the html created from the ViewUserControl to the browser to replace the innerHtml of the statistic div.  Next is the ViewUserControl.



<%@ Control Language="C#" AutoEventWireup="true"
    Inherits="Web.Views.PlaqueOrder.Statistic" %>
<%= Html.Select("StatisticId", 
                ViewData.Sport.Statistics, "Name", "Id")%> 


And here is the codebehind that types the ViewUserControl to the Season that we are passing as the ControlData.



namespace Web.Views.PlaqueOrder 
   public partial class Statistic : 
   { } 


We had a hard time find much information how to do this.  I’m sure there are other ways to accomplish this, but to us being able to render a ViewUserControl from a Controller is helpful with how we have used Prototype for AJAX communication.


Posted in .NET, Web/Tech