C# .NET Microsoft.AspNetCore.Http.Extensions UriHelper.GetDisplayUrl返回无效的URI
我是.NET framework的新手,我对Microsoft.AspNetCore.Http.HttpRequest接口有问题。我正在尝试使用扩展,但它返回的URI无效。稍后,我将URI传递给C# .NET Microsoft.AspNetCore.Http.Extensions UriHelper.GetDisplayUrl返回无效的URI,c#,.net,http,.net-core,C#,.net,Http,.net Core,我是.NET framework的新手,我对Microsoft.AspNetCore.Http.HttpRequest接口有问题。我正在尝试使用扩展,但它返回的URI无效。稍后,我将URI传递给System.URI.CreateThis(),并引发以下异常: System.UriFormatException: Invalid URI: The format of the URI could not be determined. GetDisplayUri方法应该基于HttpRequest中的
System.URI.CreateThis()
,并引发以下异常:
System.UriFormatException: Invalid URI: The format of the URI could not be determined.
GetDisplayUri
方法应该基于HttpRequest
中的字段创建URL,但我无法确定URL的哪些部分位于哪些字段中,我也无法在网上找到任何此类示例。我特别想知道如何将URL分解为路径
、路径库
和查询字符串
变量
例如,假设我想构建URL”http://example.com/route/endpoint?foo=bar“
。我很确定我的QueryString
只是“?foo=bar”
,但我不知道如何将URL的其余部分分解为其他字段。另外,请告诉我除了我提到的三个字段之外,是否还有其他与GetDisplayUri
相关的字段
如果有什么不清楚的地方,请告诉我。我可能无法帮助您找出异常的来源,但我可以给您一个示例,说明如何根据请求和查询字符串构建/重建URL 我有一个屏幕来显示记录列表。因为有很多,我需要支持过滤和分页。过滤器作为查询字符串放置,即,
?foo1=bar1&foo2=bar2
。分页也会在url上放置额外的页面大小和当前页码,即size=15&page=1
我没有使用GetDisplayUri()
,而是使用了UrlHelperExtensions
,它获取当前Url,检查Url查询字符串,并根据需要向Url添加其他查询字符串(页面大小和当前页面)
namespace DL.SO.Project.Framework.Mvc.Extensions
{
public static class UrlHelperExtensions
{
public static string Current(this IUrlHelper url, object routeValues)
{
// Get current route data
var currentRouteData = url.ActionContext.RouteData.Values;
// Get current route query string and add them back to the new route
// so that I can preserve them.
// For example, if the user applies filters, the url should have
// query strings '?foo1=bar1&foo2=bar2'. When you construct the
// pagination links, you don't want to take away those query
// strings.
var currentQuery = url.ActionContext.HttpContext.Request.Query;
foreach (var param in currentQuery)
{
currentRouteData[param.Key] = param.Value;
}
// Convert new route values to a dictionary
var newRouteData = new RouteValueDictionary(routeValues);
// Merge new route data
foreach (var item in newRouteData)
{
currentRouteData[item.Key] = item.Value;
}
return url.RouteUrl(currentRouteData);
}
}
}
为了进行分页,我需要跟踪当前页面大小、项目总数、当前页面、总页面、起始页面和结束页面。我为此创建了一个类,Pager.cs
namespace DL.SO.Project.Framework.Mvc.Paginations
{
public class Pager
{
public int TotalItems { get; private set; }
public int CurrentPage { get; private set; }
public int CurrentPageSize { get; private set; }
public int TotalPages { get; private set; }
public int StartPage { get; private set; }
public int EndPage { get; private set; }
public Pager(int totalItems, int currentPage = 1, int currentPageSize = 15)
{
currentPageSize = currentPageSize < 15
? 15
: currentPageSize;
// Calculate total, start and end pages
var totalPages = (int)Math.Ceiling(
(decimal)totalItems / (decimal)currentPageSize
);
currentPage = currentPage < 1
? 1
: currentPage;
// Only display +- 2
var startPage = currentPage - 2;
var endPage = currentPage + 2;
if (startPage <= 0)
{
endPage = endPage - startPage + 1;
startPage = 1;
}
if (endPage > totalPages)
{
endPage = totalPages;
if (endPage > 5)
{
startPage = endPage - 4;
}
}
this.TotalItems = totalItems;
this.CurrentPage = currentPage;
this.CurrentPageSize = currentPageSize;
this.TotalPages = totalPages;
this.StartPage = startPage;
this.EndPage = endPage;
}
}
}
通过这种方式,分页上的链接将反映到带有查询字符串的当前url,以及页面大小和当前页面。好的,经过大约一个小时的尝试和错误,我已经找到了哪些字段映射到url的哪个部分。一般形式是
url=[Scheme]://[Host][PathBase][Path][QueryString]
,它们都有关于如何连接它们的特定规则(例如,Path和PathBase必须以/
开头)
因此,在问题()的示例中http://example.com/route/endpoint?foo=bar“
),您的HttpRequest对象将需要以下字段
var request = class_implementing_HttpRequest() {
Scheme = "http",
Host = new HostString("example.com"),
PathBase = new PathString("/route"),
Path = new PathString("/endpoint"),
QueryString = new QueryString("?foo=bar")
}
这有点令人讨厌,因为GetDisplayUri
的实现是隐藏的。如果有人碰到这个问题,我希望能帮你省下一个小时的猜测和检查时间
编辑:正如David在其答案的评论中指出的,.NET Core是开源的,我可以从外观上找到答案。这是一个很好的信息,我感谢您的帮助。我正在为一个调用GetDislpayUri()的方法编写单元测试,但我实际上没有能力更改实现,所以我不能在这里真正使用它。哦,我明白了。由于.NETCore是开源的,您可以看看它们的实现吗?啊,不知道推广的方式是开源的。几小时前那就太好了。无论如何谢谢你!
var request = class_implementing_HttpRequest() {
Scheme = "http",
Host = new HostString("example.com"),
PathBase = new PathString("/route"),
Path = new PathString("/endpoint"),
QueryString = new QueryString("?foo=bar")
}