Pass a viewModel to the layout - c#

I have this viewmodel that has some properties and stuff that i would like to apply
to the layoutpage:
public class BasicViewModel
{
public Page Page { get; set; }
public List<Settings> Settings { get; set; }
}
From other threads here have i understood that this is possible but i dont really understand how.
From what I understand I somehow need to modify a controller and this is where I get confused. How do I know what controller that has to be modified and how?
Any help appreciated.

In controller, Prepare an action like
public ActionResult BasicViewModelDemo
{
BasicViewModel obj=new BasicViewModel()
// assign properties
return View(obj);
}
and view write some jquery. (Here i am using knockout to make view model)
<script>
var model='#Html.Raw(Json.Encode(Model))';
var viewmodel = ko.mapping.fromJSON(model);
</script>

Here goes my solution -
Lets say you have a model of this way -
public class BasicViewModel
{
public Page Page { get; set; }
public List<Settings> Settings { get; set; }
}
public class Page
{
public string PageName { get; set; }
}
public class Settings
{
public string SettingName { get; set; }
}
Then in the controller you should initiate the model in this way -
public class HomeController : Controller
{
BasicViewModel model;
public HomeController()
{
model = new BasicViewModel();
model.Page = new Page();
model.Settings = new List<Settings>();
}
public ActionResult Index()
{
model.Page.PageName = "My Page";
ViewBag.LayoutModel = model;
return View();
}
}
So basically we used Constructor to initiate the model and then we assign proper values in the controller action.
Then in the Layout, we can use the Model property as shown below -
<div> #ViewBag.LayoutModel.Page.PageName </div>

Related

How to retrieve an object property inside a view

I have an index method in a controller which looks like this :
public ActionResult Index()
{
var object = _ObjectService.GetAll();
return View(object);
}
Which give me a list of object with those properties :
public class Object : EntityWithNameAndId
{
public virtual Site Site { get; set; }
public virtual List<User> Users { get; set; }
public virtual List<Planning> Plannings { get; set; }
public virtual Guid IdPilote { get; set; }
}
Now in my Index() view, i want to get the User who's related to the IdPilote id and display its name.
I tried something like this, thanks to this topic ASP.Net MVC: Calling a method from a view :
#model List<MyClass.Models.Promotion>
#foreach (var item in Model)
{
<td>#item.Site.Name</td>
#{
var id = item.IdPilote;
//Here Interface and Service are folders
var user = MyDAL.Interface.Service.IUserService.Get(id);
}
<td>
//This is where i try to display my User name,
//that i get dynamically using the idPilote for each User in list
</td>
}
But Get(id) is not recognize as a valid method..
public interface IUserService : IDisposable
{
User Get(Guid id);
}
public class UserService : IUserService
{
private MyContext context;
public UserService(MyContext context)
{
this.context = context;
}
public User Get(Guid id)
{
return context.User.Where(w => w.Id == id).SingleOrDefault();
}
}
So what's the best way to get my User object inside my view, since i only get an Id ?
Should i create a new list, using the first one, in my Index method (where i can call IUserInterface.Get()) or is there a better way to do it ?
Make it worked by creating a new list and a specific ViewModel, as suggested :
public class IndexObjectViewModel : EntityWithNameAndId
{
public virtual Site Site { get; set; }
public virtual List<User> Users { get; set; }
public virtual List<Planning> Plannings { get; set; }
//To store User instead of its Id
public virtual User Pilote { get; set; }
}
Now Index() looks like this :
public ActionResult Index()
{
var objects = _IObjectService.GetAll();
ViewBag.NotPromoExist = false;
var indexObj = new List<IndexObjectViewModel>();
foreach (var p in objects)
{
var indexModel = new IndexObjectViewModel();
indexModel.Id = p.Id;
indexModel.Name = p.Name;
indexModel.Site = p.Site;
indexModel.Users = p.Users;
indexModel.Plannings = p.Plannings;
indexModel.Pilote = _IUserService.Get(p.IdPilote);
indexObj.Add(indexModel);
}
return View(indexObj);
}
Everything is done in the controller now. Not sure if it's the best way to do it though..

How to pass a list of ViewModels to a View?

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
}

Form submission in partial views in MVC

I am developing a simple mvc application . The code is as follows:
Model .cs:
public class CustomModel
{
public IEnumerable<lang> lstlang { get; set; }
public IEnumerable<org> lstOrg { get; set; }
}
public class lang
{
public int langid { get; set; }
public string langName { get; set; }
}
public class org
{
public int orgId { get ;set;}
public string orgName { get; set; }
}
Controller.cs
public Action Index()
{
// Get data from database and fill the model
var model = new CustomModel();
return View(model);
}
public Action Partial()
{
// Get data from database and fill the model
var model = new CustomModel();
return PartialView(model);
}
[HttpPost]
public Action Partial(FormCollection frm, CustomModel model)
{
// Get data from database and fill the model
var model = new CustomModel();
return PartialView(model);
}
Index.cshtml
#model CustomModel
#Html.TextboxFor(x => x.lang.FirstOrDefault().id);
<input type="button" id="btn" />
#Html.RenderPartial("Partial", model)
Partial.cshtml
#model CustomModel
#Html.TextboxFor(x => x.lang.FirstOrDefault().id);
<input type="submit" id="submit" />
The thing is, when I click the submit button in the Partial.cshtml page, and examine the model in httppost method in public Action Partial(FormCollection frm, CustomModel model), the model contains null for both lists lstlang and lstOrg, but the formcollection[0] will give the selected textbox value.
What am I missing, or is this the right way of using partial views?
Don't use FirstOrDefault(). If you want to post something back to the front end with collections, you'll need to use indexing.
Public class CustomModel
{
public ICollection<lang> lstlang { get; set; }
public ICollection<org> lstOrg { get; set; }
}
#HTML.textboxfor(x=>x.lang[0].id);

