views:

210

answers:

2

We have a [UserNameFilter] ActionFilterAtrribute which populates the controller actions username parameter. This works nicely. However, when I use the Html.ActionLink helper stringly typed to the controller, the compiler requests said username parameter in the View.

Has anyone come across this and know how to recitify?

Controller Action:

[UserNameFilter]
public ActionResult Category(int categoryId, int page, string userName)

Code in View:

<%= Html.RenderTree(ViewData.Model, i => Html.ActionLink<ProductController>(pc =>
    pc.Category(i.CategoryId, 1, **Complier error here**),i.CategoryName)) %>
A: 

This is a compile time error - C# compiler knows nothing of your application, MVC or ActionFilter you're using so it cannot possibly know how to fill the userName parameter.

On way I can think of right now is to declare a new action in the controller

public ActionResult CategoryNoUser(int categoryId, int page)
{
   string userName = ""; /* get username here same way you do in action filter */
   return Category(categoryId, page, userName);
}

and use that in your view.

If you can access the username in the view you could supply that to your current Category action:

<%= Html.RenderTree(ViewData.Model, i => Html.ActionLink<ProductController>(pc =>
    pc.Category(i.CategoryId, 1, CurrentUser.UserName),i.CategoryName)) %>

or if you can put username in the model:

<%= Html.RenderTree(ViewData.Model, i => Html.ActionLink<ProductController>(pc =>
    pc.Category(i.CategoryId, 1, Model.UserName),i.CategoryName)) %>
Robert Wilczynski
A: 

Yep, one has to declare an overloaded stub action in the controller. What I have done is declare the stub to match the instance where there is no parameter for the userName thus we get a clean compile. I have then decorated this overloaded action as illustrated to ensure that it is never called. Now everything is hunky dory.

Cheers for the reply Robert

    [ActionName("UNCALLABLE")]
    public ActionResult Category(int categoryId, int page)
    {
        return View();
    }