// Raw URI including query string with multiple parameters
var rawurl = "https://bencull.com/some/path?key1=val1&key2=val2&key2=valdouble&key3=";
// Parse URI, and grab everything except the query string.
var uri = new Uri(rawurl);
var baseUri = uri.GetComponents(UriComponents.Scheme | UriComponents.Host | UriComponents.Port | UriComponents.Path, UriFormat.UriEscaped);
// Grab just the query string part
var query = QueryHelpers.ParseQuery(uri.Query);
// Convert the StringValues into a list of KeyValue Pairs to make it easier to manipulate
var items = query.SelectMany(x => x.Value, (col, value) => new KeyValuePair<string, string>(col.Key, value)).ToList();
// At this point you can remove items if you want
items.RemoveAll(x => x.Key == "key3"); // Remove all values for key
items.RemoveAll(x => x.Key == "key2" && x.Value == "val2"); // Remove specific value for key
// Use the QueryBuilder to add in new items in a safe way (handles multiples and empty values)
var qb = new QueryBuilder(items);
qb.Add("nonce", "testingnonce");
qb.Add("payerId", "pyr_");
// Reconstruct the original URL with new query string
var fullUri = baseUri + qb.ToQueryString();
/// <summary>
/// Gets the query value collection parsed from owin.RequestQueryString.
/// </summary>
/// <returns>The query value collection parsed from owin.RequestQueryString.</returns>
public abstract IReadableStringCollection Query { get; }
public static string AddOrReplaceQueryParameter(this HttpContext c, params string[] nameValues)
{
if (nameValues.Length%2!=0)
{
throw new Exception("nameValues: has more parameters then values or more values then parameters");
}
var qps = new Dictionary<string, StringValues>();
for (int i = 0; i < nameValues.Length; i+=2)
{
qps.Add(nameValues[i], nameValues[i + 1]);
}
return c.AddOrReplaceQueryParameters(qps);
}
public static string AddOrReplaceQueryParameters(this HttpContext c, Dictionary<string,StringValues> pvs)
{
var request = c.Request;
UriBuilder uriBuilder = new UriBuilder
{
Scheme = request.Scheme,
Host = request.Host.Host,
Port = request.Host.Port ?? 0,
Path = request.Path.ToString(),
Query = request.QueryString.ToString()
};
var queryParams = QueryHelpers.ParseQuery(uriBuilder.Query);
foreach (var (p,v) in pvs)
{
queryParams.Remove(p);
queryParams.Add(p, v);
}
uriBuilder.Query = "";
var allQPs = queryParams.ToDictionary(k => k.Key, k => k.Value.ToString());
var url = QueryHelpers.AddQueryString(uriBuilder.ToString(),allQPs);
return url;
}
下一个和上一个链接,例如视图中的链接:
var next = Context.Request.HttpContext.AddOrReplaceQueryParameter("page",Model.PageIndex+1+"");
var prev = Context.Request.HttpContext.AddOrReplaceQueryParameter("page",Model.PageIndex-1+"");
7条答案
按热度按时间ljsrvy3e1#
如果您使用的是ASP.NETCore1或2,则可以使用Microsoft.AspNetCore.WebUtilities包中的
Microsoft.AspNetCore.WebUtilities.QueryHelpers
执行此操作。如果您使用的是ASP.NETCore3.0或更高版本,则
WebUtilities
现在是ASP .NETSDK的一部分,不需要单独的nuget包引用。要将其解析到字典中,请执行以下操作:
请注意,与System.Web中的
ParseQueryString
不同,它在ASP.NET Core 1.x中返回IDictionary<string, string[]>
类型的字典,在ASP.NET Core 2.x或更高版本中返回IDictionary<string, StringValues>
类型的字典,因此该值是字符串的集合。这就是字典处理具有相同名称的多个查询字符串参数的方式。如果要在查询字符串上添加参数,可以在
QueryHelpers
上使用另一种方法:使用.net core 2.2,您可以使用
您将获得一个键:值对的集合-如下所示
k4aesqcs2#
获取绝对URI并仅使用ASP.NET核心包操作其查询字符串的最简单和最直观的方法可以通过几个简单的步骤完成:
安装软件包
PM> Install-Package Microsoft.AspNetCore.WebUtilities
PM> Install-Package Microsoft.AspNetCore.Http.Extensions
重要课程
为了指出它们,下面是我们将使用的两个重要类:一个一个二个一个三个一个四个一个。
代码
要了解最新的变化,你可以在这里查看我的博客文章:http://benjii.me/2017/04/parse-modify-query-strings-asp-net-core/
dsekswqp3#
HttpRequest
具有Query
属性,该属性通过IReadableStringCollection
接口公开解析的查询字符串:GitHub上的This discussion也指向它。
7gyucuyw4#
此函数返回
Dictionary<string, string>
,但不使用Microsoft.xxx
以实现兼容性接受两端的参数编码
接受重复键(返回最后一个值)
tzcvj98z5#
值得注意的是,在最上面的答案被标记为正确之后,
Microsoft.AspNetCore.WebUtilities
进行了一次主要版本更新(从1.x.x到2.x.x)。也就是说,如果您正在针对
netcoreapp1.1
进行构建,则需要运行以下命令,该命令将安装最新的受支持版本1.1.2
:Install-Package Microsoft.AspNetCore.WebUtilities -Version 1.1.2
rhfm7lfc6#
我用这个作为扩展方法,可以使用任意数量的参数:
下一个和上一个链接,例如视图中的链接:
unguejic7#
我不知道它是在什么时候添加的,但早在.NET Core 3.1
HttpUtility.ParseQueryString
可用并内置到标准的.NETMicrosoft.NETCore.App
框架中时,我就可以从类库中访问它,而不需要额外的NuGet包或特殊的dll引用。我已经用.NET Core 3.1、.NET 6和.NET 7测试过它。
这种方法的优点是,如果您正在建置可能在ASP.NET内容之外使用的程式库,则不需要指涉任何Web程式库,因为这会增加项目的负担。
...当然,如果您在ASP.NET核心应用程序中需要它,
Microsoft.AspNetCore.WebUtilities
类是完全有效的。