ASP.Net MVC Razor Sum and Count functions - c#

Is it possible to use "Sum" within Razor, so you can sum up what has been interated through on the view. ie. my view is like this:
#model IEnumerable<cb2.ViewModels.ResultsVM>
...
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Qualified)
</td>
...
}
I then want to sum up all of the Qualified in at the bottom of the screen similar to this:
#Model.Qualified.Sum()
But I get the error:
'System.Collections.Generic.IEnumerable<cb2.ViewModels.ResultsVM>' does not contain a definition for 'Qualified'
I thought it would have been easy in Qazor to simply use Sum or Count on a model?
thanks, Mark

I think you want:
#Model.Sum(i => i.Qualified)
Qualified is a property of the items within the model, not the model itself.

Remember that Model is an IEnumerable<cb2.ViewModels.ResultsVM>, it does not contain a property for Qualified, but each item within the collection does. So you can call Sum directly on the collection and specify the property that you want to sum, namely Qualified...
#Model.Sum(x => x.Qualified)

Related

Edit IEnumerable collection of items simultaneously in a View in MVC 5

I have a collection of items, name it type "A", that I want to view and edit some of its attributes in a View. I would like it to save simultaneously, however, this does not seem to work as it does not seem like it is passing anything back to the Post method.
My Controller:
[HttpPost]
public ActionResult inline(IEnumerable<A> listA)
{
for (int i = 0; i <= listA.Count(); i++ )
{
A theObj = listA.ElementAt(i);
db.SaveChanges();
} //Somehow this is returning to be Null
}
My View:
#model IEnumerable<A>
#using (Html.BeginForm())
{
#Html.EditorForModel("Multiple")
}
So far this prints out all the Id of the entries (with no formatting/line breaks, of course) for some reason.
And I am not sure how to create an editor template "Multiple", this is what I have so far:
#model Models.A
#Html.EditorFor(x => x.Id)
I'm not sure where to put it / create it, so I just made it as another view in the same folder.
Any pointers how I can make this to work, so that I can edit multiple entries of the same object in the same view and pass it back to the controller and save it? I'm a newbie to MVC, so if this seems like a really simple question, I apologize in advance. Thanks!
Like most things in programming, there's multiple ways to achieve this. If you want to go the editor template route, though, it's pretty straight-forward.
As #JamieD77 pointed out, editor templates go into Views\Shared\EditorTemplates. The most important part of that path is the EditorTemplates directory convention, though. Just as with any other view in MVC, you can override/fallback depending on where you place your view. For example, Areas\Foo\Views\Shared\EditorTemplates, will work as well, but then it's only available to the Foo area. Or, you can override it for a particular controller by placing it in Views\Foo\EditorTemplates.
Then, the name of the view should correspond with the type it's intended to be used with. In your case, the view should be named A.cshtml. You can technically specify the view name manually by either passing it to EditorFor or using something like UIHint, but it's easier and more foolproof to just rely on convention here.
Inside this view, you should create the look and feel you want to have a for a single instance of A, with all editable properties represented. Then, in your main view, you simply call Html.EditorFor on the collection property, which in your case here, is the whole model:
#Html.EditorFor(model => model)
Razor will realize it has a collection and render the editor template for each item in the collection. Importantly, because it has this context, it will also be able to generate the appropriate indexes on the field names.
If you did something like the following instead:
#foreach (var item in Model)
{
#Html.EditorFor(m => item)
}
Your field names would not be indexed, and the modelbinder would not know what to do with the posted data. If you wanted to use a loop, you would have to use indexing inside the loop:
#for (var i = 0; i < Model.Count(); i++)
{
#Html.EditorFor(m => Model[i])
}
That then gives Razor the proper context to generate appropriate field names. However, importantly, that approach requires utilizing a List<T> structure, rather than something like IEnumerable<T> or ICollection<T>.

Post item of IEnumaration to controller

