Dbl
Dbl

Reputation: 5893

Url.Action delivers wrong result when RouteAttribute is used

I've got the following scenario:

[RoutePrefix("MvcApi/MyData")]
public class MyDataController : Controller
{
    [Route("GetAsSelectionListBySiteId/{siteId}")]
    public async Task<ActionResult> GetAsSelectionListBySiteId(int siteId)
    {
        var items = await IoC.Instance.GetInstance<IDataProvider>().GetBySiteIdAsync(ParallelDataAccessor, siteId);
        return Json(items.Select(s => new KeyValuePair<int, string>(s.Identifier, s.DisplayName)).ToArray(), JsonRequestBehavior.AllowGet);
    }

    public static class Routes
    {
        public static RouteValueDictionary GetAsSelectionListBySiteId(int siteId)
        {
            return new RouteValueDictionary()
                .AddReturn(nameof(siteId), siteId)
                .AddReturn("area", "MvcApi");
        }
    }
}

When i use

@Url.Action("GetAsSelectionListBySiteId", "MyData", MyDataController.Routes.GetAsSelectionListBySiteId(5))

in a view this will render as

MvcApi/MyData/GetAsSelectionListBySiteId?siteId=5 <- 404 error

when i do in fact need it like this

MvcApi/MyData/GetAsSelectionListBySiteId/5 <- 200 ok

Is this a bug in @Url.Action? Is there a way to influence it?

Upvotes: 0

Views: 371

Answers (1)

Vinicius Zaramella
Vinicius Zaramella

Reputation: 531

When generating URL your best options is to always use the route names because this way you do not get into the subtleties of the algorithm used to select the route that will be used to generate the URL.

My advice if for you not to use Url.Action and instead use Url.RouteUrl which allows you to specify the name of the route that should be used to construct the URL.

By always using route names you also make your code more robust to changes, for example, you can add new routes without having to worry that they might break your existing code for URL generation.

Upvotes: 1

Related Questions