Passing object containing object from model to view in ASP.NET - c#

Usin ASP.NET I am trying to add a list of profiles to a object in a model and then enumerate over this list in the view.
public ActionResult Index(BlogPage currentPage)
{
var model = new BlogPageModel(currentPage);
var pages = new List<BlogPage>();
var profilePages = new List<ProfilePage>();
if (currentPage.ProfileArea != null)
{
foreach (LinkItem linkItem in currentPage.ProfileArea)
{
var page = _pageDataHelper.GetPageData(linkItem);
var profilePage = page as ProfilePage;
if (profilePage != null)
{
profilePages.Add(profilePage);
}
}
model.Profiles = profilePages;
}
return View(model);
}
Using this code in the view:
#foreach (ProfilePage profile in Model.BlogPages)
{
#Html.Partial("../ProfilePage/Index", new PageViewModel<ProfilePage>(profile))
}
However above code returns the error:
CS0030: Cannot convert type 'Models.Pages.BlogPage' to 'Models.Pages.ProfilePage'
Can someone point me the correct way to store a list inside a model and render this nested object in a view?
Thanks!

Hi Its seems that you have problem in the for each loop,but i couldn't exactly figure out the problem line, since model is not available above.
Answer to your question:
Can someone point me the correct way to store a list inside a model and render this nested object in a view?
ex:
public class somemodelname
{
public list<anytype> somepropertyname{get;set;}
}
accessing:
#foreach (var singlevalueOrObj in Model.somepropertyname)
{
#Html.Partial("../ProfilePage/Index", new PageViewModel<singlevalueOrObj >(profile))
}
In the above way you can store any list object inside your model and for rendering the page as same way as you did in the above that is using the partial view.
Hope above information was helpful.
Thanks
Karthik

You have a typo in your foreach loop:
#foreach (ProfilePage profile in Model.BlogPages)
{
#Html.Partial("../ProfilePage/Index", new PageViewModel<ProfilePage>(profile))
}
You are looping over the property BlogPages not the property Profiles that you set with a ProfilePage collection in your controller:
var pages = new List<BlogPage>();
var profilePages = new List<ProfilePage>();
if (currentPage.ProfileArea != null)
{
...shortened for length...
model.Profiles = profilePages; // Right here is what you intended to loop over
}

Related

How to resolve: Cannot implicitly convert system.collections.generic.list to system.collections.generic.ienumerable

