capturing output in ASP.NET MVC - asp.net-mvc

I have a need to capture all the rendered output/html of a view so that I can persist the result. How can I do this within ASP.NET MVC?

There's a great post about partial output caching and includes code about how to capture output using an attribute.
The post: http://blog.codeville.net/2008/10/15/partial-output-caching-in-aspnet-mvc/
The code: http://blog.codeville.net/blogfiles/2008/October/ActionOutputCacheAttribute.cs

MVC Views output to the response stream via an HtmlTextWriter object in the HttpContext. So, one way to accomplish your task is to replace the existing HttpContext object with a new which contains an HtmlTextWriter that is outputting to a StringBuilder rather than the response stream.
This is reasonably straightforward if a little complicated and is covered in some detail in this blog post: http://andrewlocatelliwoodcock.com/2011/04/28/capturing-the-output-of-a-view-as-a-string/
I have used this technique successfully to capture View output as it is sent to the browser.
Don't forget: if you want to actually see the View as well, once you have captured the output you will also need to write it to the response stream ...

Related

Render Razor View inside of WCF service

It's a quite odd task to do, but I can't change the requirements. We have to write a WCF service (SOAP, not REST) and return an HTML as a property on response object.
I don't want to use:
hard-coded strings and use string.Format() to fill in some values;
t4 template as not many people can support this approach in the future;
WebForm controls as most of our developers are used to work with MVC projects.
I already know how to render some ActionResult to a string. So, ideally, I would like to be be able to create a controller, invoke some action and get an ActionResult.
For that, I created MVC application and added service.svc file to it. Service work fine - I can invoke its methods and receive results. But my problems start when I try to render Razor View. If I simply create an instance of any controller and then invoke an action, controller's property ControllerContext is null and hence View can't be rendered. I tried crafting ControllerContext on the fly, but seems like I'm missing something.
I found very similar question here, but the solution offered there didn't work for me as HttpContext.Current is null inside of wcf methods.
Does any body know how to achieve that? Or maybe somebody can sugggest other simple and flexible way to render HTML inside of WCF method?
You should also have a look at the Nancy framework (http://nancyfx.org), as their implementation of the RazorEngine is more lightweight.
I've had a fair amount of success using Nancy to generate HTML on demand - because it was designed as being inherently testable, you can abuse it to your own ends as a templating framework pretty easily.
You will need to host the Razor Engine in your app. Look at this article Rendering ASP.NET MVC Views to String, especially the section "Rendering without a ControllerContext"
Also, much more info can be found in this answer Render a view as a string. (The are several "correct" answers, with different contexts)

Razor: #Html.Partial() vs #RenderPage()

What is the appropriate way of rendering a child template?
And what's the difference? Both seem to work for me.
And why does #Html.RenderPartial() no longer work?
Html.Partial("MyView")
Renders the "MyView" view to an MvcHtmlString. It follows the standard rules for view lookup (i.e. check current directory, then check the Shared directory).
Html.RenderPartial("MyView")
Does the same as Html.Partial(), except that it writes its output directly to the response stream. This is more efficient, because the view content is not buffered in memory. However, because the method does not return any output, #Html.RenderPartial("MyView") won't work. You have to wrap the call in a code block instead: #{Html.RenderPartial("MyView");}.
RenderPage("MyView.cshtml")
Renders the specified view (identified by path and file name rather than by view name) directly to the response stream, like Html.RenderPartial(). You can supply any model you like to the view by including it as a second parameter
RenderPage("MyView.cshtml", MyModel)
I prefer
#RenderPage("_LayoutHeader.cshtml")
Over
#{ Html.RenderPartial("_LayoutHeader"); }
Only because the syntax is easier and it is more readable. Other than that there doesn't seem to be any differences functionality wise.
EDIT: One advantage of RenderPartial is you don't have to specify the entire path or file extension it will search the common places automatically.
The RenderPartial method doesn’t return HTML markup like most other helper methods. Instead, it writes
content directly to the response stream, which is why we must call it like a complete line of C#, using a semicolon.
This is slightly more efficient than buffering the rendered HTML from the partial view, since it will be written to the
response stream anyway. If you prefer a more consistent syntax, you can use the Html.Partial method, which
does exactly the same as the RenderPartial method, but returns an HTML fragment and can be used as
#Html.Partial("Product", p).
We can also pass model using partial views. #Html.Partial("MyView","MyModel");
#RenderPages()
The above does not work in ASP.NET MVC. It only works in WebPages.
#Html.Partial("_Footer")
You will need to use the above in ASP.NET MVC.
For ASP.NET Core 7. In the Shared folder make partial file then user this following code
<partial name="_NavBar" />

Should I write from Controller, Code Behind, or Helper in MVC?

I've seen all the questions and answers around not having code-behind for a view, however I have a case where I need complex logic to generate the presentation (view) layer. I have to output a PDF file based on data obtained from db. Where is the best place to generate this PDF and write to the response stream? Doing response.write from the controller feels very wrong to me, but I would like responses to this, and to using a code-behind file for the view to generate the PDF. I suppose I could encapsulate the data in a viewmodel class and pass that to a Helper method to generate the output as well, what would be considered best practice in this case, specifically having a lot of logic around creating the PDF?
I would create a ActionResult class for this and return that from the controller. The ActionResult class is responsible for writing stuff to the output stream.
The better way to do it is by defining an ActionResult specific for outputting pdf files. This way you can reuse the code easily also in other applications

Asp.Net WriteSubsitution vs PartialView - the right way

I have a partial view that should not be cached in a output cached MVC view.
Usually you write non-cached content by using Response.WriteSubstitution.
The problem is that WriteSubstitution takes as a parameter a HttpResponseSubstitutionCallback callback which looks like this:
public delegate string HttpResponseSubstitutionCallback(System.Web.HttpContext context)
This is where things get complicated since there is no easy/fun way to generate the html on the fly.
You have to do a hack like this.
So the question is: Is there an easier way to make a partial view not cached ?
See Phil Haack's article on donut caching in MVC. Phil takes advantage of the existing API to create a new HtmlHelper method to provide a callback that can render the non-cached code. His supplies an anonymous method to the helper to specify the callback. To get this to work unchanged, you'll still need to have a method that renders a partial view to a string, though I think it would be easier to do in an HtmlHelper -- just look at the source for RenderPartial and RenderPartialInternal and see what changes would be needed to write it to a MemoryStream instead of the Response -- I believe it would be the same code except you'd supply your stream instead of the Response output stream, then convert your stream to a string.
It might look like this:
<%= Html.Substitute( cb => Html.RenderToString( "Partial" ) ) %>
Phil indicates that it might make it in to ASP.NET MVC 1.0, but I think it's only available in the MvcFutures assembly.
In MVC2 we can use Html.Action to easily obtain the substituted html. Yeeeeiii
But Response.WriteSubstitotion is not working anymore. Aaaahhhh

How to update Model in MVC

I'm wondering how you keep a constant value of the Model in an ASP.NET MVC framework. Like when adding something to the Model through the view. You go back to an action in the controller but where do you keep the Model? Is it a private in the controller? or is it passed back and forth from the view to the controller because if it gets big then you are passing alot of data back and forth to add/delete a single item from the Model.
Also any small examples to show this?
Thanks
What are you referring to? Are you meaning a database table loaded up into an object such as Ruby on Rails's ORM -- typically the 'Model' is a series of interfaces or domain objects that load data into objects from the database .. or more simply just the database period.
Please be more specific. There are many MVC frameworks and many different kinds of 'Models'
I think you should check out a ASP.NET MVC tuturial like NerdDinner (from "Professional ASP.NET MVC 1.0"). Scott Guthrie has posted a html version of the tutorial on his site. It's a fairly simple site that they build in the tutorial, and is a great intro to ASP.NET MVC (in my opinion).
There are also some good tutorials on the ASP.NET site.
Hope these help you with .NET MVC, it's a great framework to use!
You can pass the model to the page and you can then use UpdateModel(model name) within your controller.
Each member in the model must be a property with a getter and a setter.
On the page you can hold the data in say a hidden field if you need to maintain the value outside of state.
If you have problems using UpdateModel then you can use the following in your controller;
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult MyAction(int? id, FormCollection collection)
{
string commentText = collection["myFieldName"];
}
This will normally get your values from the model.
Hope this is what you were asking.
Think of the model as a data transfer object. In a list, display only or edit page, you pull it out of a data layer as a single object or a list of objects. The controller passes it along to the view and it gets displayed.
In the case of an insert, a new data transfer object is instantiated upon post back and is updated with the posted values. Then sent back to the the data layer for persistence.
In the case of an edit, it comes from the data layer on the HTTP GET request and is used to pre-populate the HTML form. Then on post back, the data transfer object gets updated with the posted values and sent back to the the data layer for persistence.
Definitely checkout NerdDinner or Stephen Walther's samples.

Resources