my site is on MVC3 razor and on .Net 4 framework.
I have a href link in my view
mylink
this links go to News action and news action is :
[ValidateInput(false)]
public ActionResult Index(int NewsID, string NewsUrl)
{
//do some process on NewsID and NewsUrl
mymodel mm=new mymodel();
return View(mm);
}
it works fine but return url include NewsId and NewsUrl as parameter ,i know
it is normal but how can i remove all parameter when response returned from my action?
The only way to do this would be to perform an HTTP 302 or 301 redirect.
return Redirect(); //302
return RedirectPermanent(); //301
return RedirectToAction(); //302
return RedirectToActionPermanent(); //301
return RedirectToRoute(); //302
return RedirectToRoutePermanent(); //301
By performing an HTTP 301 redirect you are telling the client that this is a permanent redirection (i.e. that the resource has officially been relocated). The browser may cache this redirect.
You probably don't want to do a 301 redirect; I only mention it to give a complete answer.
Related
I have a void function that based on a conditional statement should redirect users to a different action.
public void MyFunction()
{
if (!condition)
{
Redirect(url);
}
...
...
}
Using redirect without a return statement doesn't seem to work. Is there a more suitable method for accomplishing this?
Response.Redirect("Some URL") or Server.Transfer("Some URL") can be used to redirect any web page
Response.Redirect("Some URL") should be used when to :
redirect the request to some plain HTML pages on our
server or to some other web server
not to care about causing additional roundtrips to the server on each request
not need to preserve Query String and Form Variables from the original request
to be able to see the new redirected URL where he is
redirected in his browser (and be able to bookmark it if its
necessary)
Server.Transfer("Some URL") should be used when to:
transfer current page request to another .aspx page on the
same server
preserve server resources and avoid the
unnecessary roundtrips to the server
preserve Query String and Form Variables (optionally) we don't need to show the real URL
where we redirected the request in the users Web Browser
try this
public IActionResult MyFunction()
{
if (!condition)
{
return Redirect(url);
}
...
...
}
About IActionResult
Actions can return anything, but frequently return an instance of
IActionResult (or Task for async methods) that produces
a response. The action method is responsible for choosing what kind of
response. The action result does the responding.
from https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/actions
You may get more information about action methods at above link
I have a controller with an Index method that has several optional parameters for filtering results that are returned to the view.
public ActionResult Index(string searchString, string location, string status) {
...
product = repository.GetProducts(string searchString, string location, string status);
return View(product);
}
I would like to implement the PRG Pattern like below but I'm not sure how to go about it.
[HttpPost]
public ActionResult Index(ViewModel model) {
...
if (ModelState.IsValid) {
product = repository.GetProducts(model);
return RedirectToAction(); // Not sure how to handle the redirect
}
return View(model);
}
My understanding is that you should not use this pattern if:
You do not need to use this pattern unless you have actually stored some data (I'm not)
You would not use this pattern to avoid the "Are you sure you want to resubmit" message from IE when refreshing the page (guilty)
Should I be trying to use this pattern? If so, how would I go about this?
Thanks!
PRG Stands for Post-Redirect-Get. that means when you post some data to the server back, you should redirect to a GET Action.
Why do we need to do this ?
Imagine you have Form where you enter the customer registration information and clicking on submit where it posts to an HttpPost action method. You are reading the data from the Form and Saving it to a database and you are not doing the redirect. Instead you are staying on the same page. Now if you refresh your browser ( just press F5 button) The browser will again do a similar form posting and your HttpPost Action method will again do the same thing. ie; It will save the same form data again. This is a problem. To avoid this problem, We use PRG pattern.
In PRG, You click on submit and The HttpPost Action method will save your data (or whatever it has to do) and Then do a Redirect to a Get Request. So the browser will send a Get Request to that Action
RedirectToAction method returns an HTTP 302 response to the browser, which causes the browser to make a GET request to the specified action.
[HttpPost]
public ActionResult SaveCustemer(string name,string age)
{
//Save the customer here
return RedirectToAction("CustomerList");
}
The above code will save data and the redirect to the Customer List action method. So your browser url will be now http://yourdomain/yourcontroller/CustomerList. Now if you refresh the browser. IT will not save the duplicate data. it will simply load the CustomerList page.
In your search Action method, You dont need to do a Redirect to a Get Action. You have the search results in the products variable. Just Pass that to the required view to show the results. You dont need to worry about duplicate form posting . So you are good with that.
[HttpPost]
public ActionResult Index(ViewModel model) {
if (ModelState.IsValid) {
var products = repository.GetProducts(model);
return View(products)
}
return View(model);
}
A redirect is just an ActionResult that is another action. So if you had an action called SearchResults you would simply say
return RedirectToAction("SearchResults");
If the action is in another controller...
return RedirectToAction("SearchResults", "ControllerName");
With parameter...
return RedirectToAction("SearchResults", "ControllerName", new { parameterName = model.PropertyName });
Update
It occurred to me that you might also want the option to send a complex object to the next action, in which case you have limited options, TempData is the preferred method
Using your method
[HttpPost]
public ActionResult Index(ViewModel model) {
...
if (ModelState.IsValid) {
product = repository.GetProducts(model);
TempData["Product"] = product;
return RedirectToAction("NextAction");
}
return View(model);
}
public ActionResult NextAction() {
var model = new Product();
if(TempData["Product"] != null)
model = (Product)TempData["Product"];
Return View(model);
}
I got an action List
//[HttpGet] (will come back to that!)
public ViewResult List(int page = 1)
{
//blah blah blah
return View(viewModel);
}
In its view we render action:
#{
Html.RenderAction("UpdateSearch");
}
Action definitions:
[ChildActionOnly]
[HttpGet]
public PartialViewResult UpdateSearch()
{
// do something and display a form in view
return PartialView(so);
}
[HttpPost]
public RedirectToRouteResult UpdateSearch(Options searchOptions)
{
// do something and redirect to List
return RedirectToAction("List");
}
and I'm getting: Child actions are not allowed to perform redirect actions exception every time someone submits the form. I'm new to MVC3, but it looks like the redirection is also a POST, because if [HttpGet] above List method is uncommented "the resource cannot be found" happens.
How do I change Http method on redirection or am I doing something wrong? I did try to Bing it, but no success.
The redirect info is stored in response header. However, the response is already being sent when child action is run so headers can't be written.
In short, there's no way of performing a redirect from child action other than through the use of javascript on client side.
I have one method which I use in some place. Now I make RedirectToActio.... and back me to the concrete page. Is possible to make, it back to previusly page?
You could use the Referer HTTP header but it's not very reliable. A better way is to pass the url you want to redirect to the controller action (it's the way the POST LogOn method on the AccountController is implemented when you create a new ASP.NET MVC 3 application using the built in wizard. Take a look at it):
public ActionResult Foo(string returnUrl)
{
...
return Redirect(returnUrl);
}
Then when you call this action you pass the url of the current page. For example you could generate the following anchor:
#Html.ActionLink(
"do some processing and redirect back here",
"foo",
new { returnurl = Request.Url.AbsoluteUri }
)
How to configure asp.net mvc routing to redirect permanently 301
hocalhost/Products.aspx and hocalhost/Search.aspx
to
hocalhost/Products and hocalhost/Search
i.e. to remove .aspx extension from the path?
Something along these lines should do the trick. Map the following route:
routes.MapRoute("Redirect route", "{file}.aspx",
new { controller = "home", action = "redirect" });
And define a Redirect action in your controller:
public ActionResult Redirect()
{
// use Request.RawUrl, for instance to parse out what was invoked
// this regex will extract anything between a "/" and a ".aspx"
var regex = new Regex(#"(?<=/).+(?=\.aspx)", RegexOptions.Compiled);
var action = regex.Match(Request.RawUrl);
return RedirectToActionPermanent(action.Value);
}
You could redirect both aspx pages to the same redirect route and detect which file has actually been invoked by parsing HttpContext.Request.RawUrl (there might be a better way for this last point though).
UPDATE
There is indeed a simpler way, as found out by #alex himself. In order to get the file in the original request, just do:
string file = RouteData.Values["file"].ToString();