public class Student { [Key] public int Id { get; set; } // public string Name { get; set; } // public string Group { get; set; } // public short DefYear { get; set; } // public bool IsDefended { get; set; } }
public class StudentFilter : FilterModel<Student> { [FilterName("")] [InputType(InputTypeAttribute.InputTypies.TextBox)] public string Name { get; set; } [FilterName("")] [InputType(InputTypeAttribute.InputTypies.TextBox)] public string Group { get; set; } [FilterName(" ")] [InputType(InputTypeAttribute.InputTypies.DropDownList)] [SelectListProperty("DefYearList", "")] public short? DefYear { get; set; } [FilterName(" ")] [InputType(InputTypeAttribute.InputTypies.DropDownList)] [SelectListProperty("IsDefendedList", "")] public bool? IsDefended { get; set; } public SelectList DefYearList { get { return new SelectList(new List<short> { 2011, 2012 }, DefYear); } } public SelectList IsDefendedList { get { var list = new List<object> { {new {Id="true", Title=""}}, {new {Id="false", Title=" "}}, }; return new SelectList(list, "Id", "Title", IsDefended); } } public override Func<Student, bool> FilterExpression { get { return p => (String.IsNullOrEmpty(Name) || p.Name.IndexOf(Name) == 0) && (String.IsNullOrEmpty(Group) || p.Group.ToLower().IndexOf(Group.ToLower()) == 0) && (DefYear == null || p.DefYear == DefYear) && (IsDefended == null || (p.IsDefended == IsDefended)); } } public override void Reset() { Name = null; Group = null; DefYear = null; IsDefended = null; } }
var filters = IocContainer.Resolve<IFilterFactory>(); var students = DbContext.Students .Where(Filter.FilterExpression) .OrderBy(s => s.Name) .ToList();
.................. <h2></h2> @Html.FilterForm(Filters.Find<UserFilter>()) ..................
public abstract class FilterModel { [Dependency] public IUnityContainer IocContainer { get; set; } public abstract void Reset(); } public abstract class FilterModel<ModelType> : FilterModel { public abstract Func<ModelType, bool> FilterExpression { get; } }
public interface IFilterFactory { /// <summary> /// /// </summary> /// <typeparam name="TFilter"></typeparam> /// <returns></returns> TFilter Find<TFilter>() where TFilter : FilterModel; /// <summary> /// GUID /// </summary> /// <param name="guidString"></param> /// <returns></returns> FilterModel Find(String guidString); /// <summary> /// /// </summary> /// <param name="filter"></param> void Replace(FilterModel filter); /// <summary> /// /// </summary> /// <param name="guidString">guid </param> void Reset(String guidString); }
public class DefaultFilterFactory : IFilterFactory { protected List<object> Collection { get; private set; } [InjectionConstructor] public DefaultFilterFactory() { Collection = new List<object>(); } [Dependency] public IUnityContainer IocContainer { get; set; } /// <summary> /// /// </summary> /// <typeparam name="TFilter"> </typeparam> /// <returns></returns> public TFilter Find<TFilter>() where TFilter : FilterModel { try { return (TFilter)Collection.Single(f => f.GetType().FullName == typeof(TFilter).FullName); } catch { AddNew<TFilter>(); return Find<TFilter>(); } } /// <summary> /// GUID /// </summary> /// <param name="guidString"> GUID</param> /// <returns></returns> public FilterModel Find(String guidString) { return (FilterModel)Collection.Single(f => f.GetType().GUID.ToString() == guidString); } public void Replace(FilterModel filter) { try { var old = Collection.SingleOrDefault(f => f.GetType().FullName == filter.GetType().FullName); if (old != null) { if (!Collection.Remove(old)) throw new InvalidOperationException(" "); } } catch (InvalidOperationException) { throw; } catch { // } Collection.Add(filter); } /// <summary> /// /// </summary> /// <typeparam name="TFilter"> </typeparam> protected void AddNew<TFilter>() where TFilter : FilterModel { var filter = IocContainer.Resolve<TFilter>(); filter.Reset(); Collection.Add(filter); } /// <summary> /// GUID /// </summary> /// <param name="guidString"> GUID</param> /// <returns></returns> public void Reset(String guidString) { try { var filter = Find(guidString); filter.Reset(); } catch { // } } }
public class FilterBinder { /// <summary> /// , guid /// </summary> public static string TypeKey { get { return "_filter_type"; } } /// <summary> /// , /// , InputTypeAttribute /// </summary> public static Func<PropertyInfo, bool> IsFilterProperty { get { return p => p.GetCustomAttributes(true).Count(a => a.GetType() == typeof(InputTypeAttribute)) > 0; } } /// <summary> /// /// </summary> public HttpRequest Request { get; protected set; } /// <summary> /// Unity /// </summary> [Dependency] public IUnityContainer IocContainer { get; set; } /// <summary> /// /// </summary> public Type FilterType { get { return IocContainer.Resolve<IFilterFactory>().Find(Request[TypeKey]).GetType(); } } public FilterBinder() { Request = HttpContext.Current.Request; } /// <summary> /// /// </summary> /// <returns></returns> public FilterModel BindFilter() { var filter = (FilterModel)IocContainer.Resolve(FilterType); // , InputTypeAttribute foreach (var property in FilterType.GetProperties().Where(FilterBinder.IsFilterProperty)) { object value = null; // , , if (property.PropertyType == typeof(String)) { value = Request[property.Name]; } // , else { try { var parse = property.PropertyType.GetMethod("Parse", new Type[] { typeof(String) }) ?? property.PropertyType.GetProperty("Value").PropertyType.GetMethod("Parse", new Type[] { typeof(String) }); if (parse != null) value = parse.Invoke(null, new object[] { Request[property.Name] }); } catch { value = null; } } // property.SetValue(filter, value, null); } return filter; } }
public class _FilterController : ExpandController { public ActionResult SetFilter(string backUrl) { try { var filter = IocContainer.Resolve<FilterBinder>().BindFilter(); if (filter == null) { FlashMessanger.ErrorMessage = " "; return Redirect(backUrl); } Filters.Replace(filter); } catch { FlashMessanger.ErrorMessage = " : . , "; } return Redirect(backUrl); } public ActionResult Reset(string backUrl, string filter) { Filters.Reset(filter); return Redirect(backUrl); } }
/// <summary> /// , SelectList /// </summary> public class SelectListPropertyAttribute : Attribute { /// <summary> /// /// </summary> public string Property { get; set; } /// <summary> /// null /// </summary> public string OptionLabel { get; set; } public SelectListPropertyAttribute(string property) { Property = property; OptionLabel = String.Empty; } public SelectListPropertyAttribute(string property, string optionLabel) : this(property) { OptionLabel = optionLabel; } } /// <summary> /// /// /// </summary> public class InputTypeAttribute : Attribute { public enum InputTypies { TextBox, CheckBox, DropDownList } public InputTypies Type { get; set; } public InputTypeAttribute(InputTypies type) { Type = type; } } /// <summary> /// /// </summary> public class FilterNameAttribute : Attribute { public string Name { get; set; } public FilterNameAttribute(string name) { Name = name; } }
public static class Helpers { /// <summary> /// , /// </summary> private const string CONTROLLER_NAME = "_Filter"; /// <summary> /// /// </summary> private const string SET_ACTION_NAME = "SetFilter"; /// <summary> /// /// </summary> private const string RESET_ACTION_NAME = "Reset"; /// <summary> /// /// </summary> /// <returns></returns> public static IHtmlString FilterForm(this HtmlHelper helper, FilterModel filter, string controllerName = CONTROLLER_NAME, string setActionName = SET_ACTION_NAME, string resetActionName = RESET_ACTION_NAME) { var url = new UrlHelper(HttpContext.Current.Request.RequestContext, helper.RouteCollection); // url var hrefSet = url.Action(setActionName, controllerName, new { area = "", backUrl = HttpContext.Current.Request.Url }); var result = String.Format("<form action=\"{0}\" method=\"post\">\n\t<div class=\"filters\">", hrefSet); result += helper.Hidden(FilterBinder.TypeKey, filter.GetType().GUID.ToString()).ToString(); result += "<h3></h3>"; // , // Func<PropertyInfo, string> getFilterName = p => p.GetCustomAttributes(typeof(FilterNameAttribute), true).Any() ? ((FilterNameAttribute)p.GetCustomAttributes(typeof(FilterNameAttribute), true).Single()).Name : p.Name; // , SelectList Func<PropertyInfo, PropertyInfo> getSelectListProperty = p => !p.GetCustomAttributes(typeof(SelectListPropertyAttribute), true).Any() ? null : p.DeclaringType.GetProperty( ((SelectListPropertyAttribute)p.GetCustomAttributes(typeof(SelectListPropertyAttribute), true).Single()).Property, typeof(SelectList) ); // Func<PropertyInfo, string> getSelectListOptionLabel = p => !p.GetCustomAttributes(typeof(SelectListPropertyAttribute), true).Any() ? null : ((SelectListPropertyAttribute)p.GetCustomAttributes(typeof(SelectListPropertyAttribute), true).Single()).OptionLabel; // , InputTypeAttribute foreach (var property in filter.GetType().GetProperties().Where(FilterBinder.IsFilterProperty)) { result += "\n\t\t<div class=\"filter_item\">"; result += "\n\t\t\t<span>" + getFilterName(property) + "</span>"; // , var type = (InputTypeAttribute)property.GetCustomAttributes(typeof(InputTypeAttribute), true).Single(); // html switch (type.Type) { case InputTypeAttribute.InputTypies.TextBox: result += helper.TextBox(property.Name, property.GetValue(filter, null)).ToString(); break; case InputTypeAttribute.InputTypies.CheckBox: result += helper.CheckBox(property.Name, property.GetValue(filter, null)).ToString(); break; case InputTypeAttribute.InputTypies.DropDownList: var selectList = getSelectListProperty(property) != null ? (SelectList)getSelectListProperty(property).GetValue(filter, null) : new SelectList(new List<object>()); result += String.IsNullOrEmpty(getSelectListOptionLabel(property)) ? helper.DropDownList(property.Name, selectList) : helper.DropDownList(property.Name, selectList, getSelectListOptionLabel(property)); break; } result += "\n\t\t</div>"; } result += "\n\t\t<div class=\"clear\"></div>"; result += String.Format( @"<input type='image' src='{0}' /><a href='{1}'><img src='{2}' alt='' /></a>", url.Content("~/Content/images/button_apply.png"), url.Action(resetActionName, controllerName, new { area = "", backUrl = HttpContext.Current.Request.Url, filter = filter.GetType().GUID }), url.Content("~/Content/images/button_cancel.png") ); return helper.Raw(result + "\n\t</div>\n</form>"); } }
public abstract class FilterModel<ModelType> : FilterModel { public abstract Func<ModelType, bool> FilterExpression { get; } }
public abstract class FilterModel<ModelType> : FilterModel { public abstract Expression<Func<ModelType, bool>> FilterExpression { get; } }
Source: https://habr.com/ru/post/141440/
All Articles