Reputation: 4231
How can I write code in View so as to access the groupby fields in linq. Here the data is rendered through a web service.
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Find Member";
var obj = new SearchMemberServiceClient();
List<MemberProxy> members = obj.FindMember("Mason", "Birkes", "", "", "", "").Members;
var sorted = from a in members
orderby a.FirstName ascending
group a by new { a.FormattedFullName, a.PersonId, a.Associations, a.MembershipsProxy[0].MembershipId } into k
select new { formattedname = k.Key.FormattedFullName, id = k.Key.PersonId, assoc = k.Key.Associations, memprox = k.Key.MembershipId };
return View(sorted.ToList());
}
}
Upvotes: 1
Views: 3203
Reputation: 1038720
You are passing an anonymous object to your view. Anonymous objects are emitted as internal by the compiler. Internal classes can only be used within the same assembly. ASP.NET MVC views are dynamically compiled by the ASP.NET runtime in separate assemblies. This basically means that you cannot access the anonymous types created in your controller actions inside your views. As a consequence this means that you should absolutely never pass anonymous objects to your views. So if you cannot pass anonymous objects, well, pass a named object by creating one. In this case they will be called a view model. A view model is class that you specifically define to meet the requirements of your view.
So what are the requirements of your view is the first question you should ask yourself when designing an ASP.NET MVC application? Well, in this case you seem to need a couple of properties (formattedname
, id
, assoc
and memprox
). Great, let's write a view model:
// you probably want to find a more suitable name
public class MyViewModel
{
public int Id { get; set; }
public int MemProx { get; set; }
public string FormattedName { get; set; }
public IEnumerable<Association> Associations { get; set; }
}
and then have your action pass this view model to the view:
public ActionResult Index()
{
var obj = new SearchMemberServiceClient();
var members = obj.FindMember("Mason", "Birkes", "", "", "", "").Members;
IEnumerable<MyViewModel> sorted =
from a in members
orderby a.FirstName ascending
group a by new
{
a.FormattedFullName,
a.PersonId,
a.Associations,
a.MembershipsProxy[0].MembershipId
} into k
select new MyViewModel
{
FormattedName = k.Key.FormattedFullName,
Id = k.Key.PersonId,
Associations = k.Key.Associations,
MemProx = k.Key.MembershipId
};
return View(sorted.ToList());
}
OK, now you can strongly type your view to this view model and present the information that it contains however you want:
@model IEnumerable<MyViewModel>
@foreach (var item in Model)
{
<div>@item.FormattedName</div>
...
}
Upvotes: 4