17

I have an action method that looks like this:

public ActionResult Index(string message)
{
  if (message != null)
  {
    ViewBag.Message = message;
  }
  return View();
}

What happens is that the url of a request to this will look like:

www.mysite.com/controller/?message=Hello%20world

But I want it to look just

www.mysite.com/controller/

Is there a way to remove the query string inside the actionmethod?

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
willvv
  • 8,439
  • 16
  • 66
  • 101
  • 1
    are you saying you want a default message when they do not enter a querystring? Or that you want to hide the querystring regardless of the type of message sent on the url initially? – Erik Funkenbusch Mar 12 '12 at 18:55
  • The second one, basically I want to process the message (it can be anything) and not show it on the url. – willvv Mar 12 '12 at 19:30
  • Check this : https://stackoverflow.com/questions/21280071/clear-or-remove-query-string-in-asp-net – Kiran B Jul 21 '20 at 06:14

5 Answers5

22

No, unless you use a POST method, the information has to get passed somehow. An alternative may be to use an in-between class.

// this would work if you went to controller/SetMessage?message=hello%20world

public ActionResult SetMessage(string message)
{
  ViewBag.Message = message ?? "";
  return RedirectToAction("Index");
}

public ActionResult Index()
{
  ViewBag.Message = TempData["message"] != null ? TempData["message"] : "";
  return View();
}

Or. if you simply used a POST

//your view:
@using(Html.BeginForm())
{
    @Html.TextBox("message")
    <input type="submit" value="submit" />
}


[HttpGet]
public ActionResult Index()
{ return View(); }

[HttpPost]
public ActionResult Index(FormCollection form)
{
  ViewBag.Message = form["message"];
  return View();
}
Seb Nilsson
  • 26,200
  • 30
  • 103
  • 130
naspinski
  • 34,020
  • 36
  • 111
  • 167
  • 1
    Yep, just what I thought. I ended up doing something similar: if (message != null) { TempData["Message"] = message; return RedirectToAction("Index"); } if (TempData.ContainsKey("Message")) { ViewBag.Message = TempData["Message"]; TempData.Remove("Message"); }, which basically saves the message and then reloads the same actionmethod without parameters. – willvv Mar 12 '12 at 19:28
  • Is this still the best solution? I have a page only display at certain hours, and it takes a model, but this action isn't publicly accessible and I want it to have a pretty URL like /Registration/AfterHours and not /Registration/AfterHours?DateTime...[crazy chars]. Regardless, this does work. – Evan Morrison Jun 28 '16 at 03:52
5

You can remove the query string by adding some JavaScript in the razor view.

@section scripts{
    <script>
        if (location.href.includes('?')) { 
            history.pushState({}, null, location.href.split('?')[0]); 
        }
    </script>    
}

If you navigate to page

www.mysite.com/controller/?message=Hello%20world

Then it'll show

www.mysite.com/controller/

in the browser.

Most modern browsers support this (browser support).

Ohlin
  • 4,068
  • 2
  • 29
  • 35
2

Look into routes. They define how a url with parameters will be written.

If you create a new MVC application, and look at the Global.asax.cs file under `RegisterRoutes(). you should see one entry.

routes.MapRoute(
   "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "home", action = "index", id = UrlParameter.Optional } // Parameter defaults
        );

Look at each part:

  • "Default" is the name. This just has to be unique for each route you create.
  • "{controller}/{action}/{id}" is the pattern you want to use. example.org/home/index?id=2 will be written example.org/home/index/2 instead
  • new { controller = "home", action = "index", id = UrlParameter.Optional } is defining the defaults if nothing is specified.

So, that route make it so if you go to example.org it will assume you mean example.org/home/index{id is optional}.

Working from that, you can start to see how to create your own routes.

Now, addressing your question the short answer is yes you could make the URL look like that, but not really. You would have to define a route with a default message, and it would only look like that if someone didn't specify a message. You have to tell the controller what the message is. I'm sorry, but the best you can do is define a route that gives you

/message/Hello%20World and using string.replace make that look even nicer `'/message/hello_world'

1

I'm not sure you're really thinking that through. If you remove the query string... then you remove the query string.. ie, your page won't have the query string value to do whatever it needs to do.

There's a bunch of different hacks you could do.. all of them are not ideal. You could use javascript to strip out the query string. You could redirect to a querystring-less page after setting a session variable.. it's all pretty ugly.

Remember that what the user sees in the address bar is on the client. The client controls that. You can fiddle with it via javascript, but doing so is generally a bad idea. Since hiding things from the user can be considered malware-like behavior.

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
0

I recommend using a slug. Check out this post: SOF Slug post In previous applications, I took this approach to remove querystrings from the URL.

Community
  • 1
  • 1
JoshYates1980
  • 3,476
  • 2
  • 36
  • 57