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)
Related
How can we use one div on multiple places in View in MVC.
Suppose I have declared one div and just call that div in multiple frames in Views razor in MVC.
Consider using of partial view for you requirement. So the div you want to show many place will be part of partial view with its own ViewDataDictionary.
Partial Views
A partial view enables you to define a view that will be rendered inside a parent view. Partial views are implemented as ASP.NET user controls (.ascx).
When a partial view is instantiated, it gets its own copy of the ViewDataDictionary object that is available to the parent view.
The partial view therefore has access to the data of the parent view. However, if the partial view updates the data, those updates affect only the partial view's ViewData object. The parent view's data is not changed.
Check this for more information
Or
Another way is using jQuery to get div and inject where it is required.
Create a partial view in Shared folder. Put your common HTML there in that partial view. Use #Html.Partial("_SharedPartialViewName") wherever you want that common html.
You can also learn implementation from this URL
http://www.codeproject.com/Tips/617361/Partial-View-in-ASP-NET-MVC
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).
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.
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()
}
Using ASP.net MVC3 with C#
I want to create a partial view that uses a single database record so I have the View down fine but what controller would I create to actually create the LINQ query or do I need to do it in the View file?
The partial will display a random ad and be on every page on the site.
As M.Babcock says, you really should keep the logic out of the View and into the Controller (or Model if appropriate).
I would pass the resulted data to the View either through a Model, or it little data then just pass it through the ViewBag (or ViewData).