Action called twice - asp.net

I have a #Html.Action() in my layout, and putting a breakpoint in the controller action behind this shows it is being called twice (one seems to be as part of the overall controller action returning my main View and the second seems to be on the #Renderbody() call).
This results in my partial view being returned from the action (depending on the user role) being shown twice, once in the right place in the layout (where the #Html.Action() call is and once within the rest of the page, just before where next #Html.Action() call is inside the main page being shown in the layout.
I assume it has something to do with #Renderbody() displaying all partial views returned from the controller but I have no idea.
Any pointers on if this is true, and if so how can I show my menu without using an action?

I had a similar situation where I was calling an ActionResult using #Html.Action in order to render a partial view (after processing some data), however it kept repeating the layout twice. To fix it I had to change the ActionResult to a PartialViewResult, even though both were returning a partial view, the former seemed to treat it as if it were returning a view anyway...

Related

Grouped preloading of database items in ASP.Net MVC

Imagine you have a View within ASP.Net MVC which have got several Partial Views embedded in it which work independently and each load their own model through Html.Action (Child Actions). Now each separate Partial View would need to load certain items from the database. In terms of performance it would be much more efficient to group all such database calls together and preload all the items of the same type with one query rather than one by one through each separate Child Action.
For example, lets say we have the following structure:
Index (View)
Main Menu (Child Action / Partial View)
This would load Sections with IDs 1 & 2
Main Content (Child Action / Partial View)
This would load Sections with IDs 3, 4, & 5
Related Sections (Child Action / Partial View)
This would load Sections with IDs 6 & 7
...
Now in the above scenario, each child action above would separately make the respective database calls to load the sections required by its own model.
In order to improve on performance, we need a way whereby before we execute each Action or Child Action, such database item requests are 'registered' and then be able to load all the items together. Then when the Action or Child Action would need to use such database items, they would have already been preloaded altogether.
We were thinking of using Action Filters which are attached to each Action & Child Action stating which items are requested but unfortunately the OnActionExecuting method is called separately prior to each action being call.
We would like something similar to Action Filters but rather than being executed prior to each call, they are executed all in the beginning of the request before any Action / Child Action is called. This way we can register all such database item requirements and load them together.
Something similar to the OnInit event within Asp.Net Web Forms whereby first the OnInit for all user controls & controls is called followed by the other events within the ASP.Net Web Forms life cycle.
Or maybe you can offer a different solution which performs similarly to what we require?
Child actions are explicitly intended for unrelated content: things you actually couldn't reasonably combine in a single DB query, anyways. If it's all related things and you can query all at once, then just add it all to a view model, and use partial views with just RenderPartial.
Actually there is no way to predict which child actions will be invoked in a view. Also you may have nested calls to child actions, invocations from the Layout, etc.
In you situation I see two ways to optimize performance:
1) Use caching - it will improve performance for the further requests, but not the first one
2) Instead of having only child actions - use partial views. In this case your main Index action will load all necessary items, build a model containing properties MenuItems, Content, RelatedSections and pass them to Index view. Then from index view you will invoke RenderPartial and pass corresponding data as a model to this partial. If you need AJAX functionality to retrieve updated part of the page - then you need to create separate actions for the each partial view.
In a short - use RenderPartial for the normal requests, and Actions for the each view in case of AJAX requests.
If you are not planning to use AJAX - then it's better to use only RenderPartial method, since Action is heavier and will work a little bit slower, since routing, instantioation of a controller, etc is involved to render HTML for child action.

ASP .NET MVC - How to redirect a user control to the view its called from?

