0

I'm working on a C# MVC project and need to pass some data from controller to all views.

My task was to save a webpage to a pdf file.

there are total of 5 pages so 5 different views, I also have 5 controllers, one for each view.

I created a extension class of controller so functions inside it can be used by all controllers.

As I need to render the view differently, I need to pass a parameter to each view to toggle the display (i.e. if it is for generating pdf I only need the main content on the view without the menus and links, otherwise display the whole view.)

Here is my implementation:

ControllerExtension.cs

public GenerateAllPagesAsPdf
{
    bool DisplayMainContentOnly = True;

   SaveWebPagetoPDF(MVC.Controller1.Index(DisplayMainContentOnly ), pdf1)
   SaveWebPagetoPDF(MVC.Controller2.Index(DisplayMainContentOnly ), pdf2)
   SaveWebPagetoPDF(MVC.Controller3.Index(DisplayMainContentOnly ), pdf3)
   SaveWebPagetoPDF(MVC.Controller4.Index(DisplayMainContentOnly ), pdf4)
   SaveWebPagetoPDF(MVC.Controller5.Index(DisplayMainContentOnly ), pdf5)

   DisplayMainContentOnly = False;
}

Controller1.cs

[HttpGet]
[Page("View1")]
public virtual ActionResult Index(bool DisplayMainContentOnly)
{
    TempData["mainOnly"] = DisplayMainContentOnly;
    model1 = new Model();           
    return this.View(model1);
}

View1.cshtml

@{
    bool mainOnly= (bool)TempData["mainOnly"];
}

@if (mainOnly) {
    <div>
        <h2>@Html.Heading()</h2>
        @RenderBody()
    </div>
} else {
    <div>
        <h2>@Html.Heading()</h2>
        @RenderBody()
    </div>
    <div id="mc-column-wrapper">
        @Html.Action(MVC.Home.Menu())      
    </div>
}

And all other controllers and views have same implementation of Controller1 and View1, using TempData directory to pass the parameter. I don't want to add this bool variable to each model of the views

I tried to set TempData directory in my ControllerExtension class but it doesn't pass the parameter to the views

Just wondering, is there any other way to pass the parameter to all views instead of pass it to all controllers' actions?

thanks

Justin
  • 927
  • 11
  • 24
  • Is there a reason why you can't place DisplayMainContentOnly on your model? – David L May 07 '15 at 02:36
  • @DavidL I can, but for me adding the same bool variable to 5 models seems like a overhead. Just try to find a way to do it only once. I was thinking about add a global variable to my ControllerExtension class and then access this global variable from each view. But should the view know anything about the controller? – Justin May 07 '15 at 02:43
  • 1
    No, it shouldn't. The view should only know about the model and even then, it really shouldn't make a lot of rendering options based on the model. It seems like you should think about rendering different views that may or may not include partials (that render navigation, links, etc) and that should be chosen by the controller. – David L May 07 '15 at 02:53
  • 1
    What about a base class for your view models that includes the DisplayMainContentOnly? Descend your other view models from that. – TheEdge May 07 '15 at 05:21

1 Answers1

0

I did some research and finally find the following solution which suits my needs, not quite sure whether it is the best way to do it.

the function SaveWebPagetoPDF(string url, string outputFileName) is converting a webpage of passed in url and save the converted file as a pdf file.

I add one extra step in the SaveWebPagetoPDF function to append the parameter to the url as querystring.

url = url + "?DisplayMainContentOnly=true";

And in my view, instead of checking TempData, I'm checking the QueryString:

bool mainOnly= Request.QueryString["DisplayMainContentOnly"] == null? false : Request.QueryString["DisplayMainContentOnly"] == "true";

By doing this, I'm no longer need to add parameter to all of my controller action methods

[HttpGet]
[Page("View1")]
public virtual ActionResult Index()
{
    model1 = new Model();           
    return this.View(model1);
}
Justin
  • 927
  • 11
  • 24