When do you use Html.Action over Html.Partial - c#

I still don't get the primary purpose of Html.Action in asp.net mvc. I have been using Html.Partial every time I need to load up a partial view or wanted to split up some code in a view to clean it up.
Where does Html.Action fit into all of this (e.g. where would you want to use Html.Action and not use Html.Partial)?
Edit
The answers seem to be use Html.Action for dynamic data. I don't get this as you can use Partial Views for Dynamic data as well.
For instance if a user on my site edits a row. A ajax call is made to a method and I go grab that row from the db. I then return a parital view of a form that has all the data on it ready for editing. If an error occurs then I return a json result with the error method and my javascript consumes it and alerts the user.
If all is good then the rendered html is put into a jquery dialog and displayed to the user.
Is it because you can use the "ChildActionOnlyAttribute" that makes people use Action instead?

Ankur has the right idea but I find you can really simplify the concept down further.
For me it comes down to What versus How
If you know what you want to render but not how it's likely you'll use a partial to let it determine how to render the information.
For example, maybe your view model is for an invoice. Your invoice view model probably already has all the information you need about the invoice itself, including an enumerable of the line items on the invoice perhaps. A partial might be a good choice for the line items so that it's self contained. You already have the line items details (the what), but a partial will handle how it gets rendered (the how)
On the flip side, maybe your invoice view model has a customer ID on it but no actual customer details. Here you don't have the what, so you'd pass in the customer ID to an Action and it'll get what data it needs and pass it off to the view to render how it seems fit.
So in summary if you already have all the data you want to work with, just stick with a Partial, but if you are missing information that you need to obtain, Action would be better.
Where this get really fuzzy around the edges is when a Partial view includes the ability to retrieve it's own data via Ajax (or other technologies). In which case you might be able to get away with making that Customer details portion in my example, a Partial, and have it retrieve the data it needs Using Ajax after the client get's the response. But that's more up to you if that sort of thing even makes sense for your implementation.
Addendum:
It's worth noting that if you decide to try out ASP.NET MVC Core, ChildActions are no longer available. In which case your choices will be limited to partial views, ajax, or the newly introduced feature of Components. The last of which is similar to ChildActions, but slightly different in how they are implemented.

Perhaps an example will make this clearer.
Let's say you have a menu which appears on every page, so you put it in your layout. The menu will never change - there is just some basic navigation links, Home, About, Contact us etc, so you just use a normal partial view. This will work fine - as the content is static - you don't need to go to a database to get the data. You can just use #Html.Partial("Menu");.
Later you decide you need to change the menu so that it gets all the links from a database. You update your partial view to have a model that is a List<string> - one for each link.
Now, if you still want to just use a Partial View, every action would need to query the database to get the list of links, and every Model for every View would need to have a List<string> property for the links, so that it could pass this to the Menu Partial View. This would be a bad idea.
Instead, you would make a new Child Action GetMenuLinks() - this would query the database to get the links as a List<string>, and pass this to the Partial View. This puts the Child Action in charge of getting it's own data. This means you only need to have this query in one place, the 'About Us' action for example doesn't need to worry about getting the list of links for the menu.

Partial views
Use for sharing subsections of view markup between views. Partial views can
contain inline code, HTML helper methods, and references to other partial
views. Partial views do not invoke an action method, so they cannot be used
to perform business logic.
Child actions
Use for creating reusable UI controls or widgets that need to contain business
logic. When you use a child action, it invokes an action method, renders a
view, and injects the result into the response stream.

I use Html.Action() to load dynaimc content that I do not wish to contain in the view model (for instance, user information in a sidebar). It is very useful for keeping input and output view models identical.
Note that I always use Html.Action() in conjunction with applying the ChildActionOnlyAttribute to the controller method that I am calling so that the HTML fragment is not accessible via the URL.

Use Html.Partial when you require a subset of your view model to render the section in question--usually it is something that has to do with what you're working on. If could be a subsection of a form, a relevant content piece related to the main view etc. A partial receives its model information from the parent view.
Otherwise use Html.Action to render content that is independent of your main view, such as a navigation piece, an aside, or other distractions. Html.Action uses its own model provided by its controller, rather than provided by the parent view.

This question is answered (and elected for 149 times!) here:
Html.Partial vs Html.RenderPartial & Html.Action vs Html.RenderAction
Update
Sorry, meant to send you these postings rather
MVC Html.Partial or Html.Action\
#Html.Partial() Vs #Html.Action() - MVC Razor
Hope this helps.

Related

How to avoid code duplication if multiple pages look almost the same?

I have a couple of pages for e.g. Product that look almost the same. I have Product/Add and Product/Modify/{id} pages where one is an empty form to add new Product and the second one comes already filled with data for a current product and can be updated with additional information. Because Razor Pages separates this into Add and Modify PageModels, I have a different cshtml view for each of them.
I tried to use ViewComponents to build reusable parts of these views, but they are only good if all you want to do is display data. Because ViewComponents don't support Binding all I have left is somehow send ajax requests and append the data to submit, which even sounds wrong and probably isn't the right approach.
Is there any other way of creating these pages without duplication?
You can create one page for create and edit by sending a new object of the Product model (with no data in id attribute) and a created object (with data in id attribute) in case of editing. And in the view you can do rendering based on the sent object (whether it is new or not).

