Skip to content

Instantly share code, notes, and snippets.

@szalapski
Last active January 13, 2023 04:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save szalapski/98639062f14af3126cf8e7f990d549d2 to your computer and use it in GitHub Desktop.
Save szalapski/98639062f14af3126cf8e7f990d549d2 to your computer and use it in GitHub Desktop.
@inject NavigationManager navigationManager
...
@code {
// example code to change state based on the querystring.
// Call perhaps from an event callback or whenever the query may have changed.
private void LoadFromQuery()
{
Uri uri = navigationManager.ToAbsoluteUri(navigationManager.Uri);
Dictionary<string, StringValues> query = ParseQuery(uri.Query);
var keys = query.Keys.ToArray();
foreach (string key in keys)
{
if (key == "section")
{
string sectionValue = query.TryGet(key);
ShowSection(sectionValue)
}
else
{
...
}
}
}
/// <summary>
/// Parse a query string into its component key and value parts.
/// </summary>
/// <param name="queryString">The raw query string value, with or without the leading '?'.</param>
/// <returns>A collection of parsed keys and values.</returns>
public static Dictionary<string, StringValues> ParseQuery(string queryString)
{
var result = ParseNullableQuery(queryString);
if (result == null)
{
return new Dictionary<string, StringValues>();
}
return result;
}
/// <summary>
/// Parse a query string into its component key and value parts.
/// </summary>
/// <param name="queryString">The raw query string value, with or without the leading '?'.</param>
/// <returns>A collection of parsed keys and values, null if there are no entries.</returns>
public static Dictionary<string, StringValues> ParseNullableQuery(string queryString)
{
var accumulator = new KeyValueAccumulator();
if (string.IsNullOrEmpty(queryString) || queryString == "?")
{
return null;
}
int scanIndex = 0;
if (queryString[0] == '?')
{
scanIndex = 1;
}
int textLength = queryString.Length;
int equalIndex = queryString.IndexOf('=');
if (equalIndex == -1)
{
equalIndex = textLength;
}
while (scanIndex < textLength)
{
int delimiterIndex = queryString.IndexOf('&', scanIndex);
if (delimiterIndex == -1)
{
delimiterIndex = textLength;
}
if (equalIndex < delimiterIndex)
{
while (scanIndex != equalIndex && char.IsWhiteSpace(queryString[scanIndex]))
{
++scanIndex;
}
string name = queryString.Substring(scanIndex, equalIndex - scanIndex);
string value = queryString.Substring(equalIndex + 1, delimiterIndex - equalIndex - 1);
accumulator.Append(
Uri.UnescapeDataString(name.Replace('+', ' ')),
Uri.UnescapeDataString(value.Replace('+', ' ')));
equalIndex = queryString.IndexOf('=', delimiterIndex);
if (equalIndex == -1)
{
equalIndex = textLength;
}
}
else
{
if (delimiterIndex > scanIndex)
{
accumulator.Append(queryString.Substring(scanIndex, delimiterIndex - scanIndex), string.Empty);
}
}
scanIndex = delimiterIndex + 1;
}
if (!accumulator.HasValues)
{
return null;
}
return accumulator.GetResults();
}
public static class NavigationExtensions {
/// <summary>
/// Navigates to the current URI, but with a different query string.
/// </summary>
public static void NavigateToQuery(this NavigationManager navigationManager, QueryString newQueryString) =>
navigationManager.NavigateTo(navigationManager.Uri.WithQuery(newQueryString));
/// <summary>
/// Returns a copy of a string URL with its query string replaced with a new one.
/// </summary>
private static string WithQuery(this string url, QueryString newQueryString) =>
new UriBuilder(url) { Query = newQueryString.ToString() }.ToString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment