Redirect 301 to another action - asp.net-mvc

I have an ASP.NET MVC Action:
public virtual ActionResult Show(Int32 id, String slug) {
} // Show
How can I, inside Show, redirect to another action?
I need to fire the 301 redirect HTTP Error to inform that the old url should be replaced by the new url.
How can I do this?
Thank You,
Miguel

You can use RedirectToActionPermanent.
That said, it is important to know that a response status 301 will make browsers to never ask for the original location again. For a simple redirection (302) use RedirectToAction.
Both methods are used basically in the same way. In this StackOVerflow answer there are some excellent examples.

Related

Asp.net mvc 4 RedirectToAction slow

When I use RedirectToAction("MyView", "MyController") sometimes the redirection is very slow to render the destination view.
It doesn't always happen.
I am using ASP.net MVC4 with IIS7.5
How can I prevent this problem and speed up the redirection?
I will put this here as code will not show very well in the comments section. If the action method you are redirecting to is in the same controller you are currently in, it is simpler and more efficient to call that method directly and return its results instead of the redirect response generated by the RedirectToAction method. Just to make sure we are on the same page, RedirectToAction actually returns a redirect response (302) to the client asking it to issue a new request to the action method you have specified as per MSDN http://msdn.microsoft.com/en-us/library/system.web.mvc.controller.redirecttoaction(v=vs.108).aspx. Some code to illustrate:
public ActionResult MyAction(){
//do some work here
Return View(MyModel);
}
public ActionResult ActionIAmCurrentlyIn(){
//Do Soe work here
return RedirectToAction ("MyAction", "MyController"); //This costs an extra trip across the wire
return MyAction(); // Does same thing but without the extra trip to the client
}
This overhead of the extra trip becomes more significant if there are parameters being passed along to "MyAction" and as the network speed goes down.
Responding as an answer because I don't have enough rep to add a comment...
#JTMon In your code the "return MyAction();" can cause potential issues because the "MyAction" action will actually try to load a view named "ActionIAmCurrentlyIn" since that is the action that's specified in the route values (at least I assume that's where it's getting it from, I haven't actually dug into the code to find out).
This can be resolved by specifying the view name in MyAction:
return view("MyAction", MyModel);
To prevent this problem and speed up the redirection use:
return Redirect("~/MyController/MyView");
This approach will not change client-server interaction.
You can use RedirectToActionPermanent("View","Controller"); for it.

How do I set the protocol when using RedirectToAction?

The action I target needs https. I already have a filter in place that redirects to https if a request comes in via http, but I would prefer to send the request via https right from the start.
EDIT
There was an answer from Darin (updated now to something else ) where he asked why I call this first action by http anyway. He had a good point there and I just updated a couple of links. This was the easiest and securest way to fix my problem.
Once I find the time to evaluate çağdaş answer I will use this as the correct answer, because I guess thats of interest for some other people (...including me in the future)
I don't know if you must use RedirectToAction but with a UrlHelper and the controller's Redirect method you can do this :
public ActionResult SomeAction() {
UrlHelper u = new UrlHelper(this.ControllerContext.RequestContext);
return Redirect(u.Action("actionName", "controllerName", null, "https"));
}
ASP.NET MVC 3 includes the RequireHttpsAttribute which may be of assistance.

Redirect problem

I have this code in the client side:
$.post('<%=Url.Action("Action_Name","Controller_Name")%>', { serverParam: clientParam}, null, null);
And this code in the server side:
[HttpPost]
public ActionResult Action_Name(string serverParam)
{
return View();
}
I currently am in a view and when i click a button i want to be redirected to Controller_Name/Action_Name/serverParam.
After the post i am sent in the action method but i still see the old view, not Action_Name
(Action_Name.aspx exists)
(I am using mvc 2)
First, you should follow the "Post/Redirect/Get" pattern by returning a redirect result instead of a view after a successful post. But that would not solve the problem you're actually asking about.
This is doing an AJAX POST, not a "regular" POST. So the browser isn't going to honor a redirect response by redirecting. You could "redirect" in your response callback by setting window.location, but...
The easiest way to do what you want is to just post the form, rather than using $.post, which is a shortcut to $.ajax, like this:
$("#someForm").submit();

