I am wondering how can an iterate over a session , to which I am assigning a list of string in an action method.
I want to display each of the elements in the session as links via the for loop.
Any help is appreciated.
Here is my index method :
public ActionResult Index()
{
Session["num"] = Posts;
//Posts = new List<string> { "element1", "element2", "element3" };
return View();
}
And here is my view :
<h2>Index</h2>
#foreach (#item c in #Session["num"])
{
}
You will need to cast your session variable since it's an object.
Something like...
#{
var posts = Session["num"] as List<string>;
if (posts != null) {
foreach (var item in posts) {
...
}
}
}
You have tagged this question as asp.net-mvc, why not take advantage of the framework?
Model
class MyModel
{
public List<string> Posts { get; set; }
}
View (Index.cshtml)
#model MyModel
<h2>Index</h2>
#foreach(var post in Model.Posts)
{
<span>#post</span>
}
Controller
public ActionResult Index()
{
var model = new MyModel();
model.Posts = Posts; //Posts = new List<string> { "element1", "element2", "element3" };
return View(model);
}
Related
Currently i am using variables inside my view that have been declared within a model, and assigned values within the respective controller. I am using Model.variableName to reference these variables, however the following exception is thrown during debugging;
I am using the following namespaces within my view;
#using ProjectName.Models
#model Category
My class model;
public class Category
{
public string result { get; set; }
}
My controller;
public ActionResult Index()
{
return View();
}
[HttpGet]
public ActionResult ReadCategory()
{
var dataFile = Server.MapPath("~/App_Data/Category.txt");
Category passCategory = new Category
{
result = "",
delimiterChar = new[] { ',' },
userData = System.IO.File.ReadAllLines(dataFile)
};
return View(passCategory);
}
Any help would be greatly appreciated!
Try moving your code to your index action result like this: (as I suspect your action result ReadCategory is not being utilized)
public ActionResult Index()
{
var dataFile = Server.MapPath("~/App_Data/Category.txt");
Category passCategory = new Category
{
result = "",
delimiterChar = new[] { ',' },
userData = System.IO.File.ReadAllLines(dataFile)
};
return View(passCategory);
}
I am trying to keep dropdownlist selected value if ModelState is not valid
Because i want to keep the data the user selected even if the ModelState is not
valid
My code looks like this
Get Method:
[HttpGet]
public ActionResult Edit(int? Id)
{
using (var db = new NewsDatabaseEntities())
{
db.Configuration.LazyLoadingEnabled = false;
var Result = (from n in db.News.Include("Categories")
from c in db.Categories
where n.NewsId == Id
select new { news = n, neweCategories = n.Categories, cate = c }).ToList();
News NewsDetails = (from news in Result
select new News
{
NewsId = news.news.NewsId,
NewsTitle = news.news.NewsTitle,
NewsBody = news.news.NewsBody,
NewsImagePath = news.news.NewsImagePath,
Categories = news.neweCategories
}).FirstOrDefault();
var AllCategories = (from c in Result
select new Category
{
CategoryId = c.cate.CategoryId,
CategoryName = c.cate.CategoryName
}).ToList();
if (NewsDetails != null)
{
var model = new NewsViewModel();
model.NewsId = NewsDetails.NewsId;
model.AllCategories = AllCategories;
model.Categories = NewsDetails.Categories;
model.NewsTitle = NewsDetails.NewsTitle;
model.NewsBody = NewsDetails.NewsBody;
model.NewsImagePath = NewsDetails.NewsImagePath;
Session["AllCategories"] = new MultiSelectList(AllCategories, "CategoryId", "CategoryName", model.Categories.Select(J => J.CategoryId).ToArray());
Session["model"] = model;
return View(model);
}
else
{
return RedirectToAction("Index", "Home");
}
}
return View();
}
Post Method:
[HttpPost]
[ValidateInput(false)]
public ActionResult Edit(NewsViewModel model,FormCollection col)
{
if (!ModelState.IsValid)
{
model = (NewsViewModel)Session["model"];
return View(model);
}
View:
#Html.DropDownListFor(c => c.SelectedCategoriesIds, (MultiSelectList)Session["AllCategories"], new { id = "DropDownList1", multiple = "multiple", #class = "form-control" })
Because you are overwriting the view model object(which has the selected option value) with your session data which you set in your GET action.
You should read the selected option value to a temp variable and use that.
[HttpPost]
[ValidateInput(false)]
public ActionResult Edit(NewsViewModel model,FormCollection col)
{
if (!ModelState.IsValid)
{
var selected= model.SelectedCategoriesIds;
model = (NewsViewModel)Session["model"];
model.SelectedCategoriesIds =selected;
return View(model);
}
//save and return something**strong text**
}
A better solution is not not use session here. You may simply read the values again from your db table/or cache. Also for rendering the dropdown, you may simply add a property to your view model and use that.
public class NewsViewModel
{
public List<SelectListItem> AllCategories {set;get;}
//Other properties
}
and in your GET action, instead of setting the categories to Session, set it to this property
public ActionResult Edit(int? id)
{
var vm = new NewsViewModel();
vm.AllCategories = GetCategories();
return View(vm);
}
private IEnumerable<SelectListItem> GetCategories()
{
return db.Categories
.Select(s=>new SelectListItem { Value=s.Id.ToString(),
Text=s.Name).ToList();
}
and in your view
#model NewsViewModel
#using(Html.BeginForm())
{
<label> Select items <label>
#Html.ListBoxFor(s=>s.SelectedCategoriesIds,AllCategories )
<input type="submit" />
}
Now in your HttpPost action, when model validation fails, you do not need to use session, just call the same method to re-load the AllCategories property.
if (!ModelState.IsValid)
{
model.AllCategories=GetCategories();
return View(model);
}
I am getting following error:
The model item passed into the dictionary is of type
'Cygnus.Global.ViewModels.StoreViewModel', but this dictionary
requires a model item of type
'Cygnus.Global.ViewModels.ProductOrderViewModel'.
Following is my Model code:
public class StoreViewModel
{
public int Id { get; set; }
public List<StoreViewModel> Stores { get; set; }
}
Following is my Controller Code:
public ActionResult StoreProducts (StoreViewModel model)
{
CygnusInternalResponseViewModel response = new CygnusInternalResponseViewModel();
response = new Logic(CApplicationId, CurrentCompanyId).GetProductsByStoreId(model.Id);
var parentmodel = new ProductOrderViewModel() { Products = response.Model, Orders = new OrderViewModel() };
if (response.Success)
return View(model);
return View();
}
And following is my View Code:
NOTE: StoreViewModel exists in ProductOrderViewModel as a property
#model Cygnus.Global.ViewModels.ProductOrderViewModel
#foreach (var pd in Model.Products)
{
<p>
span class="cmtText"> | #pd.Name | #pd.UnitPrice </span>
</p>
}
#Html.LabelFor(m => m.Orders.SubTotal)
#Html.TextBoxFor(m => m.Orders.SubTotal, new { #readonly = "readonly", #style = "width:100px; float:right;margin-top:-21px;" })
I corrected my mistake in controller
public ActionResult StoreProducts (StoreViewModel model)
{
CygnusInternalResponseViewModel response = new CygnusInternalResponseViewModel();
response = new Logic(CApplicationId, CurrentCompanyId).GetProductsByStoreId(model.Id);
var parentmodel = new ProductOrderViewModel() { Products = response.Model, Orders = new OrderViewModel() };
if (response.Success)
return View(model);
return View();
}
To
public ActionResult StoreProducts (StoreViewModel model)
{
CygnusInternalResponseViewModel response = new CygnusInternalResponseViewModel();
response = new Logic(CApplicationId, CurrentCompanyId).GetProductsByStoreId(model.Id);
var parentmodel = new ProductOrderViewModel() { Products = response.Model, Orders = new OrderViewModel() };
if (response.Success)
return View(parentmodel );
return View();
}
What you don't get about error?
Your View model is Cygnus.Global.ViewModels.ProductOrderViewModel, but you pass from controller model object witch is StoreViewModel.
I gess it's better to write your controller like this:
public ActionResult StoreProducts (StoreViewModel model)
{
CygnusInternalResponseViewModel response = new CygnusInternalResponseViewModel();
response = new Logic(CApplicationId, CurrentCompanyId).GetProductsByStoreId(model.Id);
var parentmodel = new ProductOrderViewModel() { Products = response.Model, Orders = new OrderViewModel() };
if (response.Success)
ViewData.Model = parentmodel //This is right model
return View();
}
I want to automatically generate a list in a partial view.
_Layout.cshtml
#Html.Partial("../Transaction/_Transaction")
TransactionController
public JsonResult transactionlist()
{
List<Transaction> TransactionList = new List<Transaction>().ToList();
string Usercache = MemoryCache.Default[User.Identity.Name] as string;
int UsercacheID = Convert.ToInt32(Usercache);
if (Usercache == null)
{
int UserID = (from a in db.UserProfiles
where a.UserName == User.Identity.Name
select a.UserId).First();
UsercacheID = UserID;
MemoryCache.Default[User.Identity.Name] = UsercacheID.ToString();
}
var Account = (from a in db.UserAccount
where a.UserId == UsercacheID
select a).First();
var DBTransaction = from a in db.Transaction
where a.AccountId == Account.AccountId
select a;
var DBTransactionList = DBTransaction.ToList();
for (int i = 0; i < DBTransactionList.Count; i++)
{
TransactionList.Add(DBTransactionList[i]);
}
ViewBag.acountsaldo = Account.Amount;
return Json(TransactionList, JsonRequestBehavior.AllowGet);
}`
How should my _Transaction.cshtml be coded to make a simple list without submit buttons etc.?
One way is to have a page return a list of items and feed them into your partial.
function ActionResult GetMainTransactionView()
{
List<Transaction> transactions=GetTransactions();
return PartialView("TransactionIndex",transactions);
}
TransactionIndex.cshtml
#model List<Transaction>
#Html.Partial("../Transaction/_Transaction",model)
Main.chtml
<a id="transactionLink" href='#Url.Action("GetMainTransactionView","Transaction")'/>
You should call your controller action and have it return your partial view. Also, use a view model instead of viewbag.
Layout or parent view/partial view:
#Html.Action("Transaction", "YourController")
Partial view:
#model TransactionModel
#foreach (Transaction transaction in Model.TransactionList) {
// Do something with your transaction here - print the name of it or whatever
}
View Model:
public class TransactionModel {
public IEnumerable<Transaction> TransactionList { get; set; }
}
Controller:
public class YourController
{
public ActionResult Transaction()
{
List<Transaction> transactionList = new List<Transaction>().ToList();
// Your logic here to populate transaction list
TransactionModel model = new TransactionModel();
model.TransactionList = transactionList;
return PartialView("_Transaction", model);
}
}
Just started messing around with MVC and have been trying to accomplish this by looking at this example:
http://forums.asp.net/t/1670552.aspx
I keep getting this error:
Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
Line 9: #using (Html.BeginForm("Index","Home",FormMethod.Post, new{id = "ID"})){
Line 10: #Html.DropDownListFor(m=>m.id, new SelectList(Model.list, "id","name"),"selectThis")
Line 11: }
Here is the code:
Model classes (stupid names, I know):
These are in a console application used only to store models.
namespace Model
{
public class Model
{
public int id { get; set; }
public string name { get; set; }
}
public class List
{
public int id { get; set; }
public List<Model> list = new List<Model>();
}
public class subModel
{
public int id { get; set; }
public int modId { get; set; }
public string name { get; set; }
}
public class subList
{
public List<subModel> list = new List<subModel>();
}
}
Controller: (was populating subList.list and List.list with methods in the class, but decided to try it this way now, was getting the same error)
namespace DropboxTest.Controllers
{
public class HomeController : Controller
{
//
// GET: /Model/
public ActionResult Index()
{
LoadModel();
return View();
}
[ValidateInput(false)]
[AcceptVerbs("POST")]
public ActionResult Index([Bind(Exclude = "id")]Model.Model model)
{
var modId = Request["id"];
LoadModel();
LoadSubCategory(Convert.ToInt32(modId));
return View();
}
public void LoadModel()
{
Model.List listM = new Model.List();
listM.id = 0;
Model.Model mod1 = new Model.Model();
mod1.id = 1;
mod1.name = "me";
Model.Model mod2 = new Model.Model();
mod2.id = 2;
mod2.name = "me";
listM.list.Add(mod1);
listM.list.Add(mod2);
ViewBag.Model = listM;
}
public void LoadSubCategory(int id)
{
Model.subList subList = new Model.subList();
Model.subModel sub1 = new Model.subModel();
Model.subModel sub2 = new Model.subModel();
sub1.id = 1;
sub1.name = "notme";
sub1.modId = 1;
sub2.id = 1;
sub2.name = "notme";
sub2.modId = 1;
subList.list.Add(sub1);
subList.list.Add(sub2);
List<Model.subModel> sel = new List<Model.subModel>();
foreach (var item in subList.list)
{
if (item.modId == id)
{
sel.Add(item);
}
}
ViewBag.SubModel = sel;
}
}
}
View: (I have no idea if anything for subModel dropdown is working as I haven't even gotten to that part yet, but w/e.)
#model Model.List
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
#using (Html.BeginForm("Index","Home",FormMethod.Post, new{id = "ID"})){
#Html.DropDownListFor(m=>m.id, new SelectList(Model.list, "id","name"),"selectThis")
}
#if (ViewBag.SubModel != null)
{
#Html.DropDownList("SubModel",ViewBag.SubModel as SelectList, "select one")
}
It's probably something really stupid but I've been stuck for a couple of hours trying different things.
PS: This is just a test app. After I see how it is done I will be doing one with and SQL DB, using models in ConsoleApplications to retrieve and store data from the DB and display it in views, so any advice on that will be also appreciated.
A big thank you to all that have read up to here and have a nice day.
You never pass a model to the view in the controller, you just store in ViewBag.Model.
Try something as follows:
[ValidateInput(false)]
[AcceptVerbs("POST")]
public ActionResult Index([Bind(Exclude = "id")]Model.Model model)
{
var modId = Request["id"];
//get model
var model = LoadModel();
//pass it to the view
return View(model);
}