I have a tree structure of objects (as in picture below). Classes Descendant1 and Descendant2 are to be viewed in the same way as Form class(the root class). I wanted to create a partial view for that, however, I need to have a model in the view as I am using properties from the model(such as Name from the root class)
This is my code of FormView that is to be in the partial view:
<div>
#foreach (var subForm in Model.SubForms)
{
Html.RenderPartial(partialView, subForm);
}
<div>#Model.Name</div>
</div>
I was wondering if it was possible to create a partial view that can have multiple models? Do I create one controller for all the descendant classes together? Otherwise, do you have any ideas how to proceed?
I was wondering if it was possible to create a partial view that can have multiple models?
Yes, make a view model for those 3 classes. Example below is named FormViewModel.
public class FormViewModel{
public class Descendant1 {get;set;}
public class Descendant2 {get;set;}
public class Descendant3 {get;set;}
}
Then in your view you could do;
#foreach (var subForm in Model.SubForms)
{
FormViewModel fmv = new FormViewModel();
// access its class properties
fmv.Descendant1.SubForms.Add(new Form(){ // assign properties });
// pass the view model to the partial view
Html.RenderPartial(partialView, fmv);
}
Related
I am looking to rewrite an existing ASP.NET MVC application to .Net 5 Razor pages and one of the issues I am struggling to resolve is how to create a partial razor page that creates it's own model rather than having the model passed in from the parent page.
In MVC, I would simply add an action to the controller and specify this within the view;
#Html.Action("_SideNavigation", "Shared")
Ultimately, this would call the _SideNavigation action on the share controller, which would then create the model and pass it back to the view.
I am trying to achieve something similar in Razor Pages, I do not want to define the model of the partial within the model of the parent view, such as this;
<partial name="_Partial1" model="Model.PartialModel" />
I have tried creating an empty model within the parent page and assumed this would then call the OnGet() method within the partial itself;
<partial name="_Test" model="new _TestModel()" />
public class _TestModel : PageModel
{
public TopNavigation TopNavigation { get; set; } = new TopNavigation();
public void OnGet()
{
TopNavigation = new TopNavigation { NotificationCount = 1 };
}
}
and then referencing the model in the page;
#Model.TopNavigation.NotificationCount
But it is always null.
Is this behaviour not available in razor pages?
I have a Web app where my controller passes a model to the parent view like so:
public ActionResult Results()
{
//Processing
return View ("ParentView",model);
}
Within my "ParentView" I will do render a partial view like so:
#Html.Partial("_PartialView", anotherModel)
Now I would like to not touch the anotherModel at all.
But what I am trying to do is pass a value to _PartialView from the ParentView.
I know I can pass something like ViewBag.Value="Text" from the Controller to the "ParentView", however is something like that doable from "ParentView" to "_PartialView"?
Basically I want to add a value in the model that is being used by "ParentView", and somehow pass it down to "_PartialView"
You will have to create a View model. you can create it by 3 ways
first way
public class ViewModel
{
public class ParentViewModel {get; set;}
public class ChildViewModel {get; set;}
}
in this case your view
#model ViewModel
...... //html is using #Model.ParentViewModel)
#Html.Partial("_PartialView", #Model.ChildViewModel)
second way
public class ParentViewModel:ChildViewModel
in this case the same model can be used for both
#model ParentViewModel
...... //html is using #Model)
#Html.Partial("_PartialView")
The third way can be used if it is possible to use interface to another model
partial view
#model IAnotherModel
viewmodel
public class ViewModel:IAnotherModel
view is the same as the second way
You can pass properties from your PageView Model to your PartialView like this:
#Html.Partial("_PartialView", #Model.AnotherModel)
You then set the Model of your _PartialView to be of the type of AnotherModel.
I was originally developing a project for WPF, using MVVM, which had the benefit of allowing me to populate a list of views that I wanted available. Each view had a "Next" button that would progress to the next view in the list.
However, now I am trying to do the same in ASP.NET MVC. This is my first time using MVC, but I have an XML file, from which I need to generate this UI. These views, which are chosen from the script, also have components in them that are dynamic -- sometimes ViewA might need 3 "input views" nested in it, sometimes it might need 1.
I was achieving that before with ListBox, ItemsSource, and DataTemplate. So my question is this: how can I dynamically populate which views to display, and (more importantly) how can I dynamically fill those views with x number of control A, and y number of control B?
First off, a high-level overview of the project structure...
YourProjectName
Controllers
ProductController.cs
Models
ProductViewModel.cs
Views
_ProductPartial.cshtml
ListProducts.cshtml
ProductViewModel.cs
public class ProductViewModel
{
public string Name { get; set; }
public string Description { get; set; }
}
ProductController.cs
public class ProductController : Controller
{
public ActionResult Index()
{
// Create your model (this could be anything...)
var model = new List<ProductViewModel>
{
new ProductViewModel { Name = "Apple", Description = "A red apple" },
new ProductViewModel { Name = "Orange", Description = "An orange orange" }
};
// Return the main view and your model
return View("ListProducts", model);
}
}
_ProductPartial.cshtml
#model YourProjectName.Models.ProductViewModel
<h1>#Model.Name</h1>
<p>#Model.Description</p>
ListProducts.cshtml
#model System.Collections.Generic.List<YourProjectname.Models.ProductViewModel>
#foreach (var product in Model)
{
Html.Partial("_ProductPartial", product)
}
Summary
Now if you request that controller action (localhost/Product/Index or whatever it ends up being for you), the controller will create the model, render the parent view, and the parent view will render as many of the product partial views as necessary depending on the product model collection we defined in the controller. Views and partial views don't require models, but I imagine you will be using a model class of some sort to help you determine what/where/how many partial views to render in your parent views. This is about as basic as it gets but it should get you started in using partial views.
I`m writing an ASP.Net MVC application with Razor.
Assume that I have HomeController and some views for it.
1. View1
2. View2
3. View3
All this views use common _MyLayout file, which should look like this:
When the links are clicked, the views are rendered by RenderBody() method.
Each view is strongly typed: it requires its own Model.
Everything was fine untill I decided to add special Model to _MyLayout view.
But now I get error
The model item passed into the dictionary is of type 'TestUp.Models.UserModels.PendingTestsModel', but this dictionary requires a model item of type 'TestUp.Models.UserModels.UserNavigationModel'.
Here is controllers code
public ActionResult View1()
{
ModelForView1 model = new ModelForView1();
return View(model);
}
public ActionResult View2()
{
ModelForView2 model = new ModelForView2();
return View(model);
}
public ActionResult View3()
{
ModelForView3 model = new ModelForView3();
return View(model);
}
Shortly speaking if layout view doesn`t require model, specific method for View is invoked,
model is created, passed to view and everything is ok. But now layout requires model as well so it crashes.
The question is: how do I elegantly resolve this problem?
Desired workflow is:
View1 is requested
Method in controller for this view is called, model instance created, passed to view
Some method for layout is called, model for layout created, passed to layout.
Is it possible to make things work somehow like this?
Thanks.
Create a base model type and have your specific view models extend it. This base model can have a property of type UserNavigationModel. The layout can accept the base model and use the new property as the model for the navigation menu.
public abstract class ModelBase
{
public UserNavigationModel NavigationModel { get; set; }
}
public class ModelForView1 : ModelBase { ... }
public class ModelForView2 : ModelBase { ... }
public class ModelForView3 : ModelBase { ... }
View1:
#model ModelForView1
Layout:
#model ModelBase
#* use Model.NavigationModel for nav bar *#
I have a view model as such:
public class MyViewModel
{
public MyObject myObject{ get; set; }
public List<MyList> myList{ get; set; }
}
I have a view with a form strongly typed to MyViewModel
This view allows you to enter values for the properties of MyObject, as well as create a list of MyList objects. The List part works fine although I thought that would be the more difficult of the two.
Assuming MyObject has a property Description I create a textbox to enter the value as such:
#Html.EditorFor(x => x.myObject.Description);
The text box renders with an id of MyObject_Description...The problem is when I post this to my controller action, MyObject does not get bound at all(althought the list items do as they recieve the appropriate IDs of "MyViewModel_MyList[guid].myListValue")
What am I doing wrong here??
EDIT: more info
The first line of the view is:
#model MyApp.ViewModels.MyViewModel
And the Action method:
[HttpPost]
public ActionResult Create(MyViewModel myViewModel)
{
}
I am passing a new MyViewModel into the partial view to begin...
public ActionResult Create()
{
MyViewModel model = new MyViewModel();
return PartialView(model);
}
EDIT 2
Ok When I render my partial view that contains the forms I call :
#{Html.RenderAction("Create", "MyController");}
this is called from within a View of type #model IEnumerable<MyApp.Models.MyObject>
(this view displays a list of currently existing MyOjects, and at the bottom the partial is rendered to allow the user to add another MyObject to the DB)
If you are not already doing so, try creating a editor template (e.g., Views->Shared->EditorTemplates) called MyObject.cshtml. Move your partial view content to this view and then call
#Html.Editor("myObject").
from your parent partial view.
Change your ViewModel to have the Description directly
public class MyViewModel
{
public string Description { get; set; }
public List<MyList> myList{ get; set; }
}
then bind accordingly
#Html.EditorFor(x => x.Description);
I would expect the top line of your view to look something like this:
<%# Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage<MyViewModel>" %>
This tells the view that the model it is supplied is of type MyViewModel (a la <T> style).
I don't think the out of the box model binding knows how to bind to complex objects. You're probably going to have to write up some sort of custom model binder.
I'm afraid it's not something I've done since MVC1 so I'm a bit hesitant to give you any sample code because the mechanism may well have changed completely since then. A quick google did turn up this article http://www.learnxpress.com/asp-net-mvc-hosting-6-tips-for-asp-net-mvc-model-binding-2.html and this article http://bradwilson.typepad.com/blog/2010/10/service-location-pt9-model-binders.html.
Edit: I've just seen this answer which might help Retrieving data from view, should I use model binder?