What to use instead of WebViewPage.RenderPage method in ASP.NET 5 MVC6 - asp.net-core

Given an example based on old MVC5:
Views/Shared/Index.cshtml - a view for a SPA app. It contains some markup and a reference to a layout-page:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
In _Layout.cshtml there're number of includes which are being used via RenderPage helper:
#RenderPage("~/Views/Shared/_ImportCssInline.cshtml")
#RenderPage("~/Views/Shared/_ImportCssLinks.cshtml")
Now in AspNet5 #RenderPage helper isn't available.
It was the method of WebViewPage/WebPageBase/WebPageRenderingBase. Now they were replaced by RazorPage. But there's no RenderPage method in it.
What should be used instead?
p.s. issue

I've always had success using #Html.Partial("~/Views/Shared/_ImportCssInline.cshtml") rather than #RenderPage - I hope there's not usage differences for you. There are also async versions of these imports now, too.
Since the Html property is now injectable as the interface IHtmlHelper, I assume the direct methods were removed in the improvements for the testability of the views.

Related

Can PartialViews replace with TagHelpers in ASP.NET Core?

I am new to ASP.NET Core. I just discovered TagHelpers and as I may get the idea, theoretically we should be able to replace partial views with tag helpers.
Beyond that, TagHelper can accept input but PartialView don't.
do I think right? or it's a misunderstanding? can anyone explain the difference clearly?
Thanks in advance!
This is for asp.net core 2.1+
If I understand your question correctly, you can replace all your HtmlHelper partial views with your own TagHelpers, but you were already able to do this with HtmlHelpers so its not something new.
However, there is a difference between HtmlHelpers, TagHelpers and Partial Views.
Partial Views
A partial view is a Razor markup file (.cshtml) that renders HTML output within another markup file's rendered output. Eg _partial.cshtml.
HtmlHelper
HtmlHelpers were introduced with the MVC framework to be able to render html serverside. Easily distinguished by the # character in razor views.
#await Html.PartialAsync("_partial.cshtml", Model.Contact)
Beyond that, TagHelper can accept input but PartialView don't.
The second parameter in PartialAsync allows for input.
TagHelper
With asp.net-core, TagHelpers are another way to be able to render server side html by using tags and attributes in the razor views. Aside from html friendly views, it provides less abstraction from html. In the code below I'm using the Partial TagHelper, where the name attribute defines the path or name of the view, and the for attribute assigns the model expression that will evaluated (#Model). This means you don't need to use for="#Model.Contact" and simply just for="Contact".
<partial name="_partial" for="Contact" />
You could also use the model attribute, which just passes the model to the partial view on instantiation.
<partial name="_partial" model='new Contact { Id = 1, Name = "Nick" }' />
As seen from above, both TagHelpers and HtmlHelpers can render partial views.
Furthermore if you look at asp.net-core github for the HtmlHelper
https://github.com/aspnet/Mvc/blob/b18526cdc8d8c868e8d7f9c6c8484064215e1002/src/Microsoft.AspNetCore.Mvc.ViewFeatures/HtmlHelper.cs#L554
and compare it to the TagHelper
https://github.com/aspnet/Mvc/blob/b18526cdc8d8c868e8d7f9c6c8484064215e1002/src/Microsoft.AspNetCore.Mvc.TagHelpers/PartialTagHelper.cs#L216
Both are actually calling and IView.RenderAsync() and passing in a ViewContext which includes the partial view. So they virtually do the same thing in code behind, except for the way it manipulates the html.
Side notes:
Much like HtmlHelpers, you can also create your own TagHelpers which can replace whole partial views.
TagHelpers are not to replace HtmlHelpers, but provide alternative approach. However, in my opinion TagHelpers are better. They render better in visual studio editor (razor pages used have a lot of formatting problems due to the #HtmlHelpers), is way more readable, and comply with html.
In the partial TagHelper, you can use either model or for to provide data to the partial, but never both.
Omitting .cshtml from the name will just force the framework to search for the view in Pages, Views, and Shared folders. Its totally optional.
Hope this helps

How to use GWTP for a ListView (Widget)?

I started to use GWTP for my project and I'm currently re-writing all my code to let it work with this library.
However, I struggle to understand how I use GWTP if I want e.g. a ListView with ListItemView items.
#Inject
public ToolsPresenter(PlaceManager placeManager, EventBus eventBus, MyView view, MyProxy proxy) {
super(eventBus, view, proxy, AdminToolPresenter.SLOT_AdminToolMainContent);
this.placeManager = placeManager;
ToolListView toolListView = new ToolListView(...)
ToolListPresenter toolListPresenter = new ToolListPresenter(....);
this.setInSlot(SLOT_ToolList, toolListPresenter);
}
What I want is to place my ListView inside a slot. I am very certain that I can't do what is shown up there but I just don't get how I use just simple Widgets with GWTP.
Or am I doing this completely wrong and I should just extend a Composite for ListView and not use GWTP stuff here at all?
There is a lot of information missing from your question so this is a difficult one to answer.
Assumption 1 - Your GWTP artifacts (ToolListView, ToolListPresenter, ToolListView.ui.xml, and ToolListModule) are setup correctly and ToolListModule is installed in a parent module.
Assumption 2 - You are using GWTP version 1.5+ which has typed slots.
You should not be instantiating your ToolListView or ToolListPresenter.
Simply add:
#Inject ToolListPresenter toolListPresenter;
If you are trying to call the setInSlot method then
Make sure ToolListPresenter is a PresenterWidget
Make sure your slot is not a NestedSlot.
Finally try moving the call to setInSlot outside of your constructor and into the overridden onBind() method.

How can I embed a twitter timeline in a Durandal view?

The code to embed the widget is nice and simple, but it includes javascript in tags.
Durandal appears to strip out such script tags.
How do I use the embed code in a Durandal view?
https://dev.twitter.com/web/embedded-timelines
<a class="twitter-timeline" href="https://twitter.com/XXX" data-widget-id="XXX">Tweets by #XXX</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
You would need to write a custom Knockout binding, or create a Durandal widget where the view is your tag, and the viewModel handles the JavaScript in your tag.
Some notes: In your widget's view model, you would avoid d.getElementsByTagName(s) in favor of simply referencing the view reference passed in to either the attached or compositionComplete handler that Durandal provides. In fact, you could pretty much eschew all direct DOM manipulation in favor of Durandal's imported view references and Knockout's/Durandal's templating/composition.
UPDATE
Take a look at this from the documentation you reference: "If you’re already including our ‘widgets.js’ JavaScript in your page to show embedded Tweets or Twitter buttons, you don’t need to include this script again; it updates automatically to support new features."
This could lead you down the path of simply referencing widgets.js in a script tag in your index.html or index.chtml file.
You cannot use script tags in Durandal views, but you can use them in your index page.
SECOND UPDATE
Once widget.js has been referenced in a script tag in the index.html or index.chtml (or perhaps even by using AMD), it becomes a matter of choosing the proper Durandal point at which to load the Twitter widget. This could be either in the attached handler or in the compositionComplete handler, as indicated above.
As the OP pointed out in his comments, a functional place to do this is compositionComplete, in the following manner:
var compositionComplete = function () {
twttr.widgets.load();
}
as documented here.
This assumes that twttr is either on the window or injected into the viewModel.
POSSIBLE MEMORY LEAK
It is equally important to note that unloading of widgets must take place in the Durandal's detached handler. Use Twitter's API to unload, and then be sure to nullify the windows reference.

Using TagHelpers vs ViewComponents in ASP.NET MVC6

I'm trying to understand the use case differences between TagHelpers and ViewComponents in asp.net 5 because the end result functionality seems very similar. We have TagHelpers that can create new HTML tags that get parsed by the Razor engine and then ViewComponents that get explicitly invoked. Both return some HTML content, both are backed by their respective base classes, both have async versions of methods they can implement to get their work done.
So when would one be used over another? Or am I missing some information?
There's definitely some conceptual overlap between TagHelpers and ViewComponents. TagHelpers are your utility to work with HTML where ViewComponents are your way to stick to C#, do isolated work and then spit out HTML. I'll go into each in detail:
ViewComponents
Your conceptually equivalent mini-controller; you will see that many of the methods/properties that ViewComponents expose are very familiar to those that exist on a Controller. Now as for invoking ViewComponents, that's more equivalent to utilizing HTML helpers (one thing TagHelpers make better). To sum up ViewComponents: Their primary purpose is to feel like a controller, stay in C# land (there may be no need to add utility to HTML), do smaller/isolated work and then spit out stringified HTML.
TagHelpers
A utility that enables you to work along side existing HTML or create new HTML elements that modify what happens on a page. Unlike ViewComponents TagHelpers can target any existing HTML and modify its behavior; example: you could add a conditional attribute to all HTML elements that would conditionally render the element server side. TagHelpers also allow you to intermingle common HTML terms, ex:
<myTagHelper class="btn">Some Content</myTagHElper>
As you can see we're adding a class attribute to our TagHelper just as if it were HTML. To do this in ViewComponents, you'd need to pass in a dictionary of attributes or something equivalent (unnatural). Lastly multiple TagHelpers can run over a single HTML element; each having their own stage at modifying output (allows entry for modular TagHelper toolkits). To sum TagHelpers up: They can do anything that ViewComponents can do and more BUT do not feel familiar to things like Controllers that ASP.NET developers are used to; also some projects may not want to intermingle server side HTML.
Extra:
I recently did a video showcasing the benefits of TagHelpers. Basically a walk through of what they're good at and how to use them. You can watch it here.
When deciding which one to use I always consider how complex the HTML of the component will be.
If it's something simple like a tree view or a pager
<ul class="jstree">
<li>Node 1</li>
<li>...</li>
</ul>
That is candidate for tag helper, because it's simple. Large HTML in a C# code would be hard to maintain.
On the other hand if it's complex HTML with many divs, images and configuration like a full blown menu where it can be vertical or horizontal that's your view component. Benefit of view component is that you can use multiple views so for menu so you can separate horizontal.cshtml & vertical.cshtml while reusing same backend code.
Turns out that in .Net Core 1.1, you can call a ViewComponent using the tagHelper syntax.
Regarding Taylor's comment "Their primary purpose is to feel like a controller", it is true, but since you cannot directly call this "micro-controller" directly, the "controller-like" behavior is limited in that you can only create a part of a page, you cannot call it again (say via an ajax call, an Edit Action, etc).
One primary difference between TagHelpers and ViewComponents relates to how much work needs to be done by the object. TagHelpers are fairly basic, requiring only a single class that overrides the Process method to produce the output of the TagHelper. The downside is that if you do any complex work to create inner HTML in the TagHelper, it has to all be done in code. In a ViewComponent, you have a mini-controller capable of doing a lot more work, plus it returns a view, where you have actual Razor syntax code that can be mapped to a model.
Another post mentioned that ViewComponents are more "HTML Helper"-y in how you call them. ASP.NET 1.1 addressed that issue, so that you can call it with
<vc:view-component-name param1="value1" param2="value2></vc:view-component-name>
For most purposes, a TagHelper has a definite advantage, because it's easier. But if you need a more robust solution, ViewComponent is the way to go.
And yet something that kind of defeats the purpose of View Components (IMHO) is that from the View Component class there seems to be no way to access the Inner Html of the VC if you use the tag helper syntax:
<vc:MyComponent id="1" att="something">
Some HTML markup you would not want to put in an attribute
</vc:MyComponent>
There are however good applications of a VC such as the Bootstrap Navigation Bar View Component I saw in a TechieJourney blog post.

Default EditorTemplates

I'm trying to just ever so slightly tweak the default EditorTemplate for a SelectList. Is there somewhere where I can find the source for all the default EditorTemplates (i.e so I have a base reference to work off of).
I've had a peek on the asp.net mvc source page and cannot find the templates listed in their source code (although I am most likely missing it).
The default EditorTemplate for a SelectList is actually just this method:
System.Web.Mvc.Html.SelectExtensions.SelectInternal()
So it is not implemented as a .cshtml template at all. Instead it builds up the markup in C# using a TagBuilder. You could take this implementation as a starting point for your own C# method, or else port it into the equivalent razor syntax.