The model item passed into the dictionary is of ty

2019-08-31 05:48发布

问题:

I have a query in my controller that gets all the apps, and includes their average rating from another table

var apps = from a in db.Apps
           let rating = a.Ratings.Average(r => r.Stars)
           select new { App = a, Rating = rating == null ? 0 : rating };

Then I order them based on which filter is passed from home....no big deal....

switch (sortOrder)
        {
            case "Top desc":
                apps = apps.OrderByDescending(a => a.Rating);
                break;
            case "Newest":
                apps = apps.OrderBy(a => a.App.DateUpdated);
                break;
            case "Newest desc":
                apps = apps.OrderByDescending(a => a.App.DateUpdated);
                break;
            default:
                apps = apps.OrderBy(a => a.Rating);
                break;
        }

Then return it to the view

return View(apps.ToPagedList(pageIndex, pageSize));

However, on the home page I get an error stating I am passing the wrong type of model Item, I am passing {Model.App, System. Double} ( I assume because of the way my query adds the Rating Average......How can I still get a rating average, but send back the proper model item type. Thanks!

回答1:

Don't pass anonymous types in your views. Define view models:

public class MyViewModel
{
    public App App { get; set; }
    public double Rating { get; set; }
}

and then:

var apps = 
    from a in db.Apps
    let rating = a.Ratings.Average(r => r.Stars)
    select new MyViewModel 
    { 
        App = a, 
        Rating = rating == null ? 0 : rating 
    };

and then strongly type your view to this view model.

@model PagedList.IPagedList<MarketplaceFinal.Models.MyViewModel>


回答2:

Since you are creating an anonymous type, there are two ways you could approach this. The first would be to change you view expect a model of type dynamic, but I would recommend you do away with the anonymous type and create a new class, say AppWithRating that looks like this:

public class AppWithRating
{
    public App App { get; set; }
    public double Rating { get; set; }
}

Change you linq query to this:

var apps = from a in db.Apps
           let rating = a.Ratings.Average(r => r.Stars)
           select new AppWithRating { App = a, Rating = rating == null ? 0 : rating };

And finally update your View to accept the type IEnumerable<AppWithRating>.