1

I'm attempting to add a search string (e.g. http://stackoverflow.com?this=that) to a view returned by a controller. This is being used by JS on the page which I can't change, so other ways to transfer the data aren't an option.

Currently I'm just returning View("Page", viewModel); from my controller, which doesn't seem to allow you to pass anything via the URL.

I tried using return RedirectToAction("a", "b", new { this = that }); but I can't work out how to return the view correctly with both the view model and the URL string.

How would I go about adding on a ?a=b style string to a returned view?

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
DBS
  • 9,110
  • 4
  • 35
  • 53

2 Answers2

4

A view doesn't have query string arguments, a request does. So if this is your controller action:

public ActionResult SomeAction()
{
    return View();
}

then whatever request is made to SomeAction is what needs to have that query string parameter:

http://hostname/Widgets/SomeAction?something=somevalue

The action may accept it as a parameter:

public ActionResult SomeAction(string something)

but it doesn't need to if the server-side code isn't going to do anything with that value.


If the request to SomeAction can't be modified, then you'll need to break this apart into two actions. The first one just redirects to the second:

public ActionResult SomeAction()
{
    return RedirectToAction("Widgets", "SomeOtherAction", new { something = somevalue });
}

public ActionResult SomeOtherAction()
{
    return View();
}

In that scenario the first action's only responsibility is to forward the user to the second action with a particular route parameter. This is necessary because the query string needs to be in a request from the browser, not in a response from the server. So the first action's response is to direct the browser to make a new request with the query string.

David
  • 208,112
  • 36
  • 198
  • 279
  • Not sure why OP accepted this, because they ask for _"return the view correctly with both the view model and the URL string"_, but apparently it works for them. :P – CodeCaster Jun 19 '15 at 13:50
  • @CodeCaster: Well, I didn't include a model in the second action just for brevity. But `SomeOtherAction` can pass a model to the view just like any other action can. – David Jun 19 '15 at 13:51
  • I understood OP wants to build the model in `SomeAction`, and then display it in `SomeOtherAction` after the redirect. – CodeCaster Jun 19 '15 at 14:05
  • @CodeCaster: Seems like a simpler change to build the model in `SomeOtherAction` instead. If the two actions must be chained, might as well put the responsibilities where they belong. The first one redirects, the second one displays. – David Jun 19 '15 at 14:06
  • Well, that depends entirely on the use case. The first can be a POST that creates something, where the result of that action must be displayed upon GET, while those results are not retrievable anymore in any way. But no use in discussing semantics when those aren't exposed by OP. :) – CodeCaster Jun 19 '15 at 14:55
2

I'm attempting to add [query string parameters] to [the URL of] a view returned by a controller.

You can't. A view is rendered in response to a request to a certain URL. The request has already been made on that point by the browser, so logically you can't change the URL anymore.

What you can do is a redirect.

I tried using return RedirectToAction("a", "b", new { this = that }); but I can't work out how to return the view correctly with both the view model and the URL string.

I think the problem you're trying to address there is that your Page action builds some model, which you'd like to access again from the SeachResults page after the redirect.

For that you can set the model in TempData before redirecting. See Using Tempdata in ASP.NET MVC - Best practice. Adapted for your scenario:

public ActionResult Page()
{
    var tempModel = new FooModel
    {
        Foo = "Bar"
    };

    TempData["TempModel"] = tempModel;

    return RedirectToAction("SeachResults" new { searchParameters = "baz" });
}

public ActionResult SeachResults(string searchParameters)
{
    var model = TempData["TempModel"] as FooModel;

    return View(model);
}
Community
  • 1
  • 1
CodeCaster
  • 147,647
  • 23
  • 218
  • 272