#Html.Action causing 'No parameterless constructor defined for this object' exception

I'm getting a 'No parameterless constructor defined for this object' exception and the culprit is a #Html.Action inside my view. I just figure out why this is happening. Any help would be greatly appreciated.
My Controller
public class AsyncController : Controller
{
public ActionResult Jobs()
{
var jobViewModel = new JobViewModel("Junior Accountant", Sector.Accountancy, DateTime.Now, "Enterprise Banking");
return View(jobViewModel);
}
public ActionResult MoreJobs(JobViewModel model)
{
var viewModel = new MiniJobsView(model);
return PartialView("_Rand.cshtml", viewModel);
}
}
Jobs View
#model SampleAsyncPartialViews.ViewModels.JobViewModel
#{
ViewBag.Title = "Jobs";
}
<h2>#Model.Title</h2>
<h3>#Model.CompanyName</h3>
<h3>#Model.Sector</h3>
<h3>#Model.StartDate</h3>
#Html.Action("MoreJobs", Model);
_Rand Partial View
#model SampleAsyncPartialViews.ViewModels.MiniJobsView
<div>
<h1>#Model.Title</h1>
</div>
JobViewModel
namespace SampleAsyncPartialViews.ViewModels
{
public class JobViewModel
{
public JobViewModel(string title, Sector sector, DateTime startDate, string companyName)
{
Title = title;
Sector = sector;
StartDate = startDate;
CompanyName = companyName;
}
public string Title { get; set; }
public Sector Sector { get; set; }
public DateTime StartDate { get; set; }
public string CompanyName { get; set; }
}
public enum Sector
{
Accountancy,
IT,
Marketing,
Sales
}
}
MiniJobsView
namespace SampleAsyncPartialViews.ViewModels
{
public class MiniJobsView
{
public MiniJobsView(JobViewModel model)
{
Title = model.Title;
StartDate = model.StartDate;
}
public string Title { get; set; }
public DateTime StartDate { get; set; }
}
}
I understand the exception, I just don't understand why #Html.Action would have to generate a new instance of JobViewModel, when i'm already passing the model.
I think you need to render your partial view into your view. There is no overload for Html.Action that take your model as a parameter.
The solution for doing what you want is to use Html.Partial methods like this :
#Html.Partial("MoreJobs", new MiniJobsView(Model))
Actually you can't bind model using #Html.Action("MoreJobs", Model); in your controller.
Try #Html.Partial("MoreJobs", new MiniJobsView(Model)) what CodeNotFound Said.
The Html.Action method wants the data like a object with route values.
// Correct:
#Html.Action("MoreJobs", new { model = Model});
// Wrong:
#Html.Action("MoreJobs", Model);

How to pass generic parameter to partial view [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Generic partial view: how to set a generic class as model?
I am trying to build common functionality using generic types but got stuck with below scenario.
View Model
public class DeleteForm<T>
{
public LogInfo Ticket { get; set; }
public string Id { get; set; }
public DeleteForm() {
Ticket = new LogInfo();
}
public DeleteForm(T viewModel) : this() {
ViewModel = viewModel;
}
public T ViewModel { get; set; }
}
Controller
public ActionResult Index(string name)
{
return View("index", new DeleteForm<List<Users>>(new List<Users>());
}
List Screen
#model DeleteForm<List<Users>>
//gridview displays list of users
#Html.Partial("revisionwindow", Model)
Partial View
#model DeleteForm<T> <---Its not working
#Html.EditorFor(o=>o.Ticket)
#Html.EditorFor(o=>o.Id)
use dynamic model instead.
your partial view can look something like this :
#model dynamic
#{
var myModel = (DeleteForm<List<Users>>) Model;
}
#Html.EditorFor(o=>myModel.Ticket)
#Html.EditorFor(o=>myModel.Id)
hope this help.
If you pass a model to view, it has to be strongly-typed (particular type).
So SomeClass<T> type won't work. Instead of generic type a base class could fill
your requirements. What I mean is:
View Model
public abstract class Form
{
public Form()
{
Ticket = new LogInfo();
}
public LogInfo Ticket {get; set;}
public int Id {get; set;}
}
public class DeleteUsersForm: Form
{
public DeleteUsersForm(IEnumerable<Users> users):base()
{
this.ViewModel = users;
}
public IEnumerable<Users> ViewModel {get; set;}
}
Controller
public ActionResult Index(string name)
{
return View(new DeleteUsersForm(new List<Users>()));
}
List Screen
#model DeleteUsersForm
//displays list
#Html.Partial("revisionwindow", Model)
Partial View
#model Form
#Html.EditorFor(o=>o.Ticket)
#Html.EditorFor(o=>o.Id)

Categories