i have html.partial in my html markup which is getting and displaying all the records from database. but i want to change it to selected records.. i mean i want to put where clause in html.partial.. is it possible to add where clause in partial and filter the records?
my html markup is like this
#Html.Partial("ListProductPartial", Model.Data.OrderByDescending(o => o.Id))
i am very much new to asp.net mvc. i am using pre defined code and want to understand the code. i hope you guys will help me to resolve this issue..
Depending on your model, this should work (keeping the OrderByDescending):
#Html.Partial("ListProductPartial", Model.Data.Where(o => o.Name == "FilterText").OrderByDescending(o => o.Id))
I do not recommend this style but you can try this sample;
Partial View
#model List<WebApplication4.Models.WebModelData>
#{
foreach (var item in Model)
{
#Html.Raw(item.Value)
}
}
Call to partial
#Html.Partial("PartialView", Model.Data.Where(o => o.Id > 5).ToList())
Controller:
public ActionResult Index()
{
List<Student> ob = new List<Student>()
{
new Student{ id=1, Name="x"},
new Student{ id=2, Name="y"},
};
return View(ob);
}
Index:
#model List<WebApplication15.Controllers.Student>
#{
ViewBag.Title = "Index";
}
#Html.Partial("Name",Model.OrderByDescending(x=>x.id))
<h2>Index</h2>
Partial View:
#model IEnumerable<WebApplication15.Controllers.Student>
#foreach (var student in Model)
{
<li>#student.id</li>
<li>#student.Name</li>
}
Related
Controller action method-
public ActionResult Index()
{
var todaysTarget = from ra in db.Employee ...
select new { ra.RaCode, ra.TargetQuantity };
return View(todaysTarget.ToList());
}
Razor view-
#model List<object>
#foreach (var item in Model)
{
#:item.Name;
}
It gives me exception-
this dictionary requires a model item of type 'System.Collections.Generic.List`1[System.Object]'.
Any help?
Try in your view:
#model List<dynamic>
Or try in your return statement doing:
return View(todaysTarget.Cast<object>().ToList());
But if you do the latter, the item.Name statement will raise an error (type Object doesn't have a property of Name) which is why dynamic should get the job done.
This should work . I tried locally .
#model IEnumerable<dynamic>
<div>
<h1> Test</h1>
#foreach (var item in Model)
{
#item.Name;
}
</div>
I am having a problem in a ASP.NET MVC project. I have a database where I have several tables, and I want to list all the records inside each table in my View, I am able to do this using only one table, I am going to provide here the code that works with one table and what I am trying to do.
Controller:
Using only one table I would do:
Mp5DataclassesDataContext db = new Mp5DataclassesDataContext();
public ActionResult Admin()
{
return View(db);
}
This is what I am trying to do:
return View(db);
At this point I can debug and see that all my tables are in that db object, with all the correct data. Then the problem is in my View
View:
#*This is defined at the top of my .cshtml*#
#model IEnumerable<Interface_AutoUtad.Models.Mp5DataclassesDataContext>
#*This is the code that works with only one table*#
#foreach (var item in Model)
{
#Html.DisplayFor(modelItem => item.table_column)
}
#*What I am trying to do:*#
#foreach (var item in Model)
{
#Html.DisplayFor(modelItem => item.some_other_table.table_column)
}
I can't get this last part to work because "some_other_table" doesn't show up.
Is there a way I can achieve this ? I want to Iterate through each table and inside iterate through each record in that table.
Thank you all in advance :)
It looks like you've set the "model" for your view to be your application's DbContext. Don't do that. Views are only processed at runtime, and querying into your database is way too much logic for a view. Any errors will only be exposed at runtime, and you have a huge potential for errors.
Views are designed to work with only one type. If you need to work with multiple types in the same view, you can either utilize a view model or use child actions.
View Model
public class MultipleTypesViewModel()
{
public IEnumerable<SomeType> SomeTypes { get; set; }
public IEnumerable<OtherType> OtherTypes { get; set; }
...
}
Then in your view:
#model Namespace.To.MultipleTypesViewModel
...
#foreach (var item in Model.SomeTypes)
{
#Html.DisplayFor(modelItem => item.table_column)
}
#foreach (var item in Model.OtherTypes)
{
#Html.DisplayFor(modelItem => item.table_column)
}
...
Child Actions
[ChildActionOnly]
public ActionResult ListSomeTypes()
{
var someTypes = db.SomeTypes.ToList();
return PartialView(someTypes);
}
[ChildActionOnly]
public ActionResult ListOtherTypes()
{
var otherTypes = db.OtherTypes.ToList();
return PartialView(otherTypes);
}
...
Then, create an appropriate partial view for each:
ListSomeTypes.cshtml
#model IEnumerable<Namespace.To.SomeType>
#foreach (var item in Model)
{
#Html.DisplayFor(modelItem => item.table_column)
}
ListOtherTypes.cshtml
#model IEnumerable<Namespace.To.OtherType>
#foreach (var item in Model)
{
#Html.DisplayFor(modelItem => item.table_column)
}
Etc. And then finally in your main view:
#Html.Action("ListSomeTypes")
#Html.Action("ListOtherTypes")
(In this case, the model of the main view is totally irrelevant.)
I tried to follow this, as it was quoted as an example in many places:
http://weblogs.asp.net/mikebosch/archive/2008/11/25/hierarchical-treeview-with-asp-net-mvc-jquery.aspx
and have come up with the following (a few alterations due to me using mvc4 not 2)
In the controller class:
public ActionResult Index()
{
MenuDBContext db = new MenuDBContext();
ViewData["AllMenu"] = db.Menus.ToList();
return View(db.Menus.ToList().Where(c => c.PId == null));
}
The view class:
#{
ViewBag.Title = "Index";
}
#model IEnumerable<Geo.Models.Menu>
<h2>Index</h2>
#foreach (var item in Model)
{
<li>
#item
#{var children = ViewData["AllMenu"].Where(c => c.PId == item.Id);}
#if (children.Count() > 0)
{
<ul>
#{Html.RenderPartial("ItemControl", children);}
</ul>
}
</li>
}
I can't for the life of me work out why I can't use .Where on ViewData["AllMenu"] or .Count() on children. Any tips on where I am going wrong would be fantastic.
You need to cast ViewData["AllMenu"] as IEnumerable<
var children = (ViewData["AllMenu"] as IEnumerable<GeomantApp.Models.Menu>).Where(c => c....
ViewData is Dictionary<string,object> so when you try and get a property from that dictionary, ASP.NET has no way of knowing what it is before hand so you get compiler errors if you don't cast your object first.
I believe that I couldn't find a proper title to explain my problem but I think this is the best possible short explanation.
Please let me explain the details.
I want to show a list of my pictures on a page and using a #foreach loop on MVC 3.
Partial View of this list as below:
#model IEnumerable<Picture>
#foreach (var item in Model)
{
<a href="#item.PicId">
<img height="35px" style="padding-top:3px" src="ImageHandler.ashx?id=#item.PicId" id="pictureMy" />
</a>
}
As you may understand I am sending a list to this partialview and it is placing the pictures on a single column.
It is working without any problem but I want to show 3 pictures for each row but couldn't manage.
Any guidance will be very appreciated.
Thanks in advance for your helps.
You could group them by 3:
#model IEnumerable<Picture>
#foreach (var item in Model.Select((value, index) => new { value, index }).GroupBy(x => x.index / 3))
{
<div>
#foreach (var picture in item)
{
<a href="#picture.value.PicId">
<img height="35px" style="padding-top:3px" src="ImageHandler.ashx?id=#picture.value.PicId" id="pictureMy" />
</a>
}
</div>
}
But honestly this grouping is not something that should be done in the view. You should define a view model and then have your controller action perform the grouping and return the view model.
So let's start by defining our view models:
public class PictureViewModel
{
public int PicId { get; set; }
}
public class GroupedPicturesViewModel
{
public IEnumerable<PictureViewModel> Pictures { get; set; }
}
then the controller action:
public ActionResult Index()
{
// fetch the pictures from the DAL or something
IEnumerable<Picture> pictures = ...
// Now build the view model
var model = pictures
.Select((value, index) => new { value, index })
.GroupBy(x => x.index / 3)
.Select(x => new GroupedPicturesViewModel
{
Pictures = x.Select(p => new PictureViewModel
{
PicId = p.value.PicId
})
}
);
return View(model);
}
then the corresponding view:
#model IEnumerable<GroupedPicturesViewModel>
#Html.DisplayForModel()
then the corresponding display template for the GroupedPicturesViewModel type (~/Views/Shared/DisplayTemplates/GroupedPicturesViewModel.cshtml):
#model GroupedPicturesViewModel
<div>
#Html.DisplayFor(x => x.Pictures)
</div>
and finally the display template for the PictureViewModel type (~/Views/Shared/DisplayTemplates/PictureViewModel.cshtml):
#model PictureViewModel
<a href="#Model.PicId">
<img class="image" src="#Url.Content("~/ImageHandler.ashx?id=" + Model.PicId)" alt="" />
</a>
One final thing that's bugging me is this anchor. Looks ugly. Don't you think? Looks like spaghetti code.
Let's improve it by writing a custom, reusable HTML helper which will render those pictures:
public static class HtmlExtensions
{
public static IHtmlString Picture(this HtmlHelper<PictureViewModel> htmlHelper)
{
var anchor = new TagBuilder("a");
var picture = htmlHelper.ViewData.Model;
var id = picture.PicId.ToString();
var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
// You probably need another property on your view model here as this
// id is suspicious about href but since that's what you had in your
// original code I don't know what is your intent.
anchor.Attributes["href"] = id;
var image = new TagBuilder("img");
image.Attributes["alt"] = "";
image.Attributes["src"] = urlHelper.Content(
"~/ImageHandler.ashx?id=" + urlHelper.Encode(id)
);
image.AddCssClass("image");
anchor.InnerHtml = image.ToString();
return new HtmlString(anchor.ToString());
}
}
and then in the display template we will simply have:
#model PictureViewModel
#Html.Picture()
And that's pretty much it. No need to write loops. Everything works by convention.
I have a model with a List<string> property. I want to present several select lists that bind to that property.
For example, supposed my model is named Favories, and I let the user select several favorite colors.
public class Favorites
{
public List<string> FavoriteColors { get; set;}
}
I tried binding using the indexes to the collection, but I ran into problems, most likely because FavoriteColors was empty. Here's the code that doesn't work (null exception):
#Html.DropDownListFor(m => m.FavoriteColors[0], ColorSelectList, "Select a color (required)")
#Html.DropDownListFor(m => m.FavoriteColors[1], ColorSelectList, "Select a color (optional)")
#Html.DropDownListFor(m => m.FavoriteColors[2], ColorSelectList, "Select a color (optional)")
I realize I could fix this a couple ways.
Populate FavoriteColors with 3 empty values. But this doesn't feel right since my model would have invalid data (empty values) that I'd have to workaround in a bunch of other places in my code.
Change my model so that I have 3 string properties (e.g. FavoriteColor1, FavoriteColor2, FavoriteColor3). Binding would be easier, but I'd still have to work around that deisgn with a bunch of code.
Is there a better way?
Here is a simple solution that will work for you using Razor and standard DropDownListFor<T> helpers.
All based on example data and files which you can change to suit your needs:
HomeController.cs
public class HomeController : Controller
{
public class FavoriteColorModel
{
public List<string> FavoriteColors { get; set; }
}
public ActionResult Index()
{
ViewBag.ColorList = new[]
{
"Blue",
"Red",
"Green",
"Orange"
};
var favoriteColors = new FavoriteColorModel()
{
FavoriteColors = new List<string>()
{
"Color1",
"Color2",
"Color3"
}
};
return View(favoriteColors);
}
[HttpPost]
public ActionResult Save(FavoriteColorModel model)
{
TempData["SelectedColors"] = model.FavoriteColors;
return RedirectToAction("Index");
}
}
Index.cshtml
#model MvcApplication4.Controllers.HomeController.FavoriteColorModel
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
#if (TempData["SelectedColors"] != null)
{
<text>
You have selected the following colors:<br />
<ul>
#foreach (var color in TempData["SelectedColors"] as List<string>)
{
<li style="color:#color">#color</li>
}
</ul>
</text>
}
#using (Html.BeginForm("Save", "Home"))
{
#: Favorite colors:
for (var index = 0; index < Model.FavoriteColors.Count; index++)
{
#Html.DropDownListFor(model => model.FavoriteColors[index], new SelectList(ViewBag.ColorList))
}
<br />
<input type="submit" value="Save" />
}
Your selected colors will appear in a list element upon submit. You can control the amount of colors you wish to save by adding items to the Color1, Color2 array etc.
Peace.
This is how I would do it because I dont like the way MVC handles drop down lists.
foreach (var ColorArray in m.FavoriteColors)
{ %>
<select name='colors'>
<% foreach (var color in ColorArray)
{%>
<option><%= color.ToString() %></option>
<% { %>
</select>
}%>
You could hard code it to just the indexes you want but you get the general idea. Also this would allow you to put in null checks whereever you like to handle those cases selectively.