views:

1044

answers:

2

If you are going to be generating a page as a string and outputting all the content via Response.Write at the last minute where should you put this code?

I need to be able to dynamically write a bunch of JavaScript to the client to use some of the new Google visualization jsapi. I noticed this last release of the MVC framework "discourages" CodeBehinds on the Views. This is really presentation code. Where should it go? Whats the preferred method here... I was never a fan of the "SingleFile" thing.

+3  A: 

Is the code parameterizable? That is can you control the differences between one invocation and another via some small set of parameters? If so, then I'd consider writing an HtmlHelper extension to generate it. Then I would use the extension in my View to generate the code. Pass the parameters to the View via ViewData from the controller if you can't derive it from the Model or RouteValues.

<%= Html.GenerateGoogleVisAPI( ViewData["someThing"],
                               ViewData["otherThing"] ) %>

Another alternative would be to make it into a ViewUserControl -- to which you can pass a Model and ViewData. You'd still include this via the view.

<% Html.RenderPartial( "GoogleVisControl",
                       ViewData["GoogleVisModel"],
                       ViewData ); %>

EDIT:

My HtmlHelperExtensions usually go in a separate class library project. So my hierarchy would look something like the following. Note that I'm omitting the associated Test projects for each level for the sake of brevity, but they would be in there as well. If you have multiple applications using the same data layer, the data layer may exist in a separate solution entirely depending on whether you have one solution per app or multiple apps per solution. I add project references to the web project for the class library projects.

+-Project.Web
 +-Content
 +-Controllers
 +-Models
 +-Views
  +-...
  +-Shared
   +-Error.aspx
   +-GoogleVisControl.ascx
   +-LoginUserControl.ascx
   +-Site.Master
   +-...
  +-...
 +-...
+-Project.Common
+-Project.Common.Web
 +-HtmlHelperExtensions.cs
 +-...
+-Project.Data
 +...
tvanfosson
Since Javascript is a component of the view I would use the helper approach that tvanfosson suggests.
Todd Smith
First thought, where do you place the code for HtmlHelper extension. Can you edit you answer to include where these go in the project hierarchy. And I guess I would say "no" the stuff is not parameterizable. Its all based on loads of data coming from a ADO.NET DataTable.
tyndall
Second, If I make a this into a UserControl (.ascx) should I use a CodeBehind? I notice it "encourages" me to use a SingleFile design.... but not even that because it doesn't even put in the Page_Load stub
tyndall
So I think decided I'm going to use a UserControl.ascx. Inside it uses a standard html table (but with runat="server" added). This should allow me to DataBind to it. I'm passing in List<T> from NH/Castle Active Record. Where should the DataBind() call go? CodeBehind or SingleFile?
tyndall
Why not do the query in the controller and pass the results in ViewData, then pass that onto the ViewUserControl as the model for the table?
tvanfosson
+4  A: 

You could also use the ActionResult type Content to return a plain string to the browser.

public ActionResult myAction() {
    Return Content("Hello World!");
}

However, I am not sure whether this is the best approach when returning JavaScript. You might want to consider writing your own JavaScriptResult that inherits ActionResult.

Tomas Lycken
+1. I like this concept.
tyndall