4

I have a partial view that I want to be generic. According to this question, partial views cannot be generic. So I instead made an HtmlHelper extension that handles the pieces for which I want type-safety, then hands off the rest to a real partial view.

Usually my helper is called on page load, which works fine, but sometimes I want to add a row or something through AJAX. When this happens, the controller cannot use my "partial view" since it does not have access to the HtmlHelper.

Apart from having a partial view with a model of type object, is there anything I can do?

I'm using Razor, if that is important.

A simplified version of what I'm doing:

public static MvcHtmlString DoStuff<T>(this HtmlHelper html, IEnumerable<T> data,
   Func<T, ViewModelType> StronglyTypedFn, string PartialName)
  {
  // the pre- and post-processing for the partial view is complex enough I'd like
  // to encapsulate it. But I want the encapsulation to include the safety 
  // benefits that generics give.
  var mappedData = data.Select(StronglyTypedFn);
  string htmlData = "";
  foreach(var model in mappedData){
    htmlData += html.Partial(PartialName, model);
  }
  htmlData += "some boilerplate footer html";
  return htmlData;
}

I realize that in this example I have so few lines of code outside the partial view that it seems pointless to have a helper, but in my real example it is more complex.

Now, in an ajax call I want to return Html.DoStuff(). But I can't, because this requires access to the HtmlHelper, and the helper isn't available inside a controller.

Community
  • 1
  • 1
Xodarap
  • 11,581
  • 11
  • 56
  • 94
  • I don't fully understand your scenario. Could you show how this helper looks like and how you are calling it from your view? – Darin Dimitrov Feb 16 '11 at 18:15
  • @Darin: I've added an example. There may be a better way to accomplish this unrelated to how i've done it. – Xodarap Feb 16 '11 at 18:25
  • So what is the exact problem? Your code looks fine. You allude to "the controller cannot use my "partial view" since it does not have access to the HtmlHelper" but it's unclear what you are trying to do in the AJAX case. – marcind Feb 16 '11 at 19:02
  • @marcind: I want to call this exact helper function in the AJAX case. – Xodarap Feb 16 '11 at 19:31
  • 2
    I think you could just have a new action method that would call the helper for a single item. Would that work for you? – marcind Feb 16 '11 at 20:05
  • @marcind: how? Controllers don't have access to `HtmlHelper`, right? – Xodarap Feb 16 '11 at 20:25
  • @Xodarap see my response – marcind Feb 16 '11 at 21:59
  • @Xodarap - the confusion in this question is: what are you trying to do with AJAX? Can you post the AJAX code? that would help us answer the question. For example, is the AJAX code inserting HTML in the middle of everything, or is it refreshing an entire section of HTML using the DoStuff method? – Remus Feb 23 '11 at 23:00
  • Not an answer to your question, but this will help you: In your helper class, use a `StringBuilder` instance instead of the `html+=` to improve performance. – smartcaveman Feb 28 '11 at 13:15

2 Answers2

0

You could just have a simple action method that calls the partial for one model instance

public PartialViewResult Single(string partialName) {
    return PartialView(partialName);
}
marcind
  • 52,944
  • 13
  • 125
  • 111
  • Thanks for the answer, but the problem is that I want to return the whole helper's result. So for my example I would want to return `Html.DoStuff()`. (Unless I'm completely misunderstanding your suggestion...?) – Xodarap Feb 16 '11 at 22:24
  • I might be misunderstanding your question. Maybe you could augment your question with a sample of the kind of output you want for the first page load vs what you want from the ajax request. – marcind Feb 16 '11 at 22:28
  • I think my question was unclear. I want the exact same thing on page load vs. ajax. I'll edit the question. – Xodarap Feb 16 '11 at 22:33
0

You could use a View with a Dynamic type instead of object.

But... It seems as if there's some misunderstanding here because the Controller shouldn't try to render the view at all. Could you post the Controller code?

The better option is, IMO, returning a JsonResult for your ajax request and adding the row/rows on client side using JS.

Linkgoron
  • 4,866
  • 2
  • 26
  • 26