views:

55

answers:

2

In my current project I have a custom ViewData that has (amongst others) the following properties:

CustomViewData
  + IList <Language> siteLangauges
  + Language CurrentLanguage
  + T9nProvider

All my URL's go like this:

http://someUrl.com/{siteLanguage}/{restOfUrlIncludingcontrollersAndACtions}

I want to create an ActionAttribute that catches each request, checks what the siteLanguage value is and sets the Language value on the CustomViewData. My current (non working) code is like this:

public class TranslateAttribute: ActionFilterAttribute, IActionFilter
{
    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
        ViewDataDictionary viewData = filterContext.Controller.ViewData;
        if (viewData is CustomViewData) { 
            (viewData as CustomViewData).Language = new Language(filterContext.ActionParameters["siteLanguage"] as string));
        }
        base.OnActionExecuting(filterContext);
    }

    void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
    }
}

The first problem being that viewdata never is a customviewdata. Why not?

A: 

if (viewData is CustomViewData)

This is a very strange check. What does it do?

I suggest you drop it.

You don't need to call base implementation - base.OnAction...

You also don't need to derive from IActionFilter. Derive from ActionFilterAttribute, that's enough.

User
My CustomViewData has a few properties that hold the languages etc. If for some reason the translate attribute is used with another type of viewdata, I can't use these properties.
borisCallens
Why shouldn't I call the base? What if there are some other actions in my base that need calling?
borisCallens
What if there aren't? I removed this base calls and everything still works. I doubt there is something in base implementation.
User
A: 

You can set the ViewData on the controller so why not just make a constructor for CustomViewData that takes a ViewData object and do:

var customData = new CustomViewData( filterContext.Controller.ViewData);
customData.Language = new Language(filterContext.ActionParameters["siteLanguage"] as string));
filterContext.Controller.ViewData = customData;
base.OnActionExecuting( filterContext );
tvanfosson
Because that would imply that using the translate attribute will return a custom viewdata.
borisCallens
Presumably, your CustomViewData derives from ViewDataDictionary. If not, it should. In that case, it would not be a problem, when using TranslatedAtttribute, for it to return a CustomViewData object. Other objects expecting a ViewDataDictionary can use it interchangeably.
tvanfosson
This question was dug up by the Community User and since then a bunch of requirements changed. But to the question originally asked, this was the answer that i based my solution on. Thanks
borisCallens