views:

18

answers:

1

I am having one of those coder's block days. I should know this but instead I'll ask for a little help. I have two routes:

/Login
/Login?wa=wsignin1.0&wtrealm=http://localhost/MyApp

Accessing the Action method for the first with an HTTP GET returns the login page where-as the second does some federated authentication stuff. I defined two controller methods:

public ActionResult Index();
public ActionResult Index(string wa);

The routing of course doesn't like that because the nullable type makes it ambiguous. How do I put a constraint on it to say only execute the second method if the value exists in the route data?

EDIT: I've temporarily solved the issue with an action method selector. Is this the best approach?

public class QueryStringAttribute : ActionMethodSelectorAttribute
{
    public ICollection<string> Keys { get; private set; }

    public QueryStringAttribute(params string[] keys)
    {
        this.Keys = new ReadOnlyCollection<string>(keys);
    }

    public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
    {
        var requestKeys = controllerContext.HttpContext.Request.QueryString.AllKeys;
        var result = Keys.Except(requestKeys, StringComparer.OrdinalIgnoreCase).Count() == 0;
        return result;
    }
}
A: 

I have come across this problem many times in the past and I think this is a classic routing problem. What I have done is this:

Create your actions in your controller:

public ActionResult Index();
public ActionResult IndexForWa(string wa);

Do whatever mapping you need to do in your routes definition

routes.MapRoute(
    "index_route",
    "Login"
    new {controller="Login", action="Index"}
); //This is not even necessary but its here to demo purposes

routes.MapRoute(
    "index_for_wa_route",
    "Login/wa/{wa}",
    new {controller="Login", action="Index", wa = {wa)}
);
Yannis