I get this error
Cannot implicitly convert System.Collections.Generic.List to System.Collections.Generic.IEnumerable
when trying to use a list to build out #Html.DropDownList() in a page built using C# Razor.
There is a C# class called SubProgram.cs with the following method that returns a List<>:
public List<SubProgram> SubProgramCodeDescriptionList()
{
List<SubProgram> SubPrograms = new List<SubProgram>();
// Get the list of SubPrograms for this AcctIII role_code from BudgetAcct3ToSubProgram table
using (var db = Database.Open("DBNAME"))
{
string sql = #"
SELECT l.SubProgramID, l.SubProgram + ' ' + l.SubProgramDesc AS SubProgramDesc
FROM BARF_SubPrograms l
WHERE l.Deleted = 0
ORDER BY l.SubProgramDesc";
var ListSubPrograms = db.Query(sql);
foreach (var SubProgram in ListSubPrograms)
{
SubProgram item = new SubProgram ();
item.SubProgramID = SubProgram.SubProgramID;
item.SubProgramCodeDescr = SubProgram.SubProgramDesc;
SubPrograms.Add(item);
}
db.Close();
return SubPrograms;
}
}
Here is the SubProgram class this method is a part of:
public class SubProgram
{
private int subprogramid;
private string subprogramcode;
private string subprogramcodedescr;
public int SubProgramID
{
get { return subprogramid; }
set { subprogramid = value; }
}
public string SubProgramCode
{
get { return subprogramcode; }
set { subprogramcode = value; }
}
public string SubProgramCodeDescr
{
get { return subprogramcodedescr; }
set { subprogramcodedescr = value; }
}
}
In the C# section of a Razor page, I create an object of type SubProgram to fill the SubProgramList:
// Create List boxes variable need for this add
List<SubProgram> SubProgramIDdropdownlist = new List<SubProgram>();
// Create SubProgram object so the method can be called
SubProgram subProgram = new SubProgram();
// Pass object to method SubProgramIDdropdownlist to return all of the SubPrograms
SubProgramIDdropdownlist = subProgram.SubProgramCodeDescriptionList();
In the body section of the HTML page below this C# Razor section above, I try to populate the DropDownList with the above code:
<label class="FieldLabels">"Search SubPrograms"</label>
#Html.DropDownList("SubProgramCodes",
SubProgramIDdropdownlist,
new {
#id = "Column1",
#class = "EditTextBox",
}
)
In this last section, the error occurs on SubProgramIDdropdownlist and this is where I get the error
Cannot implicitly convert System.Collections.Generic.List to System.Collections.Generic.IEnumerable
There are other related posts, but not coming from a class method. Please help, I know this needs to probably use a cast, but not even sure where to begin to get this to cast correctly.
Two ways I can think of:
On Razor Page using AsEnumerable
#Html.DropDownList("SubProgramCodes",SubProgramIDdropdownlist.AsEnumarable(),new { #id = "Column1", #class = "EditTextBox"})
OR
Change the return type from List<SubProgram> to IEnumerable<SubProgram>
public IEnumerable<SubProgram> SubProgramCodeDescriptionList(){...}
Thank you tontonsevilla, your answer was helpful in solving this.
The final solution I came up with is that there was a conflict between two namespaces that both contained SelectListItem in both of them: System.Web.Mvc and System.Web.WebPages.Html.
Since I am primarily using Razor pages and not MVC for this project, I removed the #using System.Web.Mvc at the top of the Razor C# page because the error made it clear that SelectListItem is found in both System.Web.Mvc and in System.Web.WebPages.Html and I clearly needed to use one or the other, but not both. I was able to cast these to get them to work, but this was just a lot of extra code that was not needed when I realized it was a name conflict.
Using both namespaces created a conflict between these two namespaces because SelectListItem appears to be in both namespaces.

Passing a List from Controller to View in MVC - Can't get string using foreach

I'm trying to pass a List from my controller to a view.
The model as defined in my view is:
#model List<prismic.starter.Models.ResourceModel>
I am passing a List<ResourceModel> from my controller to the view:
public async Task<ActionResult> resources()
{
var docArray = await new Prismic_Connect().getAllByType("resource");
List<ResourceModel> resourceList = new List<ResourceModel>();
foreach(var doc in docArray)
{
resourceList.Add(new ResourceModel(doc));
}
return View(resourceList);
}
I can get the string value I am trying to display by writing the following:
#Model.First().getTitle();
However, when I try to loop through the list using foreach , the "title" string is not displayed.
#{
foreach (var doc in Model)
{
doc.getTitle();
}
}
What am I doing wrong here?
You missing the leading # which tells the razor engine to output the value
#foreach (var doc in Model)
{
#doc.getTitle(); // add #
}

Pass a generic list from controller to view mvc

