how to print an MVC3 "page" to pdf - model-view-controller

What is the best way to output an MVC page as PDF and switching the master page to a different master page?
I was thinking I could add a parameter to the query string like format=pdf
and set some sort of filtering that capture the output and transform it to a pdf.
Using classic ASP.NET I did that in an HttpModule.
What is the best way of doing it in MVC?
I have to be able to "print" all the pages in my application, so a FileResult controller method would not work.
I need something generic that can work with every url adding that specific query string parameter

Write a FileResult controller method.
How to create file and return it via FileResult in ASP.NET MVC?
As part of the return result you set the MIME type.

Related

Request page content through System.Net WebClient in asp.net MVC

Umbraco ver. 4.7
My project is running along side asp.net MVC 4. I have a Umbraco page, which has a Rich Text editor property on the document type, that will retain a body of text with HTML.
Is there a way to use a System.Net.WebClient client, and request the Umbraco page from within my MVC project and have it return the content of that page's document property to the MVC controller's WebClient request?
Bonus Question:
Is there a way to setup an Umbraco macro in the template that will parse the querystring params and have place holders in the Umbraco template that the macro will replace the placeholders with the parsed out querystring params before the content is returned to the request (explained up above)?
Have you used the /Base extension in Umbraco? I believe this may help you out, because I had similar requirements and found /Base extremely powerful. In my document type I actually used a multi-line textbox as input for the html (or in my case Razor script). In my /Base class I created a method that finds the correct node, takes the raw script from the textbox, renders the script into a raw html string, and returns the string wrapped in a tag .
public static string GetRazor()
{
var doc = new DynamicNode(nodeId);
string razorScript = doc.GetPropertyValue("{propertyAlias}");
string razorString = RenderRazor.RenderRazorScriptString(razorScript, nodeId);
return razorString;
}
Another way is to create a macro within Umbraco which your template can call, something like:
#using umbraco.MacroEngines
#{
dynamic node = #Model;
string htmlString = node.GetPropertyValue("{propertyAlias}");
#Html.Raw(htmlString)
}
Then inside your template, you just need to inject the macro:
<umbraco:Macro Alias="{RazorAlias}" runat="server"></umbraco:Macro>
Whatever html in your textbox will be rendered by the razor engine!
-Dan
Add a reference to umbraco.dll and umbraco.MacroEngines.dll in your MVC4 project.
You should then be able to do (within your controller or view):
dynamic d = new DynamicNode(nodeId);
return d.AliasOfRichTextProperty

MVC3 Finding a control by its Name

I have a C#.Net web app and I am trying to access one of the HTML/ASP Text Boxes in the Controller for the Edit View of my Proposal model. In a non-MVC app, I was able to do this using Control.ControlCollection.Find(). Is there an equivalent for a MVC3 project?
You ask for an equivalent of Control.ControlCollection.Find() in MVC?
In MVC your controller is not aware of controls.
The controller just receives data via parameters and returns data via the function result.
What do you want to do with the control in your controller code?
If you want to access the value, you should bind it to a parameter:
View:
<input name="MyControl" type="text" />
Controller:
public ActionResult MyAction(string MyControl) {
// MyControl contains the value of the input with name MyControl
}
The MVC pattern was designed to keep things separated.
The View has no knowledge of the controller at all
The Controller only knows that a view exists and what kind of data that it needs. It do not know how the data is render.
Hence, you can never get information about controls/tags in the view from the controller. You need to use javascript/jQuery in the view and invoke the proper action in the controller.
In an MVC-application you don't have controls like in a webform-application.
In MVC you collect your required data in the controller and pass it to the view.
Typicaly the view is a HTML-page with embedded code.
In opposite to controls in webforms which produce HTML and handles the post-backs in MVC you have to do all this manually. So you don't have controls with properties and events wich you can access easily in the controller and you have to handle all your posts with your own code.
Thats sounds as it is a lot of more work - and indeed it could be if you implement the behaviour of complex controls - but MVC applications are much better to maintain and you have 100% influence to the produced HTML.
Well probably i am late for this but it should help others in future...u can store ur value in hidden field in view and then access that value in controller by following code..
Request.Form["hfAnswerOrder"].ToString();
Point - hfAnswerOrder is the ID of the hidden field
My Control in cshtml page..
#Html.Hidden("hfAnswerOrder", Model.Answers.ToList()[0].AnswerOrder)

How to load a Razor view and render it on the fly?

I have a custom CMS built with ASP.NET WebForms (you can see it in action at Thought Results). Now I want to build it using ASP.NET MVC 3 (or even 4). I don't want to change the architecture that much, therefore, I need to dynamically load a Razor View, and dynamically run a Model Loader method, and give the model to the view dynamically, then render the view, and return the result rendered string, all done in server.
In ASP.NET WebForms, my code is:
string renderedString = "LatestArticles.ascx".LoadControl().GetReneredString();
Now, I'd like to be able to write a code line like:
string renderedString =
"LatestArticles.cshtml".LoadView().BindModel("ModelBinderMethodName").Render();
I know about many questions about rendering a view (view to string), but I didn't find what I want.
You may checkout RazorEngine.

Telerik MVC Grid routes?

I have a view with a Telerik MVC grid. The grid uses ajax to select the data from the server. However when i use firebug to check the performance of it, it says thats its accessing the following url to get data:
http://localhost:61094/Grid/_BigGridBinding?Test-size=20
It gets the data correctly (no problem), but it looks very bad to have a Test-size 20 attached to it. I have tried to change my routes since its most likly a routing problem, but with no succcess. Anyone got any idea of how to change the route to get rid of this Test-size 20 and instead add it like /_BigGridBinding/20 (or similar).
The method signature that the grid is calling looks like this:
[GridAction(EnableCustomBinding = true)]
public ActionResult _BigGridBinding(GridCommand command)
I am using MVC 3 and the newest Telerik Controls.
The post URL is automatically built by the Telerik grid, so I'm not sure there is any way to get rid of the Test-size parameter. Routes take a given URL and extract the parts of the URL and map them to appropriate controller actions and parameters, so I don't think changing the routes will have any effect (since the URL is already built by the time the routing engine processes it).
That said, the query string parameter is constructed using the name of the grid. In your case, Test is the name of the grid, so the parameter is Test-size=20. So if that is what your concerned with, you can rename the grid to something more appropriate and the query string parameter will be named accordingly. For example, renaming the grid to BigGrid will result in a parameter BigGrid-size=20.

ASP.Net MVC 3: Multiple views/urls to one controller action

I'm trying to do the following with ASP.Net MVC 3:
I have a lot of "flat pages", which are basically html documents with no dot.net code attached.
I want to be able to request these pages through routed URLs, but I do not want to manually add each url to the routes.
So my question is: Is it possible to define a default route, which uses the same controller / action, but returns a view based on the URL requested ?
e.g. /home/about and /profile would use the views /home/about.cshtml and /profile.cshtml
but both would use the same controller and action, which pretty much just goes:
return View();
The reason: I'm doing all the pages of the site, which require dot.net code. However another person is doing all the "flat pages" (informative pages, etc.).
I want him to be able to add new pages, by just adding a cshtml file (like he would with webforms creating aspx files, with no code-behind)
This is necessary because I'd otherwise have to edit global.asax each and everytime he adds a page, which is quite often.
If this is not possible, I'll have to stick with webforms, which I really don't want to :-(
You can make an action that takes as a parameter the name of the View; Something like this:
public ActionResult StaticPage(string viewName)
{
return View(viewName);
}
Then define a route so the viewName isn't a parameter but instead is part of the URL:
"/Static/{viewName}"

Resources