I am trying to render a partial page inside a partial page.
So i have in my layout page a call to my partial CreateMenu and here i pass the model from the layout page. This works perfect.
Now inside the CreateMenu partial i am trying to call MenuItem with the same syntax but then it fails. Visual studio shows the path as red (i know to 100% that it exists).
How can i render a partial from inside a partial.
MenuPartial's call to the render:
#Html.Partial("~/Models/Default/UserControls/_MenuItem.cshtml", Model.Modules[i])
Model.Modules[i] consists of MvcModule objects.
MenuItem:
#model Models.Default.Classes.MvcModule
<li class="#{if (Model.CanExpand) {<text>fullwidth</text>} else {<text>nodrop</text>}} first_fullwidth">
...
This results in a compilation error:
Compiler Error Message: CS0115:
"ASP._Page_Models_Default_UserControls__MenuItem_cshtml.Execute()":
Es wurde keine passende Methode zum
Überschreiben gefunden.
Line 46: public override void Execute() {
Sorry for the German text. I have tried to get it to output English instead but VS 2010 refuses to change the settings =/
I don't think this is a nested partial issue. You should be able to nest partials without any problem. It looks like the partial you're trying to render is in the ~/Models/Default/UserControls directory. This isn't a place the default view engine looks for views. Try copying the web.config file from your Views directory into the Models directory.
If it were me, I would try to avoid storing views outside of the Views directory if at all possible to avoid weird issues like this.
Related
When I use normal return this->render('create', ['model' => $model]) my pop-up window goes all haywire. When I change to return $this->renderAjax('create', ['model' => $model]); everything is magically in their correct places. I have looked around quite a bit to read about renderAjax() but there seem to be absolutely nothing out there. Can someone tell me what it does? I know ajax but from what I know it usually has nothing to do with css or bootstrap.
To know the difference between render() and renderAjax() first you need to understand how render() works.
Basically when render() is called every piece of JS and CSS code and file references registered with the view is gathered in several arrays to be rendered later on in proper places - these places are stored in the layout and their code is rendered by calling beginPage(), head(), beginBody(), endBody() and endPage().
You can point where the JS code should be rendered by setting the second parameter in related methods - like for example:
$this->registerJs("alert()", \yii\web\View::POS_HEAD);
renders
<script type="text/javascript">alert()</script>
in layout where the method $this->head() is.
Everything is working fine until you want to render only a main part of view without the layout. Without it (and its methods like beginPage()) the JS and CSS references cannot be rendered in the previous way and that is why this fancy jQuery code rotating the square does not work - JS library has not been included there.
When you are calling $this->render() from within the view or just calling $this->renderPartial() from the controller exactly this is happening - layout is not applied.
renderAjax() comes now to the rescue.
This method doesn't care about layout because it calls beginPage(), head(), beginBody(), endBody() and endPage() methods by itself. Thanks to this every JS piece of code can be attached to the rendered view and the jQuery library can rotate this square once again even when it needs to be done inside an AJAX popup.
render() public method
Renders a view.
The view to be rendered can be specified in one of the following formats:
path alias (e.g. "#app/views/site/index");
absolute path within application (e.g. "//site/index"): the view name starts with double slashes. The actual view file will be looked for under the view path of the application.
absolute path within current module (e.g. "/site/index"): the view name starts with a single slash. The actual view file will be looked for under the view path of the current module.
relative view (e.g. "index"): the view name does not start with # or /. The corresponding view file will be looked for under the view path of the view $context. If $context is not given, it will be looked for under the directory containing the view currently being rendered (i.e., this happens when rendering a view within another view).
renderAjax() public method
Renders a view in response to an AJAX request.
This method is similar to render() except that it will surround the view being rendered with the calls of beginPage(), head(), beginBody(), endBody() and endPage(). By doing so, the method is able to inject into the rendering result with JS/CSS scripts and files that are registered with the view.
renderAjax()
render()
I have Yii2 application which has a regular controller with regular action and its view trying to render a view that's part of an extension. My view is in the 'views/controllerName' folder and I'm trying to reach a view which is in 'vendor/providerName/extensionName/views/extensionController'. What is the right way to do that?
I'm tried the regular render() method with different strings like: extensionController/extensionView, /extensionController/extensionView, //extensionController/extensionView but I keep getting an error message that the file is not found in the main view folder which is not where I want the framework to look at first place.
e.g.
echo $this->render('#vendor/firephp/test');
so in your case
echo $this->render('#vendor/providerName/extensionName/views/extensionController');
We are using MVC 3 and .Net Framework 4.0. We use MVC and Webforms together. For some users, we get System.InvalidOperationException: The model item passed into the dictionary is of type 'System.Web.Mvc.HandleErrorInfo' but this dictionary requires a model item of type 'HeaderModel'.
A regular page looks like this:
#{
Layout = "~/Views/Shared/_HomeLayout.cshtml";
HeaderModel header = new HeaderModel();
ViewBag.Header = header;
}
<div id="mainAreaContainer">
....
</div>
At top of each page we create header model object and put it ViewBag.
In layout page we have this:
#Html.Partial("_HeaderPartial", (HeaderModel)ViewBag.Header)
Our layout pages does not expect any models.
We get this error on our standard regular views, not on error view.
We have an error page such that error page has a model which inherits from HandleErrorInfo.
As far as I understood, error occurs in regular views, not in error view. We handle unhandled exceptions in global.asax Application_Error part and redirect to error page.
I tried to recreate the error by throwing exceptions from view, controllerbase and some other places but the exception appeared in logs what it is.
Strangely we do not understand real error which generates a HandleErrorInfo in a standard page.
R# is incorrectly reporting one of my MVC3 views as having an error. I have 2 layouts, each with different sections defined:
#{
Layout = "~/Views/Shared/layout2.cshtml";
}
#section Layout2Section { #* Layout2Section is red, reported as error by R#. *#
<span>Injected into LayoutSection2</span>
}
The view displays fine in a browser. Here is code from layout2:
#RenderSection("Layout2Section", false)
#if (!IsSectionDefined("Layout2Section"))
{
<span>default layout2 section</span>
}
There is another layout view in ~/Views/Shared named _Layout.cshtml, the default in an MVC3 project. R# is only giving intellisense for sections in _Layout.cshtml, not layout2.cshtml. I have tried prefixing with an underscore, it does not work. If I try to define any section in layout2.cshtml that is not defined in _Layout.cshtml, R# is calling it an error. How to disable this, either to tell R# that the view is a section definer, or to get rid of the "1 file with errors" message?
Update
After derigel's comment, I realized that the above code is not exactly what I have in my project. Specifically, the line that defines the layout uses T4MVC like so:
#{
Layout = MVC.Shared.Views.layout;
}
If I change it to a string as in the original question, the R# error goes away. #Derigel, shall I still create a test project and post to your tracker? I just reproduced the above update in a brand new MVC3 project, after adding the T4MVC lib.
#olivehour Oh, now I get it. It's known limitation of R# - it can detect layouts only in constant string literals. Can you change T4 templates to generate constants instead of readonly fields?
When I try to add a partial view using asp.net mvc 3 and razor it just add's a normal .cshtml file and not a partial view. has anyone had this problem before?
/Martin
In Razor there is no notion of partial views as there was in WebForms. You only have templates with the .cshtml extension. Depending on how the controller action serves this view (with either return View() or return PartialView()) the _Layout.cshtml will be applied or not. Also if you render a template with either the Html.Partial helper this template will be considered as a partial view. Finally you have the possibility to set whether you want or not a Layout from inside the template itself. For example to disable it:
#{
Layout = null;
}
So basically in Razor you have templates and you could consider partial views as templates without a layout.