102 lines
3.1 KiB
C#
102 lines
3.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Web.Mvc;
|
|
using Portoa.Web;
|
|
|
|
namespace VideoGameQuotes.Web.Models {
|
|
public class ApiModel {
|
|
public ApiModel() {
|
|
Criteria = new Dictionary<string, IEnumerable<object>>();
|
|
}
|
|
|
|
public bool FetchAll { get; set; }
|
|
public int Id { get; set; }
|
|
public SortMethod SortMethod { get; set; }
|
|
public SortOrder SortOrder { get; set; }
|
|
public IDictionary<string, IEnumerable<object>> Criteria { get; set; }
|
|
}
|
|
|
|
public class ApiModelBinder : IModelBinder {
|
|
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
|
|
var model = new ApiModel {
|
|
SortMethod = SortMethod.None,
|
|
SortOrder = SortOrder.Ascending
|
|
};
|
|
|
|
ParseId(controllerContext, model);
|
|
ParseSort(controllerContext, model);
|
|
ParseCriteria(controllerContext, model);
|
|
|
|
return model;
|
|
}
|
|
|
|
private static void ParseCriteria(ControllerContext controllerContext, ApiModel model) {
|
|
var criteria = (controllerContext.RouteData.Values["criteria"] ?? string.Empty).ToString().Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
for (var i = 0; i < criteria.Length; i++) {
|
|
switch (criteria[i]) {
|
|
default:
|
|
if (i < criteria.Length - 1) {
|
|
model.Criteria[criteria[i]] = ParseCommaSeparatedCriterion(criteria[i + 1]);
|
|
i++;
|
|
} else {
|
|
controllerContext.AddModelError("criteria", "Unable to parse criteria for key \"system\"");
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
private static IEnumerable<object> ParseCommaSeparatedCriterion(string csv) {
|
|
var values = csv.Split(',');
|
|
var results = new List<object>();
|
|
foreach (var value in values) {
|
|
int result;
|
|
if (int.TryParse(value, out result)) {
|
|
results.Add(result);
|
|
} else {
|
|
results.Add(value);
|
|
}
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
private static void ParseSort(ControllerContext controllerContext, ApiModel model) {
|
|
var sortValue = controllerContext.HttpContext.Request.QueryString["sort"];
|
|
if (string.IsNullOrWhiteSpace(sortValue)) {
|
|
return;
|
|
}
|
|
|
|
var sortValues = sortValue.Split('|');
|
|
try {
|
|
model.SortMethod = (SortMethod)Enum.Parse(typeof(SortMethod), sortValues[0], ignoreCase: true);
|
|
} catch {
|
|
controllerContext.AddModelError("sort", string.Format("The sort method \"{0}\" is invalid", sortValues[0]));
|
|
}
|
|
if (sortValues.Length > 1) {
|
|
try {
|
|
model.SortOrder = (SortOrder)Enum.Parse(typeof(SortOrder), sortValues[1], ignoreCase: true);
|
|
} catch {
|
|
controllerContext.AddModelError("sort", string.Format("The sort order \"{0}\" is invalid", sortValues[1]));
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void ParseId(ControllerContext controllerContext, ApiModel model) {
|
|
var idValue = (controllerContext.RouteData.Values["id"] ?? string.Empty).ToString();
|
|
int id;
|
|
if (int.TryParse(idValue, out id)) {
|
|
if (id <= 0) {
|
|
controllerContext.AddModelError("id", "Invalid value for id");
|
|
} else {
|
|
model.Id = id;
|
|
}
|
|
} else {
|
|
model.FetchAll = idValue == "all";
|
|
}
|
|
}
|
|
}
|
|
} |