Skip to content

Instantly share code, notes, and snippets.

@bariloce
Created July 15, 2014 09:26
Show Gist options
  • Save bariloce/1275b8864c5d9ef541fa to your computer and use it in GitHub Desktop.
Save bariloce/1275b8864c5d9ef541fa to your computer and use it in GitHub Desktop.
Nancy Dictionary<string, customClass> binding
//necessary to call custom binding (method Create in my model)
public class BindingExtensions : IModelBinder
{
public object Bind(NancyContext context, Type modelType, object instance, BindingConfig configuration, params string[] blackList)
{
var data = GetDataFields(context);
var model = QueryHistoryConfigurationModel.Create(data);
return model;
}
static IDictionary<string, object> GetDataFields(NancyContext context)
{
return Merge(new IDictionary<string, string>[]
{
ConvertDynamicDictionary(context.Request.Form),
ConvertDynamicDictionary(context.Request.Query),
ConvertDynamicDictionary(context.Parameters)
});
}
static IDictionary<string, object> Merge(IEnumerable<IDictionary<string, string>> dictionaries)
{
var output = new Dictionary<string, object>(StringComparer.InvariantCultureIgnoreCase);
foreach (var dictionary in dictionaries.Where(d => d != null))
foreach (var kvp in dictionary)
if (!output.ContainsKey(kvp.Key))
output.Add(kvp.Key, kvp.Value);
return output;
}
static IDictionary<string, string> ConvertDynamicDictionary(DynamicDictionary dictionary)
{
return dictionary.GetDynamicMemberNames().ToDictionary(
memberName => memberName,
memberName => (string)dictionary[memberName]);
}
public bool CanBind(Type modelType)
{
return modelType == typeof(QueryHistoryConfigurationModel);
}
}
public class AdministrationModule : NancyModule
{
public AdministrationModule() : base("/administration")
{
Post["/queryhistory"] = _ => QueryHistoryAdministrationPost();
}
dynamic QueryHistoryAdministrationPost()
{
//bind back data to my model
var model = this.Bind<QueryHistoryConfigurationModel>();
return View["QueryHistory", model];
}
}
public class QueryHistoryColumnConfigurationModel
{
public bool IsVisible { get; set; }
public string Format { get; set; }
public int Ordering { get; set; }
}
public class QueryHistoryConfigurationModel
{
public QueryHistoryConfigurationModel()
{
Configuration = new Dictionary<string, QueryHistoryColumnConfigurationModel>();
}
public Dictionary<string, QueryHistoryColumnConfigurationModel> Configuration { get; set; }
//binding method - do it manually
public static QueryHistoryConfigurationModel Create(IDictionary<string, object> data)
{
var dict = new Dictionary<string, QueryHistoryColumnConfigurationModel>();
for(var i = 0; i < data.Count / 4; i++)
{
object key;
data.TryGetValue(String.Format("key_{0}", i), out key);
object isVisible;
object format;
object ordering;
data.TryGetValue(String.Format("isVisible_{0}", i), out isVisible);
data.TryGetValue(String.Format("format_{0}", i), out format);
data.TryGetValue(String.Format("ordering_{0}", i), out ordering);
dict.Add(key.ToString(),
new QueryHistoryColumnConfigurationModel
{
Format = format.ToString(),
Ordering = int.Parse(ordering.ToString()),
IsVisible = bool.Parse(isVisible.ToString().Split(',')[0]) //because of checkbox
});
}
return new QueryHistoryConfigurationModel { Configuration = dict };
}
}
@inherits NancyRazorViewBase<QueryHistoryConfigurationModel>
<form method="post">
<table class="table table-hover">
<thead>
<tr>
<th></th>
<th>IsVisible</th>
<th>Format</th>
<th>Ordering</th>
</tr>
</thead>
<tbody>
@{var i = 0;}
@foreach (var item in Model.Configuration)
{
<tr>
<td><input type="hidden" value="@item.Key" name="key_@i" />@item.Key</td>
<td>
<input type="checkbox" value="@item.Value.IsVisible" name="isVisible_@i" checked="@item.Value.IsVisible" />
<input type="hidden" value="false" name="isVisible_@i" />
</td>
<td><input type="text" value="@item.Value.Format" name="format_@i" /></td>
<td><input type="number" value="@item.Value.Ordering" name="ordering_@i" /></td>
</tr>
i++;
}
<tr>
<td colspan="4">
<input type="submit" class="btn btn-primary" value="Save" />
</td>
</tr>
</tbody>
</table>
</form>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment