How to code summary row in ASP.NET Razor table?

I have a table built out in a Razor view that goes like so:

@foreach (var item in Model)
{
    <tr>
        <td>@Html.DisplayFor(modelItem => item.column1)</td>
        ...
        ...
    </tr>
}

I want to add a summary of the table at the end, something like:

<tr>
    <td>@Model.Sum(a => a.column1)</td>
    ...
    ...
</tr>

That actually works but it doesn't use my data annotations since I'm not using DisplayFor(). I tried placing the Model.Sum within a DisplayFor() but the code doesn't work. Can anyone point me towards a solution?

Answers


You could write an HTML helper that examined the property lambda, performed the sum() and utilized your data annotations.

View Model
public class FooViewModel
{
    [Required]
    [Display( Name = "My Display Name" )]
    public int Bar {
        get;
        set;
    }

    public string Baz {
        get;
        set;
    }
}
View
@model IEnumerable<FooViewModel>

@* Razor engine prefers this syntax? think generic may confuse it *@
@(Html.SumFor<FooViewModel>( o => o.Bar ))
Helper Extension

This is far from perfect. An improvement would be to allow any type to be summed without having to provide a different method for every summable type.

public static IHtmlString SumFor<TEnumerableItem>( this HtmlHelper helper, 
    Expression<Func<TEnumerableItem, int>> expression ) {

    // get metadata through slightly convoluted means since the model
    // is actually a collection of the type we want to know about

    // lambda examination
    var propertyName = ( (MemberExpression)expression.Body ).Member.Name;

    // property metadata retrieval
    var metadata = ModelMetadataProviders.Current
        .GetMetadataForProperty( null, typeof( TEnumerableItem ), propertyName );

    // make an assumption about the parent model (would be better to enforce 
    // this with a generic constraint somehow)
    var ienum = (IEnumerable<TEnumerableItem>)helper.ViewData.Model;

    // get func from expression
    var f = expression.Compile();

    // perform op
    var sum = ienum.Sum( f );

    // all model metadata is available here for the property and the parent type
    return MvcHtmlString.Create( 
       string.Format( "<div>Sum of {0} is {1}.</div>", metadata.DisplayName, sum )
    );
}

Need Your Help

Dont want JavaScript to be printed [closed]

javascript xml object xml-parsing

I need some help with my JavaScript, i am trying to sorting XML data with the help of JavaScript, and i am successful doing the sorting part, but the output is returning [object Object], which i do...

Backup/restore sqlite file for Core data with Dropbox

ios sqlite core-data backup dropbox

I'd like to implement a backup and restore feature in a sql-backed Core Data app. I can successfully backup and restore .sqlite file via dropbox, but I have one question about this approach.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.