I have a user control that creates a new record in a database. After it creates the new record, I would like to redirect it back to the view its from. The purpose of this is to refresh the view so that it can show the newly created record. The problem is that user control can exists in more than one view, so how can i know which view is the user control from? so that I can achieve the above scenario? Thanks,
RWendi
I have a user control that creates a new record in a database.
No, it doesn't. It just renders HTML, and nothing else.
It's the controller action which creates a new record in the database, and thus this is where the redirect should happen.
The [HttpPost] action which accepts the model/form should perform the redirect after the save has been completed.
E.g:
public ActionResult Save(SomeModel model)
{
db.Save(model);
return RedirectToAction("Index");
}
I'm assuming that the "view" you want to refresh is the same page, regardless of which page the user controller was rendered on, therefore the above code is fine.
On a side note, you shouldn't be using user controls (e.g partials) for rendering forms.
You should be using editor templates. The presentation code which renders the form (and specifies which action to post to) should be in the view, not in the user control.
EDIT - example of how to render form on Views:
Instead of doing this on a View:
#Html.Partial("_SomeModel")
Do this:
#using (Html.BeginForm()) {
#Html.EditorFor(model => model.SomeModel)
}
And place the form markup in the editor template. The key thing here is IMO the Views should be responsible for setting up the form, not the user control.
There are several ways,
1) You can use this.Request.UrlReferrer.AbsoluteUri , which will always give you the Url of your page.
2) Or, you can have a hidden property in ... in PartialView, which will hold the value for current url. (#this.ViewContext.ParentActionViewContext.HttpContext.Request.UrlReferrer.AbsoluteUri)
But only if you are using #Html.RenderAction.
In the child action, you can redirect to either of above urls. (First approach is much more better and will work in all scenarios)
I think the refresh is responsibility of the action that renders the view your user control is from.
You can have scenarios (or views) where the inserting is done in one action and then pass the request to another action (maybe a list) that shows the newly created record.
Or you can have other scenarios where the inserting is just part of what you want to save to the db and refreshing the original view may cause the loss of data.
Maybe what I'm saying is not what happens with your project right now but it's something you should consider before giving the user control a responsibility it shouldn't have.

Specify in controller code which partial a view will render

I have a RegisterView, used for three different actions. Until now it was only used for two, and I have a FormVisible flag on my view model that the controller sets for the first action, which uses the visible form to collect user details. On the second action, confirming the registration, the details form is not visible.
I now have two sets of details to collect, so instead of a boolean decision of whether on partial view must be rendered or not, I need a way for the controller to specify which partial view to render. How can I do this?
have not tried this, but you can pass the name of the partial view in either the view model or the ViewBag, then use that in your view to render the partialview
in the controller:
ViewBag.PartialView = "PartialViewA";
in the view:
#Html.RenderPartial(ViewBag.PartialView)

posting an action from a partial view within a jquery dialog

I have an index page with a jquery tab loaded. Within one of the tabs I open a partial view company.ascx. Within that I have 2 RenderActions' One loads the company header and the other loads the branch information.
<% Html.RenderAction("Compheader", "Home"); %>
<br />
<br />
<% Html.RenderAction("BranchList", "Branch", new { Id = Request.QueryString[0], pdate = Request.QueryString[1] }); %>
Within BranchList I display a table of branches each of which has a delete button associated to it. There is also an add button on the branch list. Both these buttons open a jquery dialog that open partial views (acsx) within it. The dialogs have a submit post within them.
When the user clicks on submit on the insert/add or delete view I want to be able to refresh the BranchList action, which will get the new branchlist and display it.
Right now on post within the delete or insert I response redirect to the index page which refreshes the whole page. Can somebody tell me how I can accomplish this using Html.BeginForm and ajax posts in a clean way instead of the response redirect.
You are accessing QueryString directly within your view and that means that you are not using any of the goodness of ASP.NET MVC framework. You should get these values in action method (using the matching parameter names as the QueryString variables in the action method's constructor) and then pass these values from action method to the view (using a view model or ViewData) so that you don't have to access QueryString directly inside the view.
Now coming to your question, I think you are doing it right. If you are getting the right behavior from your application, then you should not change the post-redirect behavior of the application.
You are posting the data from the partial views and then doing a redirect. This is a valid pattern, also known as GPG (Get, Post, Get) pattern. This is advantageous compared to simply sending the user to their "Posted" page as it avoids from letting the user post the same data twice in case they refresh the page.
Hope it helps.

ASP.NET MVC ViewResult vs PartialViewResult

What is the difference between the controller result named ViewResult and PartialViewResult? More importantly, when is the PartialViewResult used?
PartialViewResult is used to render a partialview (fx. just a user control). This is pretty nifty for AJAX stuff, i.e.
<script type="text/javascript">
$.get(
"/MyController/MyAction",
null,
function (data) { $("#target").html(data) }
);
</script>
and action
public ActionResult MyAction()
{
return PartialView("SomeView");
}
where SomeView is a MVC User Control, e.g.:
<div>
<%= DateTime.Now.ToString() %>
</div>
http://msmvps.com/blogs/luisabreu/archive/2008/09/16/the-mvc-platform-action-result-views.aspx
In practice, you’ll use the
PartialViewResult for outputing a
small part of a view. That’s why you
don’t have the master page options
when dealing with them. On the other
hand, you’ll use the ViewResult for
getting a “complete” view. As you
might expect, the Controller class
exposes several methods that will let
you reduce the ammount of typing
needed for instanting these types of
action results.
Generally speaking, ViewResult is for rendering a page with optional master, and PartialViewResult is used for user controls (likely responding to an AJAX request).
none of the existing answers actually answer the question "What is the difference".
The differences are as follows:
1) the locations where the view engine will attempt to find the view:
for ViewResult, it's in ViewLocationFormats and MasterLocationFormats
for PartialViewResult, it's in PartialViewLocationFormats
2) ViewResult has the additional property MasterName
that is all.
There are several cases where you would want to break down your view into several small components. One use case that I am working with right now, is I have a multi-lingual site that I would like to reload content using AJAX principles.
Normally what I would do in the case of a non-multi lingual site is to create another ActionResult to return the ViewModel that is changing with the new parameters. I like to use a custom ActionResult that I have called JsonpResult. The problem resides in the fact that I have labels not in my database but in Resource files. So what I would need to do is to somehow hydrate my Resource file data into the ViewModel.
Once the data comes down the pipe, my AJAX callback handles the wiring up of the ViewModel response back to the HTML page using Javascript (I use jQuery).
This definitely works, however it becomes a question of maintainability. I now need to not only maintain my original ASP.NET view, but I also need to maintain a set of scripts that handle AJAXian behavior. If you need to have your site SEO, then you really need to make sure that both the Server Side and Client Side behavior are both working the same.
This is where Partial Views come into play for me. What I do is "pull out" the logical data sections where the bulk of the reload occurs. The nice thing about PartialView is that you can pass your ViewData and Model along to the PartialView. If your PartialView is strongly typed against your ViewModel you can get Intellisense to help with the wiring of the PartialView.
Now all I need to do with my AJAX call is to write the response back to a single DIV rather than handling data points individually. What it does mean is that there would be more content coming down the pipe. However, the trade off is easier to read and maintain code.
The one of the main differences is PartialViewResult doesn't use _ViewStart.cshtml. The code from _ViewStart.cshtml file executes at the start of rendering before any code in the view.

Resources