3
\$\begingroup\$

I've got the following code in my _ViewStart.cshtml file:

@using System.Text;
@{
    string controllerName = (string)ViewContext.RouteData.Values["controller"];
    ViewContext.Controller.ViewBag.BodyCssClass = ConvertControllerNameToCssClass(controllerName);
}

@functions {
    private static string ConvertControllerNameToCssClass(string text)
    {
        if (text == null)
        {
            throw new ArgumentNullException("text");
        }

        StringBuilder sb = new StringBuilder();
        sb.Append(text[0]);
        for (int i = 1; i < text.Length; i++)
        {
            if (char.IsUpper(text[i]) && text[i - 1] != '-')
            {
                sb.Append('-');
            }
            sb.Append(text[i]);
        }
        return sb.ToString().ToLower();
    }
}

In my layout the ViewBag.BodyCssClass is used like so:

<body class="@ViewBag.BodyCssClass" itemscope itemtype="https://schema.org/WebPage">

Allowing me to target a particular page with CSS specific to that controller where required.

The ConvertControllerNameToCssClass function has limited use, in that it is not likely to be used elsewhere and shouldn't be used elsewhere either.

However, it is my understanding that the _ViewStart.cshtml is supposed to be used for adding code that would otherwise be duplicated across all views. Is it acceptable to add functions to the _ViewStart.cshtml?

Does anyone have any thoughts on this or any alternatives to how they would implement something like this?

\$\endgroup\$
  • \$\begingroup\$ To make life easier for reviewers, please add sufficient context to your question. The more you tell us about what your code does and what the purpose of doing that is, the easier it will be for reviewers to help you. See also this meta question \$\endgroup\$ – Simon Forsberg Jun 14 '15 at 13:49
  • \$\begingroup\$ For brevity I've avoided explaining what the code does since it is pretty self explanatory, however I've updated the code to remove the code that does not relate to this question. \$\endgroup\$ – Professor of programming Jun 14 '15 at 13:52
3
\$\begingroup\$

The ConvertControllerNameToCssClass function has limited use, in that it is not likely to be used elsewhere and shouldn't be used elsewhere either.

It looks like the function converts a PascalCase input text to dash-separated-words format. This is actually a quite common text transformation to do. In some frameworks it's called "slugify", and I would prefer this shorter name instead of the current very long name. (Another naming idea: ToCssClass)


You seem to have a bug: you check if the input is null, but you don't check if it's empty. If it's empty, then this line will throw an exception:

    sb.Append(text[0]);

Instead of transforming the input character by character, it would be much simpler to use a regex. I don't know the syntax in C#, I hope this Perl/Bash example might help:

$ perl -pe 's/[A-Z]/-\L$&/g; s/^-//' <<< HelloWorldThere
hello-world-there
\$\endgroup\$
  • \$\begingroup\$ I've removed the function and instead opted for manually setting the body CSS class on an ad-hoc basis as I feel this makes more sense than adding a class to every body element as this could potentially be error prone if a new class is added where the name clashes with an existing CSS class. \$\endgroup\$ – Professor of programming Jun 14 '15 at 14:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.