Skip to content

Commit

Permalink
Smooth out parameter handling #93
Browse files Browse the repository at this point in the history
  • Loading branch information
programcsharp committed Sep 16, 2018
1 parent 1063ba4 commit b6522e3
Show file tree
Hide file tree
Showing 28 changed files with 458 additions and 69 deletions.
4 changes: 2 additions & 2 deletions Build/CommonAssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("2.5.1")]
[assembly: AssemblyFileVersion("2.5.1")]
[assembly: AssemblyVersion("2.6.0")]
[assembly: AssemblyFileVersion("2.6.0")]
//[assembly: AssemblyInformationalVersion("2.5-filters")]
1 change: 1 addition & 0 deletions Build/Griddly.Core.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<dependency id="CsvHelper" version="2.4.0" />
<dependency id="Dapper" version="1.50.2" />
<dependency id="EPPlus" version="3.1.3.3" />
<dependency id="Newtonsoft.Json" version="11.0.2" />
</group>
</dependencies>
</metadata>
Expand Down
6 changes: 6 additions & 0 deletions Griddly.Mvc/Griddly.Mvc.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
<Private>True</Private>
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
Expand Down Expand Up @@ -91,10 +94,13 @@
</Compile>
<Compile Include="DynamicLinq.cs" />
<Compile Include="Exceptions\DapperGriddlyException.cs" />
<Compile Include="GriddlyContext.cs" />
<Compile Include="GriddlyCookieFilterValueProvider.cs" />
<Compile Include="GriddlyFilterExtensions.cs" />
<Compile Include="GriddlyHtmlFilter.cs" />
<Compile Include="GriddlyExport.cs" />
<Compile Include="GriddlyFilterBarSettings.cs" />
<Compile Include="GriddlyParameterAttribute.cs" />
<Compile Include="InternalExtensions.cs" />
<Compile Include="GriddlyButton.cs" />
<Compile Include="GriddlyColumn.cs" />
Expand Down
27 changes: 27 additions & 0 deletions Griddly.Mvc/GriddlyContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Griddly.Mvc
{
public class GriddlyContext
{
public string Name { get; set; }
public string ParentPath { get; set; }
public bool IsDefaultSkipped { get; set; }

public GriddlyFilterCookieData CookieData { get; set; }

public string CookieName => "gf_" + Name;

public Dictionary<string, object> Defaults { get; set; } = new Dictionary<string, object>();
public Dictionary<string, object> Parameters { get; set; } = new Dictionary<string, object>();
}

public class GriddlyFilterCookieData
{
public Dictionary<string, string[]> Values { get; set; }
}
}
72 changes: 72 additions & 0 deletions Griddly.Mvc/GriddlyCookieFilterValueProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace Griddly.Mvc
{
public class GriddlyCookieFilterValueProvider : IValueProvider
{
GriddlyFilterCookieData _data;

public GriddlyCookieFilterValueProvider(GriddlyFilterCookieData data)
{
_data = data;
}

public bool ContainsPrefix(string prefix)
{
return _data.Values?.ContainsKey(prefix) == true;
}

public ValueProviderResult GetValue(string key)
{
string[] value = null;

if (_data.Values?.TryGetValue(key, out value) != true)
value = null;

string attemptedValue = null;

if (value != null)
attemptedValue = string.Join(",", value);

return new ValueProviderResult(value, attemptedValue, CultureInfo.CurrentCulture);
}
}

public class GriddlyCookieFilterValueProviderFactory : ValueProviderFactory
{
public override IValueProvider GetValueProvider(ControllerContext controllerContext)
{
if (controllerContext.IsChildAction && controllerContext.HttpContext.Request.QueryString.Count == 0)
{
var context = controllerContext.Controller.GetOrCreateGriddlyContext();
var cookie = controllerContext.HttpContext.Request.Cookies[context.CookieName];

if (cookie != null && !string.IsNullOrWhiteSpace(cookie.Value))
{
try
{
var data = JsonConvert.DeserializeObject<GriddlyFilterCookieData>(cookie.Value);

context.CookieData = data;
context.IsDefaultSkipped = true;

return new GriddlyCookieFilterValueProvider(data);
}
catch
{
// TODO: log it?
}
}
}

return null;
}
}
}
119 changes: 76 additions & 43 deletions Griddly.Mvc/GriddlyExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -158,89 +158,122 @@ public static IHtmlString ToHtmlAttributes(this IDictionary<string, object> dict
return new HtmlString(sb.ToString());
}

public static void SetGriddlyDefault<T>(this Controller controller, ref T parameter, string field, T value)
static readonly string _contextKey = "_griddlycontext";

