1
votes

Something strange is happening in my umbraco project where I have a repository set up like so;

public class HireItemsRepo:BaseGenericRepository<YouHireItContext,HireItem>
{
   public List<HireItemViewModel> PopulateHireItemViewModel(RenderModel model)
    { List<HireItemViewModel> HireItems = new List<HireItemViewModel>();   
        foreach (var Hireitem in base.GetAll())
        {
            HireItems.Add(
              new HireItemViewModel(model.Content)
              {
                  Title = Hireitem.Title,
                  Price = Hireitem.Price
              }
           );
        }
        return HireItems;
    }

}

which I'm using in my controller like this

 public class HiresController : RenderMvcController
    {
        // GET: Hire
        public override ActionResult Index(RenderModel model)
        {

            HireItemsRepo repo = new HireItemsRepo();
            var VM = repo.PopulateHireItemViewModel(model);

                return View("Hires",VM.ToList());
        }
    }

And using that model in the view like this;

    @model List<You_Hire_It.Models.HireItemViewModel>

   /*HTML starts here*/

It's strange because if I try to use that model as a List, Umbraco will blow up with the following error;

Cannot bind source type System.Collections.Generic.List`1[[You_Hire_It.Models.HireItemViewModel, You_Hire_It, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] to model type Umbraco.Web.Models.RenderModel.

However, if I refactor all the code to use the model on it's own as if I only have one set of values to use, it has no problem with it!

Could anybody point me in the right direction with this please?

Many thanks in advance!

2

2 Answers

1
votes

You can inherit from RenderModel as DZL suggests. However, I generally prefer to use route hijacking which would enable me to keep my models simple.

Instead of the Index method in your RenderMvcController, you can create a method with the same name as your view. I note your view is called Hires. So change your controller code to this:

public class HiresController : RenderMvcController
{
    // GET: Hire
    public ActionResult Hires(RenderModel model)
    {
        HireItemsRepo repo = new HireItemsRepo();
        var VM = repo.PopulateHireItemViewModel(model);

        return CurrentTemplate(VM)
    }
}

You now need to have your view inherit from UmbracoViewPage. So at the top of your view replace the @model line with the following:

@inherits UmbracoViewPage<List<HireItemViewModel>>

Your model in the view is now of type List<HireItemViewModel> which I think is what you want.

So to iterate the items you would use:

@foreach(var item in Model){
{
    // etc
}

Additionally, as this view now inherits from UmbracoViewPage, you have access to the UmbracoContext - just use @Umbraco

For example:

@Umbraco.TypedContentAtRoot().Where(x=>x.DocumentTypeAlias == "HomePage")

or

@Umbraco.AssignedContentItem etc
1
votes

That is because the model you return from the action need to be of type RenderModel or inherit from it and in your case you are returning a List. So your model should look something like this:

public class ViewModel : RenderModel
{
    public ViewModel(IPublishedContent content) : base(content) { }

    public List<HireItem> HireItems { get; set; }
}

public override ActionResult Index(RenderModel model)
{
    var vm = new ViewModel(model);
    vm.HireItems = new HireItemsRepo().GetHireItems();
    return View("Hires", vm);
}