I am getting started with MVC and I have the following Model
public class FormControls
{
//Properties of the FormControls object
public string formCName { get; set; }
public string formCType { get; set; }
public string formCCss { get; set; }
public string formCEnabled { get; set; }
public string formCDefaultVal { get; set; }
}
I also created the following control and I am querying a database using linq to select records. Each record will then have to be added to a list.
public ActionResult Index()
{
var DataContext = new EditProfileFormFieldsDataContext();
var controls = from c in DataContext.Controls
select c;
List<FormControls> Fields = new List<FormControls>();
foreach(var fc in controls)
{
//Create Object for Generic List
FormControls epc = new FormControls();
epc.formCName = fc.Control_Name;
epc.formCType = fc.Control_Type;
epc.formCCss = fc.Control_CSS;
epc.formCEnabled = fc.Control_Enabled;
epc.formCDefaultVal = fc.Control_DefaultVal;
//Add Object to FormControls Generic List
Fields.Add(epc);
}
return View("EditProfile");
}
My question is how would I access the list using RAZOR in the view? I am trying to loop through the list I created in the view. I am fairly new to MVC and I think I am over thinking a lot of this :) Thanks!
You can make the model of your view a List. Put this at the top of your view:
#model List<FormControls>
Change the return of your Index() method:
return View("EditProfile", Fields);
Then you can access it from the view by using #Model. For example, to iterate through it:
#foreach (var field in Model)
{
<p>#field.formCName</p>
}
Btw, there is a more direct way to implement the controller.
public ActionResult Index()
{
var DataContext = new EditProfileFormFieldsDataContext();
return View("EditProfile", DataContext.Controls.ToList());
}
or if you rename the view to "index.cshtml", you can do it like this:
public ActionResult Index()
{
var DataContext = new EditProfileFormFieldsDataContext();
return View(DataContext.Controls.ToList());
}
Suppose you do not have the index.cshtml yet, right click the "View(" and select "Add View", in the pop-up wizard, select "list view" and FormControls, there will be an auto-generated view with #model defined and a well done table demoing how to use it.
Related
I am quite new to C# and asp.net mvc and I have been trying to find an answer to my question here and in other foras but have not succeeded. However if this question has been asked and answered before then I apologize and could you please link to that post.
I am trying to create a treeview where I pass a list of ViewModels to my View.
I use code-first approach and have added a migration between my model and the database.
My problem is how to pass a list of objects of the ViewModel to the View?
I can pass a list of objects of the model from the controller but how to pass a list of objects of the ViewModel? Is that possible?
Maybe there is a simple solution to this that I have not found yet and maybe I am doing this all wrong. Anyway I really need some help.
public class MyClass
{
public int Id { get; set; }
public int ParentId { get; set; }
public string Name { get; set; }
}
public class MyClassViewModel
{
public MyClass Parent { get; set; }
public List<MyClass> Children
{
get { return GetChildren(); }
}
public List<MyClass> GetChildren()
{
var listOfChildren = new List<MyClass>().Where(c => c.ParentId ==
Parent.Id).ToList();
return listOfChildren;
}
}
public ActionResult CreateTree()
{
var viewModel = new MyClassViewModel();
//This only returns one instance of an object, how to return a list?
return View("CreateTree", viewModel);
}
It is very simple, you just pass the list of your view model to the view:
[HttpGet()]
public IActionResult CreateTree()
{
List<MyViewModel> viewModelList = MyViewModel.GetList();
return View("CreateTree", viewModelList);
}
On the view, you set the expected type for the model via the #model directive.
#model List<MyViewModel>
#{
//stuff
}
Now you can just iterate through your list of viewmodel.
#foreach (MyViewModel item in Model)
{
//stuff
}
You could create a class, containing a list of your ViewModels
public class ModelWithListOfViewModels
{
public List<ViewModel> ViewModels { get; set; }
}
Add your ViewModels to the list in the controller
public ModelWithListOfViewModels model { get; set; }
[HttpGet()]
public ActionResult FillList()
{
model = new ModelWithListOfViewModels();
//Here you fill the list with the ViewModels you want to pass to the View
model.ViewModels.Add(/** ViewModel here **/);
return View("CreateTree", model);
}
Then simply loop over the list to get your model in the View
#model ModelWithListOfViewModels
#foreach (var vm in Model.ViewModels)
{
//use vm to get access to a ViewModel added in the list
}
I feel this should be simple but haven't found a guide on here that explains the use of dropdownlistfor in MVC.
I have a simple List of Names in a method in a class Users:
public List<string> getUsersFullNames()
{
return (from da in db.Dat_Account
join ra in db.Ref_Account on da.AccountID equals ra.AccountID
select ra.FirstName + " " + ra.Surname).ToList();
}
I want to display each of these names in a dropdownlist so that a name can be selected.
I tried to get this working but have had no success.
My controller:
[Authorize]
public ActionResult ManageUserAccounts()
{
ViewBag.UserList = oUsers.getUsersFullNames();
return View();
}
My Model:
public class ManageUserAccountsViewModel
{
[Display(Name = "Users")]
public List<SelectListItem> UserList { get; set; }
}
My View:
Html.DropDownListFor(model => model.UserList, new SelectList(oUsers.getUsersFullNames(), "Select User"));
I'm quite new to asp.net MVC as I have always used webforms in the past. Has anyone any idea if this is possible or a way to display this?
Thanks,
I would recommend using the model directly in the view, instead of the ViewBag. Update your action to include a model reference:
public ActionResult ManageUserAccounts()
{
var model = new ManageUserAccountsViewModel();
model.UserList = oUsers.getUsersFullNames();
return View(model);
}
Your model should be updated to include a selected User property:
public class ManageUserAccountsViewModel
{
public string User { get; set; }
[Display(Name = "Users")]
public List<string> UserList { get; set; }
}
Your view should be binding to the model:
#model ManageUserAccountsViewModel
#Html.DropDownListFor(m => m.User, new SelectList(Model.UserList), "Select User")
In my Repository class I have this two queries that I want it to appear in just one view:
public ClassXXXX GetxxxoList(string Name)
{
return context.ClassXXXX.Where(v => v.Name == Name).Single();
}
And the second query in Repository class I have:
public IEnumerable<ClassXXXX> List()
{
return context.ClassXXXX.ToList();
}
Then in my view I am doing this:
#model IEnumerable<Namespace.Models.ClassXXXX>
#model Namespace.Models.ClassXXXX
To return the two queries in my view respectively.
But ASP.NET throws exception on using #model twice in just one view.
instead of:
#model IEnumerable<Namespace.Models.ClassXXXX>
#model Namespace.Models.ClassXXXX
You can create an ViewModel class, that contains all your needed data:
public class YourContextViewModel
{
public List<Person> Person { get; set; }
public string UserName{get;set;}
...
}
It's a good idea to create an ViewModel object to populate your views.
I would suggest:
Create a new model that encapsulates both models. Create the model ModelXXXX in the Models namespace
public class ModelXXXX
{
public ModelXXXX(ClassXXXX singleXXXX, List<SingleXXXX> listXXXX)
{
SingleXXXX = singleXXXX;
ListXXXX = listXXXX;
}
public ClassXXXX SingleXXXX { get; set; };
public IList<ClassXXXX> ListXXXX { get; set; }
}
Then in the controller you would have something like:
public virtual ActionResult Index()
{
[...]
string name = "name";
ModelXXXX model = new ModelXXXX(GetxxxoList(name), List());
return View("..Views/Index.cshtml", model)
}
And finally in the view you would have:
#model Namespace.Models.ModelXXXX
[...]
#Model.SingleXXXX
#Model.ListXXXX
The first one (#Model.SingleXXXX) will have the value of #model Namespace.Models.ClassXXXX
And the second one (#Model.SingleXXXX) will have the value of #model IEnumerable
I am working on asp.net MVC 4 application. I have a view model like this:
public class MainViewModel
{
public List<EmailAccount> EmailAccounts { get; set; }
public List<UserContact> Contacts { get; set; }
public List<LinkedInProfile> LinkedInProfiles { get; set; }
public IConfig Config { get; set; }
}
Contacts and LinkedInProfiles have many to many relationship so I have defined junction table:
public class LinkedInAccountConnection
{
[Key]
[Column(Order = 0)]
public Guid LinkedInAccountId { get; set; }
[Key]
[Column(Order = 1)]
public string LinkedInProfileId { get; set; }
}
In view I am using this:
#foreach (var c in Model.Collection.Contacts.OrderByDescending(c => c.LastUpdated).Take(500))
{
#Html.Action("ContactListWidget", "Account", new { contact = c })
}
EF code
var user = dataRepository.GetUserByUsername(username);
Contacts = dataRepository.GetContactsAll(user.Item.UserID).Where(c => c.UserContactEmailAddresses.All(e=> !Cleansing.IsAutomatedEmailAddress(e.EmailAddress))).ToList();
foreach (var c in Contacts)
{
var userContactToLinkedInProfiles = c.UserContactToLinkedInProfiles;
foreach (var uc in userContactToLinkedInProfiles)
{
var profile = uc.LinkedInProfile;
LinkedInProfiles.Add(profile);
}
}
I want to show information in ContactListWidget partial view related to contact as well as related LinkedInProfile. What changes do I need to make to Viewmodel and view ?
Please suggest.
You just need to fill the ViewModel and then bind it to your view.
Controller
[HttpGet]
public ActionResult GetDetails()
{
var mainViewModel = new MainViewModel();
mainViewModel.EmailAccounts=Repository.GetEmailAccounts();
mainViewModel.Contacts=Repository.GetUserAccounts();
mainViewModel.LinkedInProfiles=Repository.GetLinkedInProfiles();
mainViewModel.Config=Repository.GetConfigData();
return PartialView("ContactListWidget", mainViewModel );
}
View
#model YourProject.ViewModels.MainViewModel //set your viewmodel here
After that you can use that ViewModel's list data for bind to your other html elements.
Performance Alert: #foreach (var c in Model.Collection.Contacts.OrderByDescending(c => c.LastUpdated).Take(500))
Please don't bring all the data into view and then filter inside the
view.Just bring the filtered data only (i.e. filter inside the
repository).It'll help to improve the performance of the view.
I have a model like this:
public class ArticleWriter_ViewModel
{
public int MagId { get; set; }
public string MagNo { get; set; }
public string TitleIds { get; set; }
public MultiSelectList Articles { get; set; }
public int[] SelectedArticles { get; set; }
}
i fill the Articles like this:
ArticleWriter_ViewModel viewModel = new ArticleWriter_ViewModel();
Func<IQueryable<NumberTitle>, IOrderedQueryable<NumberTitle>> orderByFunc = null;
Expression<Func<NumberTitle, bool>> filterExpr = null;
if (id > 0)
{
filterExpr = p => p.MagazineId.Equals(id);
}
var wholeTitles = unitOfWork.NumberTitleRepository.Get(filterExpr, orderByFunc, "Magazine,Title").ToList();
then pass it to view. in a few views i show Article in DropDownListFor, but in others want to show it in DisplayFor.how can i iterate through the Articles to show in DisplayFor?
Create a display template in your project's Views\DisplayTemplates directory (create the folder if necessary) called ArticleWriter_ViewModel.cshtml like this (Razor syntax):
#model ArticleWriter_ViewModel
#foreach (NumberTitle article in Model)
{
#Html.DisplayFor(article => article.Title)
}
You can change the property referenced in the DisplayFor expression and/or add an expression to filter the list of articles as required.
If you want to give the display template a different name, use the UIHint annotation on the model name to assign the template name:
[UIHint("MyTemplate")]
public class ArticleWriter_ViewModel
{...}