4
votes

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.

2
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
@Darin: I've added an example. There may be a better way to accomplish this unrelated to how i've done it.Xodarap
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
@marcind: I want to call this exact helper function in the AJAX case.Xodarap
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

2 Answers

0
votes

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

public PartialViewResult Single(string partialName) {
    return PartialView(partialName);
}
0
votes

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.