ASP.NET MVC razor view, post to a different model from the original model binding?

Well I have a group controller and view in the project, in which the model binding is GroupViewModel. But the group page is complex, and users will be able to make discussion topics. On this group view page, I have forms that allow users to post topics/replies. The model used for these forms can be TopicViewModel or ReplyViewModel, but the original model binding is only for GroupViewModel. It is declared at the beginning of the cshtml page:
#model MyProject.ViewModels.GroupBrowseViewModel
So I wonder, is it possible to have forms bind to different view model from the one declared at the top? If so, how to achieve this?
Model binding really has nothing to do with the model used in your razor view. At least not technically.
The first thing you have to understand is that there is no magic here. This is straight HTTP posted values, and if you don't understand how HTTP posting works, I suggest you read up on it. It's just a series of name/value pairs.
When you post, the routing framework looks at the selected action method, and the parameters that method takes, then it creates new instances of those parameters, and tries to match them up with similarly named values from the posted values.
So, in other words, there is no direct connection here between the model you use on the page, and the model used in the posted controller action. It's all based on naming convention. This naming convention is "helped" by the model you declare on the page, and the Html helpers create form fields with names that match up to model entries so that the model binder can figure these out more easily.
So, what this means is that in order to post to a different action, with a different model, all you need are fields in your form that have the names that the new model expects.
This can be done in a number of ways, from defining those fields manually, to using Partial view in which you pass an instance of the model you intend to post to as the model parameter.
You can use 2 partial views in the same view, and switch from the controller which one to show.
Or you can make a new ViewModel and this view model will contain references to both of your views, and in the view html based on your logic your can switch reading from any child ViewModel.

asp MVC - Add a model representing user to a Partial displayed via layout

my layout page includes a header partial which changes depending on the user / company that is logged in, so it makes sense to make teh partial stronglyTyped.
I know how to call a partial and add in the model, but at what point (and where) do I add the header model? Do I need to add it on each page that uses the layout (which seems excessive), or is there some way I can add the header model without writing code on each page to add it to the viewbag and pass it through? (I suspect that if it is viable, it will have to pass through a controller somewhere. In which case, can I use an existing controller, or do I need a special 'partial header' controller?)
Implement an action that will
Create the model
Return a ViewResult rendering your Partial with the given model
Then do an Html.RenderAction("ActionName", "ControllerName") for that action in your Layout.

ASP.Net MVC Dashboard View. Where to perform aggregations

I have read a few other stackoverflow posts regarding dashboard setup in a view, but I am still struggling a bit. I have one master query that is returning a detailed view of my data, since I only want to hit the database once. So I have a Controller Action called GetEmployeeInfo() that returns a IEnumerable<EmployeeBase> model class. I want to be able to take this class and break it apart into different divs in a view. For example, I would have three divs on top of the View aggregating row count by employee category and 2 divs on the botton that shows the detailed table. Can this be accomplished strictly through one view by setting up conditional/aggregate statements all over or do I use partial views or something else. Or is using one controller action a problem?
Thank you.
I used the answer from Pat Burke (see comments under my question. I posted it below as well). I created one base class and one partial view for my employee categories that has all the properties I needed. I did the same for my detail portion. Then I created the DashboardViewModel which had 3 IEnumerable<EmployeeCategoryBase> properties as well as 2 IEnumerable<EmployeeDetailInfo> properties. Then I created a strongly typed DashboardViewModel view with 5 divs that used #{Html.RenderPartial(ViewName,model.property);}
Another alternative is to have your Dashboard view strongly typed to a View Model like "DashboardViewModel" which is composed of different collections which correspond to the data needed for each sub-part. This would also put the aggregation logic to the server-side rather than on the client in JS. You could even have partial views included, each of which corresponds to a sub-part and a collection of data in your View Model. It's good practice to have your view model directly correlate to the data needed by your view

c# mvc3 controls within a control

MVC3 has entity framework that makes create, delete, edit methods within a controller.
I am making a control panel that allows to edit multiple tables. How do I incorporate a controller(the entity framework) within another controller(the control panel)?
Any clever work around?
For example http://example.com/Control_panel/Another_Controller
Ok for this, there are two ways lets say you have a default controlpanel action in your ControlPanel controller, you can have a variable that comes in and says what you are trying to control, lets call it controlID, you can then use RedirectToAction to go to that action instead, like this
public ActionResult controlPanel(object controlId){
if(controlId.equals(something)){
RedirectToAction(SomeAction, SomeController);
}
}
The other one is you can use the same idea and call the controller action directly. Like this:
var result= new SomeController().SomeAction();
Although this is breaking MVC design as you should have it be a more universal function rather than a controller, as controllers are designed to control datamovement between Models and Views. If I see some of the code I can give you a more specific response.
If you want to edit data from multiple tables from the same page, you accomplish this by use of view models. The data you present to the user in your view does not need to have a 1:1 relationship with a table or a model for that matter.
A view model will allow you to pick data from various sources, present the same to the user for viewing or editing and if the user saves the same, you can pick the view model from your controller action and use that data to update one or more tables.

Categories