Reputation: 1681
Within my view, I have a line of code that renders an editor template.
However, it returns the error:
Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.
This seems like the most elegant way to achieve what I want but I realise the lambda expression in my view is too complex for the editor template.
Can anybody suggest how to make this work or advise me of a better way?
View
@Html.EditorFor(model => model.Approvers.Where(a => a.ApprovalCount > 0))
Editor Template
@model Project.ViewModels.AssignedApproverData
<div class="span3">
<label class="checkbox inline">
@Html.HiddenFor(model => model.EmployeeID)
@Html.CheckBoxFor(model => model.Assigned)
@Html.DisplayFor(model => model.FullName)
</label>
</div>
Editor Template ViewModel
using System;
using System.Collections.Generic;
using Project.Models;
namespace Project.ViewModels
{
public class AssignedApproverData
{
public string EmployeeID { get; set; }
public string FullName { get; set; }
public bool Assigned { get; set; }
public int ApprovalCount { get; set; }
}
}
ViewModel
namespace Project.ViewModels
{
public class ChangeRequestViewModel
{
public virtual ICollection<AssignedApproverData> Approvers { get; set; }
}
}
Upvotes: 0
Views: 342
Reputation: 1038710
The error message says it all: you cannot use complex lambda expressions with strongly typed helpers. Only property access and indexer access expressions are supported.
Can anybody suggest how to make this work or advise me of a better way?
By using a view model of course.
So go ahead and define a property on your view model that you could use in your view instead of writing such code in the view:
@Html.EditorFor(model => model.AcceptedApprovers)
and you will have the corresponding property on your view model:
public class ChangeRequestViewModel
{
public virtual ICollection<AssignedApproverData> AcceptedApprovers { get; set; }
}
and in your controller action that is rendering this view you will populate this property from your domain model:
public ActionResult SomeAction()
{
var domainModel = ... fetch your domain model from your repository as usual
var viewModel = new ChangeRequestViewModel();
viewModel.AcceptedApprovers = domainModel.Approvers.Where(a => a.ApprovalCount > 0);
return View(viewModel);
}
Obviously the view model will contain only the information necessary by the view, not more, not less.
Upvotes: 5