开发者

How to view the controller's resulting html in debug with ASP.NET MVC?

Is there a way that I can see, while debugging, the result (html, xml, json) of a Controller's action.

For instance, I have this in my controller:

    public PartialViewResult Reload(开发者_JAVA百科)
    {
        return PartialView("Index");
    }

While debugging, I'd like to see what HTML will be sent back to the client. Thanks


Browser will show the result anyway

Why would you want to see it in debug mode, while you can see it in your browser anyway. That's where it goes afterwards anyway. If JSON is in question use Firefox + Firebug and you'll see all requests and responses with all related data and info.

If you tell us why exactly would you like to do this, we may suggest a better way of getting you there...

A possible solution

The most likely solution to jump in while data is being rendered is to write your own view engine. And to make it easier on yourself, inherit from RazorViewEngine. This will likely spawn some more class inheriting (i.e. RazorView) but it would get you to a point where view actually get's generated and would do that in an efficient way: view would get rendered only once.

But on the other hand I'd question the rationale again. If you'd be looking at generated HTML right before it gets to the client, what point does that have? Because the next moment this same data gets sent to the client, where you can already observe it without any code manipulation and putting custom code in Asp.net MVC's extensibility points.

Intermediate view manipulation in Asp.net MVC?

No such thing in Asp.net MVC...

You referred in a comment below to observing intermediate view changes during debug when doing things like c.Controls.Add(), but this just wouldn't work, because:

  1. controller action doesn't manipulate views in any way shape or form; it merely prepares data for them and chooses which view will handle that data in however way they implement it; the choosing part can as well be abstracted away from controller actions in which case they'd only prepare data and handle it to some other view-choosing factory;

  2. views are being generated in whole by view engines using ASPX/ASCX/CSHTML files merely as templates:

    • Web forms view engine does parse those templates into object hierarchy, but if most of your view's code is static HTML (which it should be), majority of those controls will just be literals;

    • Razor view engine doesn't use any control hierarchy object model as Web forms engine does; Razor views are just strings, that engine parses character-by-character, line-by-line looking for special directives where it needs to insert view data in; no controls whatsoever...

All in all: no intermediate view manipulation. You can however debug your view while it's being parsed by the view engine though. Just put breakpoints inside a directive within the view.


It is not easy, because partial view result is sent directly to httpcontext.current.response.output, it doesn't return string. You can use this extension method to catch it as string by filtering httpcontext output:

    /// <summary>Renders a view to string.</summary>
    public static string RenderViewToString(this Controller controller,
                                            string viewName, object viewData)
    {
        //Getting current response
        var response = HttpContext.Current.Response;
        //Flushing
        response.Flush();

        //Finding rendered view
        var view = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName).View;
        //Creating view context
        var viewContext = new ViewContext(controller.ControllerContext, view,
                                          controller.ViewData, controller.TempData);

        //Since RenderView goes straight to HttpContext.Current, we have to filter and cut out our view
        var oldFilter = response.Filter;
        Stream filter = new MemoryStream(); ;
        try
        {
            response.Filter = filter;
            viewContext.View.Render(viewContext, null);
            response.Flush();
            filter.Position = 0;
            var reader = new StreamReader(filter, response.ContentEncoding);
            return reader.ReadToEnd();
        }
        finally
        {
            filter.Dispose();
            response.Filter = oldFilter;
        } 
    }

and use it like this during debug:

public PartialViewResult Reload()
{
    var result = RenderViewToString("Index",ViewData);
    return PartialView("Index");
}

Extension method for Spark:

    public static string RenderSparkToString(this Controller controller,
                                            string viewName, object viewData)
    {
        var view = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName).View;
        //Creating view context
        var viewContext = new ViewContext(controller.ControllerContext, view,
                                          controller.ViewData, controller.TempData);

        var sb = new StringBuilder();
        var writer = new StringWriter(sb);

        viewContext.View.Render(viewContext, writer);
        writer.Flush();
        return sb.ToString();
    }


What prevents you from just hitting the Route that renders the partial view and view source?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