I've racked my brain over this for way to long now to I'm deferring to the experts. I know this question has been asked and answered several times but I can't seem to get ANYTHING to work. Here's the scenario: As the title says, I'm trying to pass a list from the controller to the view. I'm using an API that has a method, "GetInventoryLocations" whose base type is List<string>. In the example below I instantiate a new list and use a foreach to loop through the "InventoryLocation" programatically casting each item in the collection to a string and adding it to the list I created "locationlist". Finally I assign the list to the viewdata. From there I've tried all kinds of things in the view but still can't get it to work. Thanks for any help. Be kind to a junior developer.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Moraware.JobTrackerAPI4;
using Evolveware1_0.Models;
namespace Evolveware1_0.Controllers
{
[Authorize]
public class InventoryController : Controller
{
//./Inventory/Locations
[HttpGet]
public ActionResult Index()
{
//declare variables for connection string to JobTracker API Service
var DB = "databasename"; // your DB name here
var JTURL = "https://" + DB + ".somecompany.net/" + DB + "/";
var UID = "****"; // your UID here - needs to be an administrator or have the API role
var PWD = "password"; // your PWD here
//connect to API
Connection conn = new Connection(JTURL + "api.aspx", UID, PWD);
conn.Connect();
//declaring the jobtracker list (type List<InventoryLocation>)
var locs = conn.GetInventoryLocations();
//create a new instance of the strongly typed List<string> from InventoryViewModels
List<string> locationlist = new List<string>();
foreach (InventoryLocation l in locs) {
locationlist.Add(l.ToString());
};
ViewData["LocationsList"] = locationlist;
return View();
}//end ActionResult
}
};
And in the view:
#using Evolveware1_0.Models
#using Evolveware1_0.Controllers
#*#model Evolveware1_0.Models.GetLocations*#
#using Evolveware1_0.Models;
#{
ViewBag.Title = "Index";
}
<h2>Locations</h2>
#foreach (string l in ViewData["LocationList"].ToString())
{
#l
}
You are doing a toString() to a list, this will not work. You will need to cast your ViewData to it's proper type, a list of InventoryLocation.
Being that you are using Razor and MVC, I suggest using ViewBag instead, no casting necessary.
In your controller instead of ViewData["LocationList"] = locationlist, initialize a ViewBag property to pass to your view.
ViewBag.LocationList = locationlist;
Then in your view in your loop just access your ViewBag.LocationList object.
#foreach (string l in ViewBag.Locationlist)
{
#l
}

Ext.net howto access treepanel nodes

I am a beginer in ext.net. I have created a simple tree with dynamic loading using proxy from out database.
#{
Layout = null;
}
#{
var thisPlugin = Model as IPlugin;
if (thisPlugin == null)
{
throw new Exception("IPlugin expected");
}
var loadChildrenFunc = new Func<string>(() =>
{
string retVal = Url.Action("GetChildren/" + Url.Encode(thisPlugin.Id));
return retVal;
});
var tree = Html.X().TreePanel().ID("FACILITY_TREE");
}
#(tree.Title("Facility tree")
.Icon(Icon.Table)
.Frame(true)
.Height(450)
.Width(300)
.Border(false)
.Store(Html.X().TreeStore().Proxy(Html.X().AjaxProxy().Url(loadChildrenFunc())))
.Root(Html.X().Node().NodeID("0").Text("Facility objects tree")))
Treepanel succesfuly created and loads nodes.
The problem I have is to acces tree to save it state.
For example then expand/collapse nodes i need to call controller and save treeview state. So the question is how to solve it?
Anoter, after click/double click i need to call JS function to modify some data on page.
Please help. Thanks!
i think you need to add a event listener.
like this
listeners: {
collapse: function() {
alert('collapsed');
},
expand: function() {
alert('expand')
},
itemclick: function(s,r) {
alert(r.data.text);
}
}
hope this helps

Fetching collection inside nhibernate session

One property has many photos. One photo belong to one property.
Inside my mvc controller I'm getting as parameter array of integers. These integers represents id of Photo which I want to delete.
I'm using nhibernate session and transaction to interact with db.
public ActionResult DeleteImgs(int[] data)
{
Property p = null;
using (ISession session = ....)
{
using(ITransaction transaction session.BeginTransaction())
{
Photo photo = session.Get<Photo>(data[0]);
p = session.Get<Property>(photo.Id);
// found images and delete them
foreach(int id in data)
{
Photo ph = session.Get<Photo>(id);
//remove property from association so I can delete photo
ph.Property = null;
session.Delete(ph);
session.SaveOrUpdate(ph);
}
//load property now with collection of remaining photos
// here IS THE PROBLEM, Even there is photos inside collection
// in debug I'm getting empty collection
p = session.Query<Property>().
.Fetch(x=>x.Photos).ToList() //empty?
.FirstOrDefault;
transaction.Commit();
}
}
return View();
}
Since I'm sending just IEnumrable of photos to the view problem is solved like this,
instead of sending lazy load property photos collection I'm sending IEnumerable of Photos like this
IEnumerable<Photo>photos = session.Query<Photo>().Where(x => x.Property == p).ToList();

Categories