Before I had this:
public ActionResult ShowSong(int id)
{
return view(db.PublishedSongs.Where(x => x.Id == id).FirstOrDefault());
}
and in my view:
#model MusicSite.Models.PublishedSong
<h2>#Model.SongName</h2>
#Html.ImageFor(x => x.CoverImageBytes, #Model.SongName + " Image", new { #class = "big-cover-image" })
This worked fine for just retrieving one item from DB and showing on view.
However now, I need to also pass a list to my view, because I want to show all of the items in model and just the select item that was passed through action method, how do I do this?
If I pass return View(db.PublishedSongs); to view then I no longer know which id to get to show just that one item.
As I am not that much good in .NET MVC but I will try to answer according to spring MVC knowledge.
The rough idea is to pass list to view as you are mentioned and along with it pass the id that you want to select using ViewBag. Now in view iterate over the list, while iteration check whether id come from iteration is equal to id that you passed in ViewBag.
So in controller :
public ActionResult ShowSong(int id)
{
ViewBag.SelectId = id;
return view(db.PublishedSongs);
}
In View :
(Loop over the db.PublishedSongs)
{
if(PublishedSong.id=#ViewBag.SelectId)
{
//select current PublishedSong
}
else
{
//otherwise
}
}
Related
I am creating products from a product template. Each time a customer selects a product to view information about, the data from that product needs to get loaded. I have created a controller, model and view. The model is generated with TDS. I need to pass the item id to the [SitecoreId] from the controller. Here is the code I am using:
From the layout:
#{var id = Sitecore.Data.ID.Parse("{74A67488-8E33-47E2-86F5-25AD23FDF3D3}"); }
#Html.Sitecore().ControllerRendering("ProductOverview", "Index", new { ItemId = #id })
The controller:
public class ProductOverviewController : Controller
{
private readonly IMvcContext _mvcContext;
public ProductOverviewController(IMvcContext mvcContext)
{
_mvcContext = mvcContext;
}
// GET: ProductOverview
public ActionResult Index()
{
var itemId = string.Empty;
var rc = RenderingContext.CurrentOrNull;
if (rc != null)
{
var parms = rc.Rendering.Properties;
itemId = parms["ItemId"];
}
var dataSource = _mvcContext.GetContextItem<ProductOverviewModel> ();
return View(dataSource);
}
}
The itemId var has the correct id that I am passing from the layout (hard coded for now). From here I am at an absolute loss on how to get that into the model. I have tried dozens of suggestions from searches but the model always uses the current item (as set by GlassBase in the model itself) as opposed to the product id that contains the data for that product.
Is what I want to do even possible? Can the [SitecoreId] even be overridden?
The line where you are setting the value for dataSource using Glass Mapper is where you'll want to make your change..
Glass Mapper lets you use a number of different options to get the Item and cast to your "type" which looks to be ProductOverviewModel currently.
you can use the following for example (notice that I've used .SitecoreService.GetItem instead of .GetContextItem ):
//pass the GUID into here (you'd need to cast to a Guid first instead of ID)
var dataSource = _mvcContext.SitecoreService.GetItem<ProductOverviewModel>(guid);
//or if you wanted to get your ID as a Sitecore Item you could use
var dataSource = _mvcContext.SitecoreService.GetItem<ProductOverviewModel>(item.Paths.Path);
I am passing a ViewBag list to my view and I am trying to display this list in a listbox so as I can select items of this list.
This is the controller method for the view:
public ActionResult AddMembers(int? id)
{
ViewBag.lstMembers = db.ClubMembers.ToList();
var selClub = db.Clubs.Find(id);
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
return View(selClub);
}
This is what I have currently but it is not displaying the items correctly as shown in the photo below:
#Html.ListBoxFor(m => m.ClubMembers, new SelectList ( ViewBag.lstMembers))
How can I set the source of my listbox so that it will display the items passed in via the ViewBag.lstMembers from the controller method
You need to specify the display member and value member that will be used to render the string representation of the object, otherwise MVC will just call ToString.
SelectList has an overloaded constructor for this e.g.:
new SelectList(items, "ValuePropertyName", "DisplayPropertyName")
see here:
https://msdn.microsoft.com/en-us/library/system.web.mvc.selectlist.selectlist(v=vs.118).aspx#M:System.Web.Mvc.SelectList.
you can use MultiSelectList some thing like that
In Action
ViewBag.lstMembers = new MultiSelectList(db.ClubMembers.ToList(), "ValueProperty", "NameProperty");
in View
#Html.ListBox("lstMembers", ViewBag.lstMembers as MultiSelectList)
Partial view does not return any data.When i check with debug tool on PartialView page(_ContentBlock.cshtml), model seem to null.
Controller
public ActionResult Module()
{
int RouteDataValue = default(int);
if (RouteData.Values["id"] != null)
{
RouteDataValue = int.Parse(RouteData.Values["id"].ToString());
}
using (Models.ContentModel db = new Models.ContentModel())
{
var Query = from n in db.PageModule
join m in db.Module on n.ModuleId equals m.ModuleId
where n.PageId == RouteDataValue
select m.PhysicalPath;
return PartialView(Query.Single()); //returns PartialView such as ~/Modules/Content/_ContentBlock.cshtml
}
}
public PartialViewResult ContentBlock()
{
using (Models.ContentModel db = new Models.ContentModel())
{
return PartialView("~/Modules/Content/_ContentBlock.cshtml", db.ContentBlock.Where(n => n.PageId == 2).Single());
}
}
Page.cshtml
#Html.Action("Module")
_ContentBlock.cshtml
#model IEnumerable<Models.ContentBlock>
#foreach (var item in Model)
{
#Html.DisplayFor(n => item.Content)
}
You seem to have used the Html.Partial helper instead of Html.Action. So you were basically only rendering the partial without ever hitting the controller action that is supposed to populate and the model to the partial.
Your page Page.cshtml is calling the partial view action Module using:
#Html.Action("Module")
The action called Module is being executed. In that action, your query results in a path to your view, such as:
"~/Modules/Content/_ContentBlock.cshtml"
That action is returning the single result of that query using:
return PartialView(Query.Single());
What this is doing is passing the name of the view to the PartialView method to return which view is going to be used to display data from the action. In addition, no model data is included in this return.
That's where your problem is. When you return the path to the partial view, you are simply telling the MVC system what view to use to display the data from Module. It won't actually call another partial view. That's not how it works. So your model is null because, you didn't pass any data in your PartialView(...) call.
You have another action called ContentBlock. But that action is not being called because nothing is calling it.
Edit:
Another problem you have is that _ContentBlock.cshtml uses a model of IEnumerable<ContentBlock>, but you're only passing it a .Single() from your ContentBlock action.
Is it possible to cash drop down list?
I'm using a Telerik MVC Window, ComboBox, and the contents of the window (including ComboBox) is being returned with a partial view. Contents of the partial view depends on the list of parameters, but on the every div in this window there is a combo box contents of which is usually unchanged and it contains ~2000 records.
i'm thinking about returning ViewData["ComboContent"] using separate controller with cashing before returning the window itself, but may be there is a better way...
TIA
updated (my controller code):
[AcceptVerbs("GET")]
[OutputCache(Duration = int.MaxValue, VaryByParam = "id")] //Some custom param??
public ActionResult LoadTimeOffset(int id)
{
String error;
IEnumerable<MyModel> model = repo.GetSomeVariableStuff(id, 10, out error); //always varies
ViewData["ComboList"] = new SelectList(repo.GetComboitems(id), "Key", "Value", -1); //changes only on id
if (model.Count() > 0)
{
return PartialView("Partial", model);
}
return Content(error);
}
Cache the data instead of caching the drop-down.
So, instead of putting the SelectList into the ViewData, put the contents for it:
if (HttpContext.Current.Cache["ComboList"] == null)
{
HttpContext.Current.Cache["ComboList"] = repo.GetComboitems(id); //use Add instead so that you can specify the cache duration.
}
ViewData["ComboList"] = HttpContext.Current.Cache["ComboList"]; //take from cache.
Note, code is not accurate, but it is an example only.
Then, in your view, render the combo.
I hope this helps.
i have a dropdown list which select a value
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Screenname(FormCollection collection)
{
Viewdata["screenname"] = collection[0];
return RedirectToAction("Index", new { ScreenName = ViewData["screenname"] });
}
then i want to access this ViewData in other actions like this
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection collection, string screenname)
{
try
{
/// thats my dataobject which creates
DataObj.SaveData(Guid.Empty, collection, screenname);
return RedirectToAction("Index", new { ScreenName = ViewData["screenname"] });
}
catch
{
return View("Error");
}
}
where index looks like this ...
public ActionResult Index(string ScreenName)
{
///thats my list
GetTable = new GetDataTable(ScreenName);
return View(GetTable);
}
First when i select the value and index gets executed properly.... but when i try to access the viewdata again it doesn't contain the value so anybody if please can help ...
or alternate method to save and retrieve data .
The ViewData object is specific for the particular action that is executing. To pass data between actions, use TempData. more on the difference between the two on MSDN.
You can also directly write to the session state through the Controller.Session property.
This has actually been covered quite often here. The solution for now is to use TempData to save the data you need before you use RedirectToAction().
If you do a search for "RedirectToAction" you'll find a number of posts covering this topic, such as this one.
The next official release of the framework will fix this.
I used a view to take the data from the user and then saved it to a static variable and then used this variable to pass the data to all the other views .
Thanks anyways