Default EditorTemplates - asp.net-mvc-4

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.

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

Vue JSX bind to class name

I'm building a simple TodoMVC app using Vue + JSX, but the documentation seems to be seriously lacking. Thus, I'm writing down the points I need to address as part of a CR to the appropriate projects. The only document I've read as of yet is the guide, which doesn't cover much JSX at all. I don't know much about how the framework works yet, but I sure prefer using the render method over the string templates for performance/network reasons.
question
What's the proper way to create a class name binding in Vue + JSX? In my TodoItem component, creating either a class or className attribute makes Babel throw a compile error complaining the API is deprecated (and suggesting I add several seemingly unrelated dependencies to the mix). Plus, including the class property in the data object seems to change nothing.
secondary question
The lack of documentation, plus the wording on the guide gives the impression JSX is not the "proper" way to write Vue components. Is that so? What's the idiomatic way to do it, given I don't want to ship the compiler along with my app?
links
code on codepan
I sure prefer using the render method over the string templates for performance/network reasons.
If you're writing *.vue files and bundling them with vue-loader (Webpack), the HTML template gets compiled into a JavaScript render function anyway, so there isn't really any kind of performance issues in that sense.
On the other hand, if you're writing your Vue components with string templates like this:
new Vue({
template: '<div>Hello</div>'
})
then you'll need the Vue template compiler at runtime to convert the string into a render function.
Typically people would opt for writing render functions manually if they need to do something specific that would be difficult/impossible to do with the HTML template alone.
You've probably already read the docs, but just in case, the relevant sections are:
Render Functions & JSX
The Data Object In-Depth
babel-plugin-transform-vue-jsx Usage
What's the proper way to create a class name binding in Vue + JSX?
You would just bind to the class attribute like you would any other attribute:
<div class={this.klass}>
data() {
return {
klass: 'foo'
}
}
The lack of documentation, plus the wording on the guide gives the impression JSX is not the "proper" way to write Vue components. Is that so? What's the idiomatic way to do it, given I don't want to ship the compiler along with my app?
JSX is definitely supported, but it is not the recommended approach. The recommended approach is to write *.vue files and load them with vue-loader (if using Webpack).
Vue comes in two versions, one with and one without the template compiler. The one with the compiler included is only for development and should not be used for production builds (unless you require string template to render function compilation at runtime, which is unlikely). See Explanation of Build Files for more info.
Typically you write HTML string templates, and they get compiled to render functions (by vue-loader) at build time.

What to use instead of WebViewPage.RenderPage method in ASP.NET 5 MVC6

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.

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.

Passing collection parameters when calling templates in StringTemplate

Run into a bit of a snag using StringTemplate today. Were using StringTemplate 3.1 with .Net 3.5.
If I have a template that renders a collection of items, it renders fine if I call it directly.
However, if I call that template from another template and passing the collection through as a parameter, it fails to render at all.
The following is the basic template for rendering the collection. (Text is a property of the object we are rendering - System.Web.Mvc.SelectListItem)
list.st
$values: {
$it.Text$
}$
And this is the calling template.
callsList.st
$list(
values={ $list$ }
)$
My question is, has anyone else run into this or does anyone know how to work around it? The strange thing is, we have other parts of our system rendering in a similiar style and they seem to work fine.
Try values=list.
Terence