public static void SetGriddlyDefault<T>(this ControllerBase controller, ref T parameter, string field, T value)
{
if (controller.ControllerContext.IsChildAction)
var context = controller.ViewData[_contextKey] as GriddlyContext;

if (context != null)
{
if (EqualityComparer<T>.Default.Equals(parameter, default(T)))
context.Defaults[field] = value;

if (controller.ControllerContext.IsChildAction
&& !context.IsDefaultSkipped
&& EqualityComparer<T>.Default.Equals(parameter, default(T)))
{
parameter = value;

controller.ViewData["_griddlyDefault_" + field] = parameter;
context.Parameters[field] = value;
}
}
else
controller.ViewData["_griddlyDefault_" + field] = value;
}

public static void SetGriddlyDefault<T>(this Controller controller, ref T[] parameter, string field, IEnumerable<T> value)
public static void SetGriddlyDefault<T>(this ControllerBase controller, ref T[] parameter, string field, IEnumerable<T> value)
{
if (controller.ControllerContext.IsChildAction)
var context = controller.ViewData[_contextKey] as GriddlyContext;

if (context != null)
{
if (parameter == null)
parameter = value.ToArray();
context.Defaults[field] = value;

controller.ViewData["_griddlyDefault_" + field] = parameter;
if (controller.ControllerContext.IsChildAction
&& !context.IsDefaultSkipped
&& parameter == null)
{
parameter = value.ToArray();
}
}
else
controller.ViewData["_griddlyDefault_" + field] = value;
}

public static void SetGriddlyDefault<T>(this Controller controller, ref T?[] parameter, string field, IEnumerable<T> value)
public static void SetGriddlyDefault<T>(this ControllerBase controller, ref T?[] parameter, string field, IEnumerable<T> value)
where T : struct
{
if (controller.ControllerContext.IsChildAction)
var context = controller.ViewData[_contextKey] as GriddlyContext;

if (context != null)
{
if (parameter == null)
parameter = value.Cast<T?>().ToArray();
context.Defaults[field] = value;

controller.ViewData["_griddlyDefault_" + field] = parameter;
if (controller.ControllerContext.IsChildAction
&& !context.IsDefaultSkipped
&& parameter == null)
{
parameter = value.Cast<T?>().ToArray();
}
}
else
controller.ViewData["_griddlyDefault_" + field] = value;
}

public static object GetGriddlyDefault(this WebViewPage page, string field)
public static object GetGriddlyParameter(this WebViewPage page, string field)
{
return page.ViewData["_griddlyDefault_" + field];
}
object value = null;

public static void ForceGriddlyDefault(this Controller controller, string field, object value)
{
controller.ViewData["_griddlyDefault_" + field] = value;
if ((page.ViewData[_contextKey] as GriddlyContext)?.Parameters.TryGetValue(field, out value) != true)
value = null;

return value;
}

public static Dictionary<string, object> GetGriddlyDefaults(this WebViewPage page)
{
Dictionary<string, object> defaults = new Dictionary<string, object>();
var context = page.ViewData[_contextKey] as GriddlyContext;

foreach (var key in page.ViewData.Keys.Where(k => k.StartsWith("_griddlyDefault_")))
if (context != null)
{
var value = page.ViewData[key];
string stringValue = null;

Type t = null;

if (value != null)
// TODO: is there any reason to make a new dict vs using the same one? nobody else uses it, right?
foreach (var pair in context.Defaults)
{
t = value.GetType();
var value = pair.Value;

if (t.IsArray)
{
t = t.GetElementType();
if (value != null)
{
Type t = value.GetType();

if (t.IsArray)
{
t = t.GetElementType();

if ((Nullable.GetUnderlyingType(t) ?? t).IsEnum)
value = ((Array)value).Cast<object>().Select(x => x?.ToString()).ToArray();
if ((Nullable.GetUnderlyingType(t) ?? t).IsEnum)
value = ((Array)value).Cast<object>().Select(x => x?.ToString()).ToArray();
}
}

if (stringValue == null)
stringValue = value.ToString();
defaults[pair.Key] = value;
}

defaults[key.Substring("_griddlyDefault_".Length)] = value;
}

return defaults;
}

public static GriddlyContext GetOrCreateGriddlyContext(this ControllerBase controller)
{
var context = controller.ViewData[_contextKey] as GriddlyContext;

if (context == null)
{
context = new GriddlyContext()
{
Name = (controller.GetType().Name + "_" + controller.ControllerContext.RouteData.GetRequiredString("action")).ToLower()
};

// NOTE: for 2020 Chris... yes, this is unique for multiple griddlies on a page as it is in the grid action context of each one
controller.ViewData[_contextKey] = context;
}

return context;
}

static IDictionary<string, object> ObjectToDictionary(object value)
{
if (value == null)
Expand Down
Loading

0 comments on commit b6522e3

Please sign in to comment.