Skip to content

Commit

Permalink
#218 - Refactor query string parsing into a service class.
Browse files Browse the repository at this point in the history
  • Loading branch information
maraf committed Mar 7, 2019
1 parent b399d7a commit d384a02
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 26 deletions.
31 changes: 5 additions & 26 deletions src/Money.UI.Blazor/Pages/Account/Login.cshtml.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Blazor.Components;
using Microsoft.AspNetCore.Blazor.Services;
using Money.Services;
using Neptuo.Collections.Specialized;
using System;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -18,7 +19,7 @@ public class LoginBase : BlazorComponent
internal ApiClient ApiClient { get; set; }

[Inject]
internal IUriHelper Uri { get; set; }
internal QueryString QueryString { get; set; }

[Parameter]
protected string ReturnUrl { get; set; }
Expand All @@ -32,29 +33,7 @@ public class LoginBase : BlazorComponent
protected override void OnParametersSet()
{
base.OnParametersSet();
SetReturnUrl();
}

private void SetReturnUrl()
{
string url = Uri.GetAbsoluteUri();
int indexOfQuery = url.IndexOf('?');
if (indexOfQuery >= 0)
{
string query = url.Substring(indexOfQuery + 1).ToLowerInvariant();
string[] parameters = query.Split('&');
foreach (string parameter in parameters)
{
string[] keyValue = parameter.Split('=');
if (keyValue[0] == "returnurl")
{
if (keyValue.Length == 2)
ReturnUrl = keyValue[1];

break;
}
}
}
ReturnUrl = QueryString.Find<string>("returnUrl");
}

protected Task OnSubmitAsync()
Expand All @@ -71,8 +50,8 @@ private async Task LoginAsync(string userName, string password, bool isPermanent
{
if (!await ApiClient.LoginAsync(userName, password, isPermanent))
ErrorMessages.Add("User name and password don't match.");
else if (ReturnUrl != null)
Uri.NavigateTo(ReturnUrl);
else if (!String.IsNullOrEmpty(ReturnUrl))
Navigator.Open(ReturnUrl);
else
Navigator.OpenSummary();
}
Expand Down
3 changes: 3 additions & 0 deletions src/Money.UI.Blazor/Services/Navigator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ private void OnLocationChanged(object sender, string e)
private void OpenExternal(string url)
=> Interop.NavigateTo(url);

public void Open(string url)
=> uri.NavigateTo(url);

public void OpenSummary()
=> uri.NavigateTo(UrlSummary());

Expand Down
76 changes: 76 additions & 0 deletions src/Money.UI.Blazor/Services/QueryString.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using Microsoft.AspNetCore.Blazor.Services;
using Neptuo;
using Neptuo.Collections.Specialized;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Money.Services
{
/// <summary>
/// A current parsed query string provider.
/// </summary>
public class QueryString : DisposableBase, IReadOnlyKeyValueCollection
{
private readonly IUriHelper uri;
private KeyValueCollection parameters;

public QueryString(IUriHelper uri)
{
Ensure.NotNull(uri, "uri");
this.uri = uri;

uri.OnLocationChanged += OnLocationChanged;
}

private void OnLocationChanged(object sender, string e)
=> parameters = null;

private void EnsureParameters()
{
if (parameters == null)
{
parameters = new KeyValueCollection();

string url = uri.GetAbsoluteUri();
int indexOfQuery = url.IndexOf('?');
if (indexOfQuery >= 0)
{
string query = url.Substring(indexOfQuery + 1).ToLowerInvariant();
string[] items = query.Split('&');
foreach (string parameter in items)
{
string[] keyValue = parameter.Split('=');
if (keyValue.Length == 2)
parameters.Add(keyValue[0], keyValue[1]);
else
parameters.Add(keyValue[0], null);
}
}
}
}

public IEnumerable<string> Keys
{
get
{
EnsureParameters();
return parameters.Keys;
}
}

public bool TryGet<T>(string key, out T value)
{
EnsureParameters();
return parameters.TryGet(key?.ToLowerInvariant(), out value);
}

protected override void DisposeManagedResources()
{
base.DisposeManagedResources();
uri.OnLocationChanged -= OnLocationChanged;
}
}
}
1 change: 1 addition & 0 deletions src/Money.UI.Blazor/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public void ConfigureServices(IServiceCollection services)
services
.AddTransient<Navigator>()
.AddTransient<ApiClient>()
.AddSingleton<QueryString>()
.AddSingleton<CommandMapper>()
.AddSingleton<QueryMapper>()
.AddSingleton<ColorCollection>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,25 @@ public static T Get<T>(this IReadOnlyKeyValueCollection collection, string key,
return defaultValue;
}

/// <summary>
/// Reads the value of <paramref name="key"/> in <paramref name="collection"/>.
/// If value is found and can be converted to <typeparamref name="T"/>, returns it.
/// Otherwise the default value of <typeparamref name="T"/> is returned.
/// </summary>
/// <param name="collection">Collection of key-value pairs.</param>
/// <param name="key">Requested key.</param>
/// <returns>Value of <paramref name="key"/> in <paramref name="collection"/>.</returns>
public static T Find<T>(this IReadOnlyKeyValueCollection collection, string key)
{
Ensure.NotNull(collection, "collection");

T value;
if (collection.TryGet(key, out value))
return value;

return default(T);
}

/// <summary>
/// Returns <c>true</c> if <paramref name="collection"/> contains <paramref name="key"/>.
/// </summary>
Expand Down

0 comments on commit d384a02

Please sign in to comment.