0
votes

So I have an ASP.NET Core 2.1 MVC webapplication with viewmodels and razorviews that use those viewmodels.

In one of my Razor views I need to assign styling to an element based on a rating. I use the following code

public class MovieViewModel
{
    public Movie Movie { get; set; }

    public string GetRatingStyle(double? rating)
    {
        if (!rating.HasValue)
            return "";
        switch (rating)
        {
            case var _ when rating < 2.5:
                return "low";
            case var _ when rating >= 2.5 && rating < 5:
                return "medium";
            case var _ when rating >= 5 && rating < 7.5:
                return "medium-high";
            case var _ when rating >= 7.5:
                return "high";
            default:
                return "";
        }
    }
}

I try to apply it in my Razor view with the following code

@model MovieViewModel
...
<div class="rating @{Model.GetRatingStyle(Model.Movie.Rating);}">

I can't seem to get this to work so is this the way to go or am I doing something stupid?

2

2 Answers

1
votes

Speaking of Extension Methods I believe this would be a good use-case for extending the HtmlHelper It seems to me that a 'rating style' would be re-used through-out the application and if you find yourself using it in more than one ViewModel, you may start repeating code.

Of note, I wouldn't keep the private static string GetRatingStyle() method in the extensions, I would extract that out to your domain or business logic class.

HtmlHelperExtensions.cs

public static class HtmlHelperExtensions
{
    public static IHtmlContent GetRatingStyle(this IHtmlHelper html, double? rating)
    {
        var tagBuilder = new TagBuilder("div");
        tagBuilder.AddCssClass(GetRatingStyle(rating));
        return tagBuilder;
    }

    private static string GetRatingStyle(double? rating)
    {
        if (!rating.HasValue)
            return "";
        switch (rating)
        {
            case var _ when rating < 2.5:
                return "low";
            case var _ when rating >= 2.5 && rating < 5:
                return "medium";
            case var _ when rating >= 5 && rating < 7.5:
                return "medium-high";
            case var _ when rating >= 7.5:
                return "high";
            default:
                return "";
        }
    }
}

Use:

@Html.GetRatingStyle(Model.Movie.Rating)

2
votes

You should be better of by using extension methods

This might be your model

namespace AspNet.Core.Models
{
    public class MovieViewModel
    {
        public Movie Movie { get; set; }
    }

    public class Movie
    {
        public float? Rating { get; set; }
    }
}

This is your extension method/class

using AspNet.Core.Models;

namespace AspNet.Core.Infrastructure
{
    public static class Extensions
    {
        public static string RatingStyle(this Movie movie)
        {
            if (!movie.Rating.HasValue)
                return "";
            switch (movie.Rating)
            {
                case var _ when movie.Rating < 2.5:
                    return "low";
                case var _ when movie.Rating >= 2.5 && movie.Rating < 5:
                    return "medium";
                case var _ when movie.Rating >= 5 && movie.Rating < 7.5:
                    return "medium-high";
                case var _ when movie.Rating >= 7.5:
                    return "high";
                default:
                    return "";
            }
        }
    }
}

Use it like this in your view. Remember to include the @using clause

@model AspNet.Core.Models.MovieViewModel
@using AspNet.Core.Infrastructure

<div class="rating @Model.Movie.RatingStyle()">

An even more elegant solution would be using .net core's tag helpers