0

I'm using Asp.NET mvc 5

I have the following controller

public class AController : Controller {
   public ActionResult ActionA(int param1, int param2) { 
         return Content("Whatever") ; 
   } 
}

What is the correct way to redirect url /B/ActionB?p1=5&p2=9 to /A/ActionA?param1=p1&param2=p2 ?

Edit : I tried the following but I'm struggle with converting the parameters

public class AController : Controller {
   [Route("/B/ActionB")]
   public ActionResult ActionA(int param1, int param2) { 
         return Content("Whatever") ; 
   } 
}
5
  • Have you tried to use RouteAttribute or RouteConfig? Show that if you're using one of them or both. Commented Oct 12, 2017 at 8:12
  • Yes but I don't know how to change parameter names. Commented Oct 12, 2017 at 8:13
  • [Route("/B/ActionB?p1={param1:int}&p2={param2:int}")] - is this enough? You can refer blogs.msdn.microsoft.com/webdev/2013/10/17/… for further details. Commented Oct 12, 2017 at 8:16
  • It doesn't work. It says that template should not contains ? Commented Oct 12, 2017 at 8:21
  • [Route("/B/ActionB/{p1=param1:int}/{p2=param2:int}")] - oh well, I'm forgot something on attribute routing... try to use this configuration. Commented Oct 12, 2017 at 8:24

2 Answers 2

0

From what I figured out, the query string can be represented on RouteAttribute using route constraint, hence this query string:

/B/ActionB?p1=5&p2=9

represented in RouteAttribute argument like below:

/B/ActionB/{param1:int}/{param2:int}

or with parameters included (not totally sure if this work, hence I preferred the former one):

/B/ActionB/{p1=param1:int}/{p2=param2:int}

Since you're using MVC 5, the argument should put inside RouteAttribute like this example:

public class AController : Controller {

   [Route("/B/ActionB/{param1:int}/{param2:int}")]
   public ActionResult ActionA(int param1, int param2) { 
         return Content("Whatever"); 
   } 
}

Note that as Ken Egozi said attribute routing with query string parameters (using ? & &) only supported by Web API controller, as in MVC controller you can bind the query string as action parameter(s) through customized model binder as workaround.

Similar issue:

Query string not working while using attribute routing

Related:

How do I route a URL with a querystring in ASP.NET MVC?

How to use Querystring Parameters in Asp.Net MVC to Retrieve or Send Data?

Sign up to request clarification or add additional context in comments.

1 Comment

It is possible to use the query string with MVC routing (that is, match only if query string parameters are passed), but it is better to subclass Route or RouteBase to do it than to use a Controller to do it.
0

The correct way to redirect is to use RedirectToAction:

// URL /B/ActionB?p1=5&p2=9
public class BController : Controller {
    public ActionResult ActionB(int p1, int p2) { 
        return RedirectToAction("ActionA", "A", new { param1 = p1, param2 = p2 });
   } 
}

// URL /A/ActionA?param1=5&param2=9
public class AController : Controller {
    public ActionResult ActionA(int param1, int param2) { 
        return Content("Whatever") ; 
   } 
}

But do note that calling /B/ActionB?p1=5&p2=9 will reach ActionB and then MVC will respond with a 302 status code telling the browser to fetch the URL /A/ActionA?param1=5&param2=9. So, it turns 1 round trip to the server into 2.

From an application design standpoint, it makes more sense to go directly to /A/ActionA?param1=5&param2=9 unless you have some specific reason why you need to change the URL in the user's browser.


If your goal is to divert all traffic from BController.ActionB to AController.ActionA because you are replacing it in your application, you should do a 301 redirect. That is best handled by the IIS URL Rewrite Module.

<?xml version="1.0"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Redirect /B/ActionB?p1=5&p2=9 to /A/ActionA?param1=p1&param2=p2" stopProcessing="true">
                    <match url="^B/ActionB?p1=(\d+)&p2=(\d+)" />
                    <action type="Redirect" url="A/ActionA?param1={R:1}&param2={R:2}" redirectType="Permanent" />
                </rule>         
            </rules>
        </rewrite>
        <httpProtocol>
            <redirectHeaders>
                <!-- This is to ensure that clients don't cache the 301 itself - this is dangerous because the 301 can't change when put in place once it is cached -->
                <add name="Cache-Control" value="no-cache"/>
            </redirectHeaders>
        </httpProtocol>
    </system.webServer>
</configuration>

Do note that if the query string parameters are optional or could appear in reverse order, you will need to add additional rules to cover those cases.

Alternatively, you could use routing in MVC for the 301 redirects. There is an example here, although it would need to be modified to extract the query string arguments from the request and pass them to the receiving end using different names.

2 Comments

Sorry but I can't edit BController so it doesn't work.
If you cannot edit BController, why do you want to redirect? Are you replacing BController with AController in your application?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.