#195: Implementing filter model validation and handling invalid from/to date values.

This commit is contained in:
Sipke Schoorstra
2014-07-23 22:59:34 -07:00
parent da4397c1cd
commit 3ee4712222
7 changed files with 54 additions and 16 deletions

View File

@@ -1,14 +1,18 @@
using System.Linq;
using System.Web.Mvc;
using Orchard.AuditTrail.Models;
using Orchard.AuditTrail.Services;
using Orchard.AuditTrail.Services.Models;
using Orchard.AuditTrail.ViewModels;
using Orchard.Collections;
using Orchard.ContentManagement;
using Orchard.Localization;
using Orchard.Localization.Services;
using Orchard.Security;
using Orchard.UI.Navigation;
namespace Orchard.AuditTrail.Controllers {
public class AdminController : Controller {
public class AdminController : Controller, IUpdateModel {
private readonly IAuthorizer _authorizer;
private readonly IAuditTrailManager _auditTrailManager;
private readonly IOrchardServices _services;
@@ -31,8 +35,14 @@ namespace Orchard.AuditTrail.Controllers {
return new HttpUnauthorizedResult();
var pager = new Pager(_services.WorkContext.CurrentSite, pagerParameters);
var filters = Filters.From(Request.QueryString);
var filters = Filters.From(Request.QueryString, this);
var pageOfData = _auditTrailManager.GetRecords(pager.Page, pager.PageSize, filters, orderBy ?? AuditTrailOrderBy.DateDescending);
// If there's a filter validation error, clear the results.
if (!ModelState.IsValid) {
pageOfData = new PageOfItems<AuditTrailEventRecord>(Enumerable.Empty<AuditTrailEventRecord>());
}
var pagerShape = New.Pager(pager).TotalItemCount(pageOfData.TotalItemCount);
var filterDisplay = _auditTrailManager.BuildFilterDisplay(filters);
var eventDescriptorsQuery =
@@ -75,5 +85,13 @@ namespace Orchard.AuditTrail.Controllers {
};
return View(viewModel);
}
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
return TryUpdateModel(model, prefix, includeProperties, excludeProperties);
}
void IUpdateModel.AddModelError(string key, LocalizedString errorMessage) {
ModelState.AddModelError(key, errorMessage.Text);
}
}
}

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Orchard.AuditTrail.Models;
using Orchard.AuditTrail.Providers.Content;
using Orchard.AuditTrail.Services;
@@ -45,12 +46,14 @@ namespace Orchard.AuditTrail.Drivers {
if (settings.ShowAuditTrail) {
results.Add(ContentShape("Parts_AuditTrail", () => {
var pager = new Pager(_services.WorkContext.CurrentSite, null, null);
var pageOfData = _auditTrailManager.GetRecords(pager.Page, pager.PageSize, ContentAuditTrailEventProvider.CreateFilters(part.Id));
var pageOfData = _auditTrailManager.GetRecords(pager.Page, pager.PageSize, ContentAuditTrailEventProvider.CreateFilters(part.Id, updater));
var pagerShape = shapeHelper.Pager(pager).TotalItemCount(pageOfData.TotalItemCount);
var eventDescriptors = from c in _auditTrailManager.DescribeCategories()
var eventDescriptors =
from c in _auditTrailManager.DescribeCategories()
from e in c.Events
select e;
var recordViewModels = from record in pageOfData
var recordViewModels =
from record in pageOfData
let descriptor = eventDescriptors.FirstOrDefault(x => x.Event == record.FullEventName)
where descriptor != null
select new AuditTrailEventSummaryViewModel {
@@ -59,6 +62,7 @@ namespace Orchard.AuditTrail.Drivers {
CategoryDescriptor = descriptor.CategoryDescriptor,
SummaryShape = _displayBuilder.BuildDisplay(record, "SummaryAdmin")
};
return shapeHelper.Parts_AuditTrail(Records: recordViewModels, Pager: pagerShape);
}));
}

View File

@@ -18,8 +18,8 @@ namespace Orchard.AuditTrail.Providers.Content {
public const string Unpublished = "Unpublished";
public const string Removed = "Removed";
public static Filters CreateFilters(int contentId) {
return new Filters {
public static Filters CreateFilters(int contentId, IUpdateModel updateModel) {
return new Filters(updateModel) {
{"content", contentId.ToString(CultureInfo.InvariantCulture)}
};
}

View File

@@ -57,7 +57,6 @@ namespace Orchard.AuditTrail.Services {
var query = _auditTrailRepository.Table;
if (filters != null) {
var filterContext = new QueryFilterContext(query, filters);

View File

@@ -17,13 +17,9 @@ namespace Orchard.AuditTrail.Services {
public override void Filter(QueryFilterContext context) {
var userName = context.Filters.Get("username");
var fromDate = context.Filters.Get("from.Date");
var fromTime = context.Filters.Get("from.Time");
var toDate = context.Filters.Get("to.Date");
var toTime = context.Filters.Get("to.Time");
var category = context.Filters.Get("category");
var from = _dateServices.ConvertFromLocalString(fromDate, fromTime).Earliest();
var to = _dateServices.ConvertFromLocalString(toDate, toTime).Latest();
var from = GetDateFromFilter(context.Filters, "From", "from").Earliest();
var to = GetDateFromFilter(context.Filters, "To", "to").Latest();
var query = context.Query;
if (!String.IsNullOrWhiteSpace(userName)) {
@@ -59,5 +55,17 @@ namespace Orchard.AuditTrail.Services {
context.FilterDisplay.Add(categoryFilterDisplay);
context.FilterDisplay.Add(userNameFilterDisplay);
}
private DateTime? GetDateFromFilter(Filters filters, string fieldName, string prefix) {
try {
var dateString = filters.Get(prefix + ".Date");
var timeString = filters.Get(prefix + ".Time");
return _dateServices.ConvertFromLocalString(dateString, timeString);
}
catch (FormatException ex) {
filters.UpdateModel.AddModelError(prefix, T(@"Error parsing ""{0}"" date: {1}", fieldName, ex.Message));
return null;
}
}
}
}

View File

@@ -1,10 +1,18 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using Orchard.ContentManagement;
namespace Orchard.AuditTrail.Services.Models {
public class Filters : Dictionary<string, string> {
public static Filters From(NameValueCollection nameValues) {
var filters = new Filters();
public Filters(IUpdateModel updateModel) {
UpdateModel = updateModel;
}
public IUpdateModel UpdateModel { get; set; }
public static Filters From(NameValueCollection nameValues, IUpdateModel updateModel) {
var filters = new Filters(updateModel);
foreach (string nameValue in nameValues) {
filters.Add(nameValue, nameValues[nameValue]);

View File

@@ -12,6 +12,7 @@
Layout.Title = T("Audit Trail");
}
@Html.ValidationSummary()
@using (Html.BeginForm("Index", "Admin", new { area = "Orchard.AuditTrail" }, FormMethod.Get)) {
<section class="audittrail-filter-section">
@Display(Model.FilterDisplay)