Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTML5 defined elements with URL accepting attributes are now TagHelpers. #57

Open
NTaylorMullen opened this issue Aug 25, 2015 · 1 comment

Comments

@NTaylorMullen
Copy link
Member

What's the Problem?

Classic Razor would resolve the value of any HTML attribute that started with ~/ as an application relative URL. This led to some invalid scenarios where users would provide attribute values such as ~/folder/file.txt and get inaccurate URL resolutions. In addition, this feature couldn't be easily disabled.

The Fix

There were multiple locations for a valid fix; we decided that it didn't make sense to hard code the list of HTML5 defined element/attribute combos in the core Razor parser. In addition, the introduction of TagHelpers led to some users expecting to see the raw value of their attribute values instead of the intercepted value.

Therefore, we decided to create the UrlResolutionTagHelper to take over ~/ resolution.

It targets the following attribute/element combos:

  • href : <a>, <area>, <link>, <base>
  • src : <audio>, <embed>, <iframe>, <img>, <input>, <script>, <source>, <track>, <video>
  • action : <form>
  • cite : <blockquote>, <del>, <ins>, <q>
  • data : <object>
  • formaction : <button>, <input>
  • icon : <menuitem>
  • itemid : everything
  • manifest : <html>
  • poster : <video>
  • srcset : <img>, <source>
  • archive : <object>, <applet>

Side effects

Any element that the UrlResolutionTagHelper targets now have runtime TagHelper restrictions applied to them. Some of these restrictions are:

  • Depending on the targets TagStructure a tag targeted by the UrlResolutionTagHelper may result in an error based on supported syntax.
    • TagStructure.WithoutEndTag = <tag> OR <tag />
    • TagStructure.NormalOrSelfClosing = <tag></tag> OR <tag />
    • TagStructure.Unspecified = Usually same behavior as TagStructure.NormalOrSelfClosing unless another TagHelper defines a different TagStructure.
  • C# must not exist in the declaration area of the tag.
    • Invalid: <a href="..." @myClass>...</a>
    • Valid: <a href="..." class=@myClass>...</a>
  • TagHelpers that bind URL based attribute values must now resolve them manually.
    • Can be done by taking in the IUrlHelper in the constructor (from DI) and calling IUrlHelper.Content on the value.

Note: These restrictions do not show up during design time due to the editor browsable attribute on UrlResolutionTagHelper. Reason behind this decision was that the majority of users will never encounter any of these restrictions and the TagHelper tooling would be misleading.

Workarounds

Disable URL resolution on the page:
By default every page essentially has an:
@addTagHelper "Microsoft.AspNet.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNet.Mvc.Razor"

Therefore, to disable ~/ URL resolution for an entire page you can do:
@removeTagHelper "Microsoft.AspNet.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNet.Mvc.Razor"
This can be done on the page and there's an issue tracking the ability to do this in _ViewImports.cshtml.

Disable URL resolution on an element:
You can also disable the URL resolution capability on a per-element basis via the TagHelper opt-out character !: <!href href="~/..." @myAttribute>...</a>

@NTaylorMullen NTaylorMullen added this to the 1.0.0-beta7 milestone Aug 25, 2015
@aspnet aspnet locked and limited conversation to collaborators Aug 25, 2015
@NTaylorMullen
Copy link
Member Author

This post is only for announcing the breaking change. Please post any feedback to corresponding discussion issue: aspnet/Mvc#3036

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant