user5648283
user5648283

Reputation: 6203

How do get these two lines to be the same context in Razor synatx?

So the beginning of my View is

@foreach ( var G in ViewBag.GroupedBySec )
{
<div class="row">
    <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
        <table class="table table-striped assessment-table">
            <tbody>
                <tr>
                    <td class="black-n-white" colspan="4">@G.Key</td>
                </tr>
                <tr>
                    <td>Section</td><td>Component</td><td>Completeness Level (0-100%)</td><td>Readines</td>
                </tr>
                @var GroupedBySubsection = G.GroupBy(x => x.SubsectionTitle);
                @foreach ( var g in GroupedBySubsection )
                {
                    @foreach ( var qa in g )
                    {

and I'm getting errors on the

@var GroupedBySubsection = G.GroupBy(x => x.SubsectionTitle);
@foreach ( var g in GroupedBySubsection )

lines which say

The name 'var' does not exist in the current context

and

The name 'GroupedBySection' does not exist in the current context

Any idea what I'm doing wrong?

Alternatively, any suggestions for how I can get a C# object that has the entire groupings and subgroupings so that I don't have to write all this crap in my View?

My Controller method for this page is like

    [HttpGet]
    public ActionResult Peek ( Guid pid )
    {
        ViewBag.PartnerId = pid;
        List<AnswerInfo> AllAnswers = this._Db.GetAnswersByPartner(pid);
        ViewBag.GroupedBySec = AllAnswers.GroupBy(A => A.SectionTitle);
        return View();
    }

Upvotes: 1

Views: 110

Answers (1)

user3559349
user3559349

Reputation:

Your error occurs because you're missing the braces around your var statement. It should be:

@{ var GroupedBySubsection = G.GroupBy(x => x.SubsectionTitle); }

This will then throw a different error because you referring an item in ViewBag which is dynamic so you need to cast it as follows

@{ var GroupedBySubsection = ((IEnumerable<yourModel>)G).GroupBy(x => x.SubsectionTitle); }

making your view even uglier.

how I can get a C# object that has the entire groupings and subgroupings so that I don't have to write all this crap in my View?

Use a view model. Based on some of your previous question, you have a data model which (abbreviated) is:

public class Answer
{
    public string Section { get; set; }
    public string SubSection { get; set; }
    public int QuestionID { get; set; }
    public string QuestionText { get; set; }
    ....
}

And you want to group it in the view by Section and then SubSection. Your view models would then be:

public class SectionVM
{
    public string Title{ get; set; }
    public List<SubSectionVM> SubSections { get; set; }
}
public class SubSectionVM
{
    public string Title { get; set; }
    public List<QuestionVM> Questions { get; set; }
}
public class QuestionVM
{
    public int QuestionID { get; set; }
    public string QuestionText { get; set; }
    ....
}

Your controller code would then be:

var answers = db.Answers..... // your previous query

List<SectionVM> model = answers.GroupBy(x => x.Section).Select(x => new SectionVM
{
    Title = x.Key,
    SubSections = x.GroupBy(y => y.SubSection).Select(y => new SubSectionVM
    {
        Title = y.Key,
        Questions = y.Select(z => new QuestionVM
        {
            QuestionID = z.QuestionID,
            QuestionText = z.QuestionText,
            ....
        }).ToList()
    }).ToList()
}).ToList();
return View(model);

and in the view

@model List<SectionVM>
@foreach(var section in Model)
{
    <h2>@section.Title</h2>
    foreach(var subSection in section.SubSections)
    {
        <h3>@subSection.Title</h3>
        foreach(var question in subSection.Questions)
        {
            <p>@question.QuestionText</p>
            ....
        }
    }
}

Side note: I have made the collection properties List<T> assuming that you might want to also generate a form for editing the Questions/Answers and to do so you will need a for loop which required the collection to implement IList. Alternatively you could save the extra overhead of .ToList(), keep them as IEnumerableand use a customEditorTemplate` for each view model type.

For an example of how an edit view might look (using the for loop option), refer to this answer.

Upvotes: 3

Related Questions