Open rianjs opened 7 years ago
💭 https://github.com/tunnelvisionlabs/dotnet-uritemplate
I don't think I ever released a stable version (lack of external interest), but it could probably be done.
For lack of a first-party solution, I would use the heck out of a nuget replacement. Another person linked their nuget package in dotnet/runtime#17085 that purported to be a replacement, but it didn't have BindByName
or BindByPosition
, wihch I use extensively.
Here's the original source, actually: http://referencesource.microsoft.com/#System.ServiceModel/System/UriTemplate.cs
@rianjs The Tavis.UriTemplates supports bind by name. I don't think bind by position would be too hard to implement. The System.ServiceModel UriTemplate library does a better job of parsing URLs for inbound requests.
@rianjs do you mind writing up a formal api proposal along with the usecases where you think this might be useful?
@rianjs Is the missing bindByPosition the only thing stopping you from using Tavis.UriTemplates ? Might be enough incentive to get me to do the .net Standard 2.0 port and add strong naming while I'm at it :-)
@joperezr I show a bunch of common cases for why you want to use a library to do URL construction here http://www.bizcoder.com/constructing-urls-the-easy-way
@darrelmiller another missing functionality preventing me from using Tavis.UriTemplates is lack of support for wildcards - which I know are not part of rfc6570 - but were supported by wcf Uri template.
var template = new UriTemplate("http://localhost/{*x}/", false)
var values = template.GetParameters("http://localhost/foo/1/"); // values is null
Any suggestions on how to work around this?
@hnafar The UriTemplate equivalent of the * wildcard is http://localhost{/x}/
I'm not sure if the current parameter parsing handles this scenario, but if it doesn't then yes we should try and fix that.
It seems that UriTemplate is not in .NET standard either, not in System.ServiceModel.Primitives.
UriTemplate is really helpful for writing dev tool. Just wonder if it will be available in .net core 2.3?
@darrelmiller @davidsh would it be possible to add some form of RFC6570 (URITemplate) support to Microsoft.AspNetCore.Http.Extensions ? It would seem like a natural fit alongside QueryBuilder which lives there. I was really surprised that there wasn't a package to do this currently in .NET Core. Thanks! I don't know if it would be realistic to adopt Tavis.UriTemplates as an option?
cc: @rmkerr
@darrelmiller @davidsh would it be possible to add some form of RFC6570 (URITemplate) support to Microsoft.AspNetCore.Http.Extensions
@Tratcher Can you comment on this feature request for Microsoft.AspNetCore.Http.Extensions?
UriTemplate
is used to safely build URLs. It's safer, and more capable than string concatenation.
How so? Because the template handles the character escaping when inserting the values?
@davidsh Microsoft.AspNetCore.Http.Extensions is one place this could be provided, but by no means the only place. The examples given above already show this is useful for client apps using HttpClient.
@davidsh Microsoft.AspNetCore.Http.Extensions is one place this could be provided, but by no means the only place. The examples given above already show this is useful for client apps using HttpClient.
@Tratcher, the only reason that I mentioned Http.Extensions as a possible landing place is that the original issue had the following comment from @davidsh, but now that there's Http.Extensions I thought I would bring up the request again as maybe now there's an appropriate place for it whereas there wasn't necessarily before?:
Thank you for the suggestion. It is a good idea in general about having templates, but we think it belongs where it is in WCF and is not generally applicable to .NET Core.
Here's some motivation background from RFC 6570. For me, it just reduces everyone writing 'reinventing the wheel (poorly)' utility classes, ensures consistent correct behavior among various teams, and means that I don't have to worry about things like missing/doubled slashes when concating fragments, escaping, etc. Does that help?
URI Templates provide a mechanism for abstracting a space of resource identifiers such that the variable parts can be easily identified and described. URI Templates can have many uses, including the discovery of available services, configuring resource mappings, defining computed links, specifying interfaces, and other forms of programmatic interaction with resources.
Missing slashes or double slashes is a common gotcha. Optional query parameters are also things people struggle with. Multi-segment paths and optional paths are easy with a template. Another nice side benefit is query parameters always appear in the same order which can be helpful.
It would be great to see this feature in ASPNetCore or even better in System.Net.Http because people don't want to pull in a 3rd party dependency for what they initially see as just string concatenation. It's once you start using templates regularly that you start to realize all the ways it saves you from pain.
Consider chunks of code like this that are all over the Azure SDKs,
var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ApiManagement/service/{serviceName}/apis/{apiId}").ToString();
_url = _url.Replace("{resourceGroupName}", System.Uri.EscapeDataString(resourceGroupName));
_url = _url.Replace("{serviceName}", System.Uri.EscapeDataString(serviceName));
_url = _url.Replace("{apiId}", System.Uri.EscapeDataString(apiId));
_url = _url.Replace("{subscriptionId}", System.Uri.EscapeDataString(Client.SubscriptionId));
List<string> _queryParameters = new List<string>();
if (format != null)
{
_queryParameters.Add(string.Format("format={0}", System.Uri.EscapeDataString(format)));
}
if (export != null)
{
_queryParameters.Add(string.Format("export={0}", System.Uri.EscapeDataString(export)));
}
if (Client.ApiVersion != null)
{
_queryParameters.Add(string.Format("api-version={0}", System.Uri.EscapeDataString(Client.ApiVersion)));
}
if (_queryParameters.Count > 0)
{
_url += (_url.Contains("?") ? "&" : "?") + string.Join("&", _queryParameters);
}
This can be replaced by a single line using a UrlTemplate
@darrelmiller that's exactly the kind of thing we see too, it's one of those things that seems 'easy' to start with string concat but then as requirements (and/or code duplication) grows everyone either rolls their own utility lib or pulls in a dep :)
@Tratcher , who would be a good PM to loop in and see if it would be possible to work this into the ASP.Net Core 3.0 timeline? THanks!
@shirhatti as he covers both the .NET Core and AspNetCore sides.
Just to confirm, is this feature on the road map for netcore 3.x? If so, can you perhaps link it here? Thank you
Not for 3.x that I'm aware of. 3.1 has shipped and so we are only shipping servicing fixes, which will very rarely include API additions. According to the Milestone on the issue, this is currently scoped as part of 5.0
Thanks for the update @joperezr
It's now mid-2023, and .Net 8 is almost out. Is there any hope of UriTemplate
being included?
@dotnet/ncl is this something that could be reviewed?
An implementation of support for RFC 6570 URI templates seems like a good fit for the standard library along side System.Uri, System.UriBuilder, etc.
It doesn't seem to me like something that should be in dotnet/aspnetcore as it's not specific to hosting. Making web requests is not the exclusive domain of web applications!
I don't know about any policy regarding adding functionality to dotnet that is already (mostly) provided by third-party libraries?
It would be nice to be able to do something like this:
dotnet/runtime#17085 asks about the same thing, and the response was:
I think that comment misunderstands the use case for
UriTemplate
s. There's nothing WCF-specific aboutUriTemplate
. In fact, the code above is taken from a service client implementation that interacts with an ASP.NET Core web service.UriTemplate
is used to safely build URLs. It's safer, and more capable than string concatenation. Building URLs isn't specific to WCF, so it would be nice if it were available in .NET Core.