Dresel / RouteLocalization

RouteLocalization is an MVC and Web API package that allows localization of your attribute routes.
MIT License
67 stars 13 forks source link

Add translation to GET and POST routes with Int and String parameters #6

Closed mdmoura closed 10 years ago

mdmoura commented 10 years ago

Hello,

I am having a few problems to translate the following two routes:

[Route("documents"), HttpGet]
public virtual ActionResult Documents(Int32 page = 1)  { }

[Route("documents"), HttpPost]
public virtual ActionResult Documents(String query, Int32 page = 1)  { }

Basically the first route gets a paged list of documents, using page = 1 when not specified. And the second also accepts a string query to filter the documents.

So for translation I am using the following:

.ForAction(x => x.Documents(), new Type[] { typeof(Int32) }).AddTranslation("documentos")
.ForAction(x => x.Documents(), new Type[] { typeof(String), typeof(Int32) }).AddTranslation("documentos")

But I get the errors: An expression tree may not contain a call or invocation that uses optional arguments
An expression tree may not contain a call or invocation that uses optional arguments

I tried a few variations of this but I always get an error.

Any idea what might be wrong?

Thank You, Miguel

Dresel commented 10 years ago

These are limitations of the expression tree api (http://stackoverflow.com/questions/12413583/an-expression-tree-may-not-contain-a-call-or-invocation-that-uses-optional-argum).

You should be able to call it like this

.ForAction(x => x.Documents(0), new Type[] { typeof(Int32) }).AddTranslation("documentos")
.ForAction(x => x.Documents(null, 0), new Type[] { typeof(String), typeof(Int32) }).AddTranslation("documentos")

The function is used for name extraction:

public RouteTranslator<T> ForAction(Expression<Func<T, object>> expression, Type[] actionArguments)
{
    MethodCallExpression methodCall = expression.Body as MethodCallExpression;

    if (methodCall == null)
    {
        throw new ArgumentException("Expression must be a MethodCallExpression", "expression");
    }

    ForAction(methodCall.Method.Name, actionArguments);

    return this;
}

So you cannot use it with default arguments. You could also use ForAction(string):

.ForAction("Documents", new Type[] { typeof(Int32) }).AddTranslation("documentos")
.ForAction("Documents", new Type[] { typeof(String), typeof(Int32) }).AddTranslation("documentos")

If you are working with T4MVC you could use the ActionName so that you do not use magic strings.