How do I access a ViewBag.Title after it has been set by the underlying View?
Asked Answered
P

1

4

Here's the thing. I have a MVC Action, and on that action, I have applied a custom ActionFilterAttribute to get the deserialization working. Now, what I want to do, is set some header based on the ViewBag.Title that is set inside this view.

I've tried wrapping the ViewResult in my own, and overriding the ExecuteResult but the ViewBag is always empty :-(.

Is this even possible or does the MVC engine reset the ViewBag once the _layout is executed?

Update: Let me post some code samples, to make clearer what I want to do. I have an email service, where I render the body from a MVC view. So my view looks like this:

@{ViewBag.Title = "EventCreated";}

Something that ressembles an email message here.

Now I have a Controller, with an action that looks something like this:

 public ActionResult HelloWorld(MailView<HelloWorldMessage> msg)
        {
            Response.Headers["subject"] = "Test subject";

            return View(msg);
        }

I want to make that Headers["subject"] statement to look like Response.Headers["subject"] = ViewBag.Title; and I want to do be able to let the View think it's handling a normal web page.

I've tried using an ActionFilterAttribute and overriding OnResultExecuted but couldn't get it to work.

One possible option is to set it on the layout page and actually decide based on certain criteria which layout to use. That way I can still keep the Reponse thing away from my views but make it rather clean. What do you think?

Thanks, Anže

Pyorrhea answered 2/6, 2011 at 15:22 Comment(6)
I'm very confused can we see some code pointed with things you want to accomplish?Trimer
Ok, I've added an example to hopefully make it clearer. Better?Hampden
If I'm understanding you correctly, you want to update the ViewBag from the view itself?Trimer
@Trimer I want to have something on the controller that reads the data from the ViewBag after the View is rendered. So the flow would be -> Controller executes the action -> View gets rendered & parsed, updating the ViewBag accordingly -> Controller (or something) reads data from ViewBag and performs something with the data.Hampden
Why don't you just make an AJAX call from the view with the information you want and then you can have another action method that takes care of that?Trimer
I need to add something to the Response headers so that's not an option. Needs to be server side, before the response is outputed to the browser.Hampden
P
3

Try this - assign the output of the view result

var output = View(msg);
//do your other viewbag stuff here
return output;

Why all of this though - I didn't follow when you said "and I want to do be able to let the View think it's handling a normal web page."

Edit: Why don't you then just set this via a helper method in your View? ala

@{
   SetTitle("Home Page");
}


and

@functions {
    public void SetTitle(string title)
    {
        ViewBag.Title = title;
        Response.Headers.Add("title", title);
    }

}

Phillipp answered 2/6, 2011 at 20:45 Comment(2)
Nope, this doesn't work. I tried it out, but the View isn't executed until the result gets rendered, if I remember correctly. I'll try another approach.Hampden
In the end, this is the approach I took.Hampden

© 2022 - 2024 — McMap. All rights reserved.