Krishh
Krishh

Reputation: 4231

Accessing group by fields from Controller to View in MVC 3

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

Answers (1)

Darin Dimitrov
Darin Dimitrov

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

Related Questions