这是我想要实现的主要问题.所以问题的基本介绍如下:
1-我有一个视图模型(作为示例),它为视图侧的过滤器操作创建.
public class Filterviewmodel { public string FilterParameter { get; set; } }
2-我有一个控制器动作,为GETting表单值创建(这里是过滤器)
public ActionResult Index(Filterviewmodel filter) { return View(); }
3-我有一个看法,用户可以过滤一些数据,并通过表单提交的查询字符串发送参数.
@using (Html.BeginForm("Index","Demo",FormMethod.Get)) { @Html.LabelFor(model => model.FilterParameter) @Html.EditorFor(model => model.FilterParameter) <input type="submit" value="Do Filter" /> }
4-在渲染视图输出中我想看到的是
<form action="/Demo" method="get"> <label for="fp">FilterParameter</label> <input id="fp" name="fp" type="text" /> <input type="submit" value="Do Filter" /> </form>
public class Filterviewmodel { [BindParameter("fp")] [BindParameter("filter")] // this one extra alias [BindParameter("param")] //this one extra alias public string FilterParameter { get; set; } }
所以基本的问题是关于BindAttribute,但复杂类型属性的使用.而且如果有这样做的内在方式好多了.
内置专业:
使用TextBoxFor,EditorFor,LabelFor和其他强类型视图模型助手可以更好地理解和沟通彼此.
2-网址路由支持
3-没有框架设计问题:
In general,we recommend folks don’t write custom model binders
because they’re difficult to get right and they’re rarely needed. The
issue I’m discussing in this post might be one of those cases where
it’s warranted.
而且经过一些研究,我发现这些有用的作品:
Binding model property with different name
One step upgrade of first link
结果:但他们没有给我我的问题确切的解决方案.我正在寻找一个强类型的解决方案来解决这个问题.当然,如果您知道其他任何方式,请分享.
更新
我想这样做的根本原因基本是:
1-每次我想更改html控件名称,那么我必须在编译时更改PropertyName. (有一个区别在更改代码中的字符串之间更改属性名称)
2-我想从最终用户隐藏(伪装)不动产名称.大部分时间View Model属性名称与映射的Entity Objects属性名称相同. (由于开发人员可读性原因)
3-我不想删除开发人员的可读性.想想很多属性,像2-3个字符长和mo意思.
4-有很多视图模型.所以改变他们的名字将比这个解决方案花费更多的时间.
这将是更好的解决方案(在我的POV)比直到现在其他问题描述的其他.
解决方法
但是我之前做过的回答(我删除了)是昨天才意识到的一个可怕的解决方案.我要把它放在github里,还有谁还想看(也许解决某个人的问题)(我也不建议)
现在我再次搜索,找不到任何帮助.如果您正在使用类似AutoMapper或ValueInjecter的工具来将viewmodel对象映射到Business对象,并且还要模糊该View Model参数,那么可能您遇到了麻烦.当然,你可以做到这一点,但强类型的html助手不会帮你很多.我甚至没有谈论其他开发人员如何分支和工作在常见的视图模型.
幸运的是,我的项目(4人工作,它的商业用途)不是那么大,所以我决定改变View Model的属性名称! (还有很多工作要做)数百个模型来模糊他们的属性!!!)谢谢Asp.Net MVC!
有些方法在我提出的链接.但是,如果您还想使用BindAlias属性,我只能建议您使用以下扩展方法.至少你不必写在BindAlias属性中写的相同的别名字符串.
这里是:
public static string AliasNameFor<TModel,TProperty>(this HtmlHelper<TModel> htmlHelper,Expression<Func<TModel,TProperty>> expression) { var memberExpression = ExpressionHelpers.GetMemberExpression(expression); if (memberExpression == null) throw new InvalidOperationException("Expression must be a member expression"); var aliasAttr = memberExpression.Member.GetAttribute<BindAliasAttribute>(); if (aliasAttr != null) { return MvcHtmlString.Create(aliasAttr.Alias).ToHtmlString(); } return htmlHelper.NameFor(expression).ToHtmlString(); } public static string AliasIdFor<TModel,TProperty>> expression) { var memberExpression = ExpressionHelpers.GetMemberExpression(expression); if (memberExpression == null) throw new InvalidOperationException("Expression must be a member expression"); var aliasAttr = memberExpression.Member.GetAttribute<BindAliasAttribute>(); if (aliasAttr != null) { return MvcHtmlString.Create(TagBuilder.CreateSanitizedId(aliasAttr.Alias)).ToHtmlString(); } return htmlHelper.IdFor(expression).ToHtmlString(); } public static T GetAttribute<T>(this ICustomAttributeProvider provider) where T : Attribute { var attributes = provider.GetCustomAttributes(typeof(T),true); return attributes.Length > 0 ? attributes[0] as T : null; } public static MemberExpression GetMemberExpression<TModel,TProperty>(Expression<Func<TModel,TProperty>> expression) { MemberExpression memberExpression; if (expression.Body is UnaryExpression) { var unaryExpression = (UnaryExpression)expression.Body; memberExpression = (MemberExpression)unaryExpression.Operand; } else { memberExpression = (MemberExpression)expression.Body; } return memberExpression; }
当你想使用它:
[ModelBinder(typeof(AliasModelBinder))] public class Filterviewmodel { [BindAlias("someText")] public string FilterParameter { get; set; } }
在html中:
@* at least you dont write "someText" here again *@ @Html.Editor(Html.AliasNameFor(model => model.FilterParameter)) @Html.ValidationMessage(Html.AliasNameFor(model => model.FilterParameter))
所以我这样回答这个问题.这甚至不是一个答案(而且MVC 5没有答案),但是在谷歌搜索同样的问题的人可能会发现这个经验很有用.
这里是github回购:https://github.com/yusufuzun/so-view-model-bind-20869735