I am having trouble figuring out what is the best aproach to a rather simple problem.
I have a payment view-model that contains a list of avalible payments and some base properties like title, content...
So in my view I use #using(Html.BeginForm()) and inside that I loop over the payments and render each out and of course the view-model that I recive in my controller post has and empty list of payment methods.
I can see that if I use a for and print out model.paymentMethods[i].Prop than it can map it but is this the right aproach or can I do something even smarter?
For the model-binder to work you need to use indexed access.
#foreach (var item in Model.PaymentMethods)
{
#Html.EditorFor(m => item.Prop);
}
does NOT work.
You need to use:
#for (int i = 0; i < m.PaymentMethods.Count(), ++i)
{
#Html.EditorFor(m => m.PaymentMethods[i].Prop);
}
Otherwise the model-binder can't map it back in the post-back.
Yoy can create a editor template of Payment type. And in view you can use that editor template like:
#Html.EditorFor(m => m.PaymentMethods)

Model binding to a list EditorFor compilation error

What I'm trying to do here appears to be pretty common, but I can't run this code. I get a compilation error.
I'm trying to bind to an ienumerable or icollection in a viewmodel. Is my syntax wrong? Is there a new way of doing thing I missed.
#for(var i=0; i < Model.traces.Count(); ++i)
{
#Html.EditorFor(x => x.traces[i].status)
}
The details of my architecture are at a previous post of mine that led to this...
Getting error on POST with Entity Framework - Value cannot be null. Parameter name: source
Is my syntax wrong?
Yes, IEnumerable or ICollection do not have indexer: x.traces[i].
It would be better if you used a collection whose elements can be accessed by index such as IList<T> or T[], depending on the concrete type of your view model.
Then you will be able to do this:
#model IList<MyViewModel>
...
#for (var i = 0; i < Model.traces.Count; i++)
{
#Html.EditorFor(x => x.traces[i].status)
}
The framework is quite smart in this case, if you have made your own EditorTemplate for the model Trace, you can actually just write
#Html.EditorFor(m => m.traces)
and MVC will render an editor for each item in the list and give you the right fieldnames for each index.

Check for null value of model property inside partial view

I am working on a asp.net mvc 3 application and I've made several partial views each one responsible for rendering of specific logic. Inside one of my views I use properties which can be null, but I don't want to pass null to the #Html.DisplayFor() and write something more user friendly to the user to know that these fields are not missing, they just don't have nothing assigned to them yet.
So I try this :
<tr>
<td>
#if (!string.IsNullOrEmpty(Model[0][0].FieldValue))
{
#Html.DisplayFor(Model => Model[0][0].FieldValue)
}
</td>
<td>
#Html.DisplayFor(Model => Model[1][0].FieldValue)
</td>
</tr>
I don't have else clause because writing the if statement results in getting both Model => in the DisplayFor marked with red and the following message :
A local variable named 'Model' can not be declared in this scope
because it would give a different meaning to 'Model' which is already
used in a 'parent or current' scope to denote something.
Basically I think I understand what this error means however I don't know how to check for null properly in this situation.
The error message is caused by the redefinition of the Model variable. Try
#Html.DisplayFor(x => x[0][0].FieldValue)
You might find this SO question useful to understand the "=>" thingie.

Asp.net mvc html.DisplayFor syntax in linq/lambda

I'm currently studying asp.net mvc and I just started, I decided to move away from web forms to mvc.
I understand the basics of linq and lambdas but I would just like to know or get a good explanation about this particular syntax.
#model IEnumerable<CodeplexMvcMusicStore.Models.Album>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Genre.Name)
</td>
I would just like to know what is the meaning of modelItem => item.Genre.Name
My knowledge on this is that modelItem gets the value item.Genre.Name and then it is passed method Html.DisplayFor().
I'm also curious about how do I write the same code without using lambda.
Correct me if I'm wrong I would just like to know the meaning of the code and how it is read.
Read this: Why All The Lambdas? : Good article explaining the use of Lambdas.
The lambda expressions (of type Expression) allow a view author to use strongly typed code, while giving an HTML helper all the data it needs to do the job.
You can write
#model IEnumerable<CodeplexMvcMusicStore.Models.Album>
#foreach (var item in Model) {
<tr>
<td>
#Html.Raw(item.Genre.Name)
</td>
Or
#model IEnumerable<CodeplexMvcMusicStore.Models.Album>
#foreach (var item in Model) {
<tr>
<td>
#item.Genre.Name
</td>

Categories