vgquotes/Src/VideoGameQuotes.Web/Models/ApiModel.cs

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";
}
}
}
}