RedirectToAction and partial views

I'm curious why it's made exactly like that?
If i call this through AJAX:
public ActionResult Foo(){
return RedirectToAction("SomethingThatReturnsPartialView","Bar");
}
It won't return me partial view in AJAX callback but will redirect to url that represents action.
So - why it is so? What are possible workarounds?
Because when the browser receives the reply from the server that is a HTTP 30x redirect, it will do just that, regardless of how the request was initiated, either synchronously or asynchronously.
On of the possible workarounds could be something like RenderViewToString, but as we know MVC lacks this feature yet. It's a known missing feature everyone wants to get.
Look in this discussion: Render a view as a string
And also look here, there may be an option to prevent the browser going redirect with JavaScript: Catching 302 FOUND in JavaScript

How do you redirect to a page using the POST verb?

When you call RedirectToAction within a controller, it automatically redirects using an HTTP GET. How do I explicitly tell it to use an HTTP POST?
I have an action that accepts both GET and POST requests, and I want to be able to RedirectToAction using POST and send it some values.
Like this:
this.RedirectToAction(
"actionname",
new RouteValueDictionary(new { someValue = 2, anotherValue = "text" })
);
I want the someValue and anotherValue values to be sent using an HTTP POST instead of a GET. Does anyone know how to do this?
For your particular example, I would just do this, since you obviously don't care about actually having the browser get the redirect anyway (by virtue of accepting the answer you have already accepted):
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index() {
// obviously these values might come from somewhere non-trivial
return Index(2, "text");
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(int someValue, string anotherValue) {
// would probably do something non-trivial here with the param values
return View();
}
That works easily and there is no funny business really going on - this allows you to maintain the fact that the second one really only accepts HTTP POST requests (except in this instance, which is under your control anyway) and you don't have to use TempData either, which is what the link you posted in your answer is suggesting.
I would love to know what is "wrong" with this, if there is anything. Obviously, if you want to really have sent to the browser a redirect, this isn't going to work, but then you should ask why you would be trying to convert that regardless, since it seems odd to me.
HTTP doesn't support redirection to a page using POST. When you redirect somewhere, the HTTP "Location" header tells the browser where to go, and the browser makes a GET request for that page. You'll probably have to just write the code for your page to accept GET requests as well as POST requests.
If you want to pass data between two actions during a redirect without include any data in the query string, put the model in the TempData object.
ACTION
TempData["datacontainer"] = modelData;
VIEW
var modelData= TempData["datacontainer"] as ModelDataType;
TempData is meant to be a very short-lived instance, and you should only use it during the current and the subsequent requests only! Since TempData works this way, you need to know for sure what the next request will be, and redirecting to another view is the only time you can guarantee this.
Therefore, the only scenario where using TempData will reliably work is when you are redirecting.
try this one
return Content("<form action='actionname' id='frmTest' method='post'><input type='hidden' name='someValue' value='" + someValue + "' /><input type='hidden' name='anotherValue' value='" + anotherValue + "' /></form><script>document.getElementById('frmTest').submit();</script>");
I would like to expand the answer of Jason Bunting
like this
ActionResult action = new SampelController().Index(2, "text");
return action;
And Eli will be here for something idea on how to make it generic variable
Can get all types of controller
I have just experienced the same problem.
The solution was to call the controller action like a function:
return await ResendConfirmationEmail(new ResendConfirmationEmailViewModel() { Email = input.Email });
The controller action:
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> ResendConfirmationEmail(ResendConfirmationEmailViewModel input)
{
...
return View("ResendConfirmationEmailConfirmed");
}

Resources