isa isa - 1 month ago 5
ASP.NET (C#) Question

.net MVC passing linq data from controller to view

I am trying to pass data from controller to view. I have searched the web but could not find a solution.

if I do this it works:

Controller:

var yyy = (from a in Connection.Db.Authorities select a) ;
ViewBag.data = yyy;


View:

@foreach(var item in ViewBag.data)
{
@item.Value
}


But the following code does not work:

Controller:

var yyy = (from a in Connection.Db.Authorities select new {Value = a.Value, TypeCode = a.TypeCode, Return = Calculate(a.Return)}) ;
ViewBag.data = yyy;


View:

@foreach(var item in ViewBag.data)
{
@item.Value
}


It gives "item does not contain a definition for Value" for the view file.

Any help would be great.

Thank you.

-edited: updated the second controller linq query. and corrected the first controller linq query.

Answer

It's because You already select Value and Value has no such property as Value. You should change in controller:

var yyy = (from a in Connection.Db.Authorities select a.Value); to

var yyy = (from a in Connection.Db.Authorities select a);

OR change the view to

@foreach(var item in ViewBag.data)
{
    @item
}

//////////////////////////////////////////////// EDITS ////////////////////////////////////////////////
Than You should not use anonymous object. You should create ViewModelClass. For Example:

public class AuthoritiesViewModel
        {
            public string Value { get; set; }
            public string TypeCode { get; set; }
            public string Return { get; set; }
        }

And change your controller:

var yyy = (from a in Connection.Db.Authorities select new AuthoritiesViewModel{ Value = a.Value, TypeCode = a.TypeCode, Return = Calculate(a.Return)});
ViewBag.data = yyy;

and in your view you will be able to use:

<table>
    <tr>
         <th>Value</th>
         <th>TypeCode</th>
         <th>Return</th>
    </tr>
@foreach(AuthoritiesViewModel item in ViewBag.data)
{
    <tr>
         <td>@item.Value<td>
         <td>@item.TypeCode<td>
         <td>@item.Return<td>
    </tr>
}
</table>

Also, I have a question to You. Why do You use ViewBag to pass data from controller to view? Why don't You use Model to pass these data to view according to MVC pattern?

//////////////////////////////////////////////// MORE EDITS ////////////////////////////////////////////////
To send more than one query result You can create more complex model. For example:

public class AuthoritiesViewModel
        {
            public string Value { get; set; }
            public string TypeCode { get; set; }
            public string Return { get; set; }
        }

        public class AnotherQueryViewModel
        {
            public string AnotherQueryValue { get; set; }
            public string AnotherQueryTypeCode { get; set; }
            public string AnotherQueryReturn { get; set; }
        }

        public class ModelClass
        {
            IEnumerable<AuthoritiesViewModel> Authorities { get; set; }
            IEnumerable<AnotherQueryViewModel> AnotherQueryResults { get; set; }
        }

And change the controller:

var yyy = (from a in Connection.Db.Authorities select new AuthoritiesViewModel{ Value = a.Value, TypeCode = a.TypeCode, Return = Calculate(a.Return)});

// do your another select
var zzz = (from smthing select new AnotherQueryViewModel ...)

// create model instance
ModelClass model = new ModelClass() 
{
    Authorities = yyy.AsEnumerable(),
    AnotherQueryResults = zzz..AsEnumerable()
}

// return view with model
return View("view", model);

and in view you can use:

@model ModelClass

@*display first query result*@
<table>
    <tr>
         <th>Value</th>
         <th>TypeCode</th>
         <th>Return</th>
    </tr>
@foreach(AuthoritiesViewModel item in Model.Authorities)
{
    <tr>
         <td>@item.Value<td>
         <td>@item.TypeCode<td>
         <td>@item.Return<td>
    </tr>
}
</table>

@*display second query result*@
<table>
    <tr>
         <th>Another Query Value</th>
         <th>Another Query TypeCode</th>
         <th>Another Query Return</th>
    </tr>
@foreach(AnotherQueryViewModel item in Model.AnotherQueryResults)
{
    <tr>
         <td>@item.AnotherQueryValue<td>
         <td>@item.AnotherQueryTypeCode<td>
         <td>@item.AnotherQueryReturn<td>
    </tr>
}
</table>
Comments