Passing a model to a partial view - c#

I have an _Address partial view. This partial view contains all of the address fields that match the Address Model. At the top of this view I set the model like this:
#model Data.Address
In my CustomerInfo view I try the following to render the Address fields as part of my form:
#Html.Partial("~/Views/Shared/Partial/_Address.cshtml")
The error I am getting is:
The model item passed into the dictionary is of type 'Data.Customer',
but this dictionary requires a model item of type 'Data.Address'.
I am assuming I am getting this error because the model declared in my CustomerInfo view is of type Data.Customer and it is automatically trying to pass it to my _Address view which has a model of type Data.Address in it.
What is the proper way to make this flow properly? I noticed there is also an #Html.RenderPartial("ViewName", model) helper but have no idea how to pass it Data.Address since the primary model in my CustomerInfo view is Data.Customer.

I guess that your primary model Data.Customer already has one or more properties of type Data.Address that you would like to display. So you would use the #Html.Partial helper and pass the value of this property like that:
#Html.Partial("ViewName", Model.SomeAddressProperty)
As an alternative to using the Html.Partial helper you could use Editor/Display templates. They work by convention. So rename your _Address.cshtml partial to ~/Views/Shared/EditorTemplates/Address.cshtml and then inside your main view use:
#Html.EditorFor(x => x.SomeAddressProperty)
or if the partial doesn't contain input fields or forms you could use a display template: ~/Views/Shared/DisplayTemplates/Address.cshtml and then:
#Html.DisplayFor(x => x.SomeAddressProperty)
The convention here is the name and location of the template. Since the type of the SomeAddressProperty is Address, ASP.NET MVC will look for the corresponding Address.cshtml template.
If your main view model doesn't have an address property you should simply go ahead and add one or more such properties and populate them in the controller action rendering the main view. Then you can call the partial for each of those properties.

First of all, don't pass Data.Customer to your main view, but only 'Data'. This is more flexible, all your have to do then is fix the references inside the main view, so instead of #Model.FirstName, you use #Model.Customer.FirstName. This way, you can call your partial view with a more explicit #Html.Partial("~/Views/Shared/Partial/_Address.cshtml", #Model.Address).

Related

MVC PartialView in multiple Views with different models

This may be a silly question and is more of a question about how to do something rather than an actual coding issue.
I want to have a partial view which contains a search form and search results and uses model Suppliers.
This partial view would then be rendered in multiple views that use different models.
Is it possible for me to this or do I have to create the search form within each view or create a partial view for each view so that the view and partial view use the same model?
If I use the Suppliers model for the partial view and another model for the view I just get error:
The model item passed into the dictionary is of type 'x', but this dictionary requires a model item of type 'y'.
You can definitely do that with different implementations.
First Option:
You can drop the Model from the "Shared" view that you have and have it work with a ViewBag or ViewData that you pass to the view from your controllers. Obviously you will need to populate this view bag or view data within all the controller actions that will return this shared partial view.
Second Options:
Instead of having Suppliers as the view model of the shared view, you can have another property in the view model "Supplier" that you can use, but when you are rendering the shared view you need to specify the property and pass it as the Model to the shared view like:
Html.RenderPartial("MySharedView", Model.SharedViewModel);
Now you have to do the same thing for all other views that render this shared and basically have this "SharedViewModel" as a property in those view models and pass the Model.SharedViewModel to the shared view.
For sure there are other options too that you can find out once you get more comfortable with Shared Views in MVC.
Try using a partial action instead of partial view.
http://pratapreddypilaka.blogspot.co.uk/2011/11/htmlpartial-vs-htmlaction-mvc-razor.html?m=1
First of all you need to create partial view under shared folder with name _SearchBox.schtml. It can be something like this:
#model IEnumerable<your.project.Supplies>
<div id="search-box">
#using (Html.BeginForm("MakeSearch", "SearchController", FormMethod.Get))
{
<input type="search" name="search" />
<input type="submit" value="GO" />
}
</div>
Then you can call it from any view by calling
#{Html.RenderPartial("_SearchBox", listOfSupplies);}
Otherwise you can create action in controller if wish to get supplies from DB and you don't have a list of supplies on your parent view.
[ChildActionOnlyAttribute]
public ActionResult _SearchBox()
{
var supplies= _service.GetSupplies();
PartialView(supplies);
}
and call it from view:
#{ Html.RenderAction("_SearchBox", "Search"); }
So each partial view is going to be directly tied to a model. If you're looking to have different information from different models in the same view, your best bet would be the concept of a modal. In terms of having search and search result partial views rendering together on the same view. Make sure you are accounting for where you are saying how you are using the model (i.e. #model [model name here] or #model IEnumerable<[model name here]> IF you are enumerating over your results like what would be likely for displaying a list of search results from a database; try using the a separate viewmodel. This will allow you to change how you are interacting with specific tables / columns individually (i.e. if you are enumerating through them)

ASP.NET MVC. How render a Partial with no model (like create view)

I would like to render partial like this:
#Html.Partial("_MyPartial")
However my partial does need a typed object, for instance: MyPartial.cshtml :
#model MyApplication.Models.MyClass
(...)
But I would like to render it on my view WITHOUT a initialized model, like a "Create" view.
Create views is bound to a model, but is initialized empty.
What I already tried:
#Html.Partial("_MyPartial") The main view model is passed to the partial and it throws an incompatible types error.
#Html.Partial("_MyPartial", null) throws same error.
#Html.Partial("_MyPartial", new MyClass()) initializes view with default values. I don't want pre initialized view.
In a "Create" view, no model is passed to the view, BUT the view is bound to a model. I would like to render this partial in a "create" view. It must no be bound to a initialized model instance. It must be initialized empty.
In the fact, this is not possible, cause partial gets the model from the main view, if there is no one from itself.
In this case you must initialize the call partial and pass not only the model as null but the entire data from the context must be cleaned.
You have already write code to accept model type in view:
#model MyApplication.Models.MyClass
So it is compulsory that you have to pass model in view.
If you don't wants to use model then remove your code which accept model
Try to use html.renderaction instead of doing partial like this and dont declare any model for the view, if it really dont use one in the first place?
Oh yeah return a partialview in the action return and dont forget the curly braces after # sign, it matters
When you want to return a partialview with no model. Use this.
#{ Html.RenderPartial("Your partial view") }

MVC 4 reuse views and view models best practice

I have 3 screens that share a section(with model data in it(#Html.TextBoxFor)). What is the best way to implement this screens?
What I tried:
1) Partial view for the common section(_ClientData). 3 views for the different screens. 3 view models that have common property(ClientData), that is the view model of the partial.
Problem: If I pass the model to the partial as #{Html.RenderPartial("_ClientData", Model.ClientData);} the data from the partial is not submited to the model.
If I pass the model to the partial as #{Html.RenderPartial("_ClientData", Model);} and reference the properties with a fill name the data is submited, but I can't pass models with different types to the partial view.
2) Use one big View model with all the data required by the 3 screens, one view and show/hide some elements depending on some flag.
Problem: I can't use ValidationAttributes(for example if one field is required in screen 1, but it's not shown in screen 2 and its value is null, the validation will fire). I can use some manual validation in the controller but the whole thing with the all in one view and viewmodel sounds very bad.
Partials are usually not the best choice in case you want to place them inside one form and submit together. In such scenario it is better to take advantage of EditorTemplates which will solve your problem.
Firstly you would have to drag your partials to the folder ~/Shared/EditorTemplates/ and rename them to match the model name.
Then you can call them in your view like this:
Html.EditorFor(model => model.ClientData)
Thanks to this your HTML code (the name attributes to be precise) will be generated in such a way that your default model binder will be able to bind this part of your view as well.

Template for ViewBag

I want to create a template to format some ViewBags.
Up to now, I had only the case of property of of a class, which I could easily modify with
[UIHint("MYTemplate")]
public virtual float Foo { get; set; }
Every selction of the property will consider "MyTemplate" and formate the output correctly.
How am I able to transfer this 'structure' to a ViewBag, which is defined in a certain controller?
Actuall, you can't. The contents of the ViewBag is Dynamically Resolved at Runtime. As opposed to Model properties. You can only use Templates for properties of a Model.
The only other option would be to add it to your model. The reason behind this is that, Your model (or View Model to be precise) ought to have everything that your view needs to display data. The ViewBag was intended to add some flexibility for data that doesn't necessarily need to be in your model like the contents of a DropDownList. Therefore, if you need to display content from the ViewBag like properties in your page, then you should consider promoting that property to your model.
Alternatively, you could use Partial Views. like so #Html.Partial("_MyTemplate",ViewBag.Data)

Update the views, after updating a model

I have created a model with Name, Email, Phone no properties and also created views for create, edit, delete and index. All these are working fine.
Now I have added a property in model like Address. Now I want that, is there any method so that, after adding the property in model, the newly added property automatic add in all the respective views.
Can we do this?
There is a way but only applicable if the view is generated by using HTML helper classes. The view should be strongly typed.
#Html.EditorForModel()
This HTML helper will automatically update and genatrate required input fields but with this you might have limited flexibility.
Other way can be creating your own class that renders html page.
Use as below in your view. View should be strongly typed of the model you want to use:
#using(html.BeginForm()){
#Html.EditorForModel()
}

Categories

Resources