ASP.NET MVC 4财产为重命名发布 [英] ASP.NET MVC 4 property-renaming for posting
问题描述
Follwing公约(多个)中给出。每个动作
有一个类型的单个参数 BaseRequest
与视动作数据
。在视图模型
始终类型的 BaseResponse
。
我想要做的是,如果一个查看
包含一个表单,在 POST
清议需要某种 BaseRequest
的。
我怎样才能获得正确的模型作为结合的视图模型
是 BaseResponse
?
我已经尝试过在 XYZResponse
添加 XYZRequest
属性,所以我可以绑定像
@ Html.ChecBoxFor(M = GT; m.RequestObject.SomeBooleanProperty)
但这样会产生名称
RequestObject.SomeBooleanProperty将不能正确绑定到后操作其接受 XYZRequest
。
有什么完全错误的用这种公约的还是我失去了一些东西?
更新#1
我也尝试创建一个新的临时
类型的对象 XYZRequest
并绑定到它像
@ Html.CheckBoxFor(M = TM preq.SomeBooleanProperty)
这会使一个名称
tmp.SomeBooleanProperty
中也无法绑定。
更新#2 - 附加信息
以下结构被设置。
-
BaseRequest
是摘要
-
GetOverviewRequest
:BaseRequest
-
GetOverviewRequest
有类型的属性字符串
,INT
或任何其他复杂类型,甚至列表
或字典
如果在 GetOverviewResponse
,从 BaseResponse
继承,给出回查看
并提供了一个命名属性的 利人
类型 GetOverviewRequest
绑定失败为
@ Html.TextBoxFor(M = GT; m.TheProperty.SomeBooleanValue)
将尝试绑定到利人
-property在 GetOverviewRequest
对象,只是不存在。
这如果 GetOverviewRequest
有一个名为利人属性可能会工作
绑定。但是,如果它的名称不同,结合也会失败。
我只希望像
<输入名称=SomeBooleanValue>
<输入名称=SomeComplexType.SomeStringValue>
而不是
<输入名称=TheProperty.SomeBooleanValue>
<输入名称=TheProperty.SomeComplexType.SomeStringValue>
更新#3 - 增加示例项目
通过dropbox.com [装订(preFIX = GetOverviewResponse.NameOf(M = GT; m.TheProperty))]
将是真正真棒。也许某种自定义的属性?由于BindAttribute是密封的,没有机会创建一个从这个继承。
任何想法?
正如评论指出,我创造了一些新的结构来实现我所需要的。
我创建了一个新的类 BaseRequestWrapperResponse< TRequest>
封装请求
-object在响应
公共抽象类BaseRequestWrapperResponse< TRequest> :BaseResponse哪里TRequest:IRequestFromResponse
本类有目前一个属性:
公共TRequest请求{搞定;组; }
接下来我创建了一个接口:
公共接口IRequestFromResponse
从我 Requset
-object将继承 - >将用于结合
在我的自定义ModelBinder的覆盖保护覆盖对象CreateModel
我检查如果(modelType.GetInterfaces()。包含(typeof运算(IRequestFromResponse)))
来看看我的请求
需求特殊处理。如果是这样我创建 BindAttribute
动态和之前设置是正常
粘结剂将完成剩下的:
VAR bindAttribute =新BindAttribute {preFIX = getPropertyName方法< BaseRequestWrapperResponse< IRequestFromResponse>中IRequestFromResponse>(R = GT; r.Request)};
TypeDescriptor.AddAttributes(modelType,bindAttribute);
在这里getPropertyName方法定义:
私有静态字符串getPropertyName方法< TSource,TProperty>(防爆pression<&Func键LT; TSource,TProperty>> propertyLambda)
{
VAR成员=(MemberEx pression)propertyLambda.Body;
返回member.Member.Name;
}
另请参阅:获取的属性名称抽象泛型类
Follwing convention(s) are given. Each Action
has a single parameter of type BaseRequest
with data depending on the Action
. The ViewModel
is always of type BaseResponse
.
What I'm trying to do is, that if a View
contains a form, the POST
-Action requires some sort of BaseRequest
.
How can I achieve correct-model binding as of the ViewModel
is BaseResponse
?
I already tried to add a property of XYZRequest
in XYZResponse
so I could bind like
@Html.ChecBoxFor(m => m.RequestObject.SomeBooleanProperty)
but this will generate name
RequestObject.SomeBooleanProperty which will not bind correctly to the POST-Action which accepts the XYZRequest
.
Is there something completely wrong with this kind of conventions or am I missing something?
Update #1
I also tried creating a new temporary
object of type XYZRequest
and bind to it like
@Html.CheckBoxFor(m = tmpReq.SomeBooleanProperty)
which will render a name
of tmp.SomeBooleanProperty
which also could not be bound.
Update #2 - additional information
Following structure is set.
BaseRequest
isabstract
GetOverviewRequest
:BaseRequest
GetOverviewRequest
has properties of typestring
,int
or any other complex type and evenLists
orDictionaries
If the GetOverviewResponse
, which inherits from BaseResponse
, is given back to the View
and provides a property named TheProperty
of type GetOverviewRequest
binding fails as of
@Html.TextBoxFor(m => m.TheProperty.SomeBooleanValue)
will try to bind to TheProperty
-property in the GetOverviewRequest
object, which just not exists.
This may would work if GetOverviewRequest
has a property called TheProperty
to bind. But if it is named differently, binding will also fail.
I just want something like
<input name="SomeBooleanValue">
<input name="SomeComplexType.SomeStringValue">
instead of
<input name="TheProperty.SomeBooleanValue">
<input name="TheProperty.SomeComplexType.SomeStringValue">
Update #3 - added sample project
Sample project via dropbox.com
Update #4 - explanation, why solution from @StephenMuecke is not working
As mentioned in comments, the solution in other question needs to know the name of the property in the GetOverviewResponse
-object. The property is named TheProperty
, therefore I have to add [Bind(Prefix = "TheProperty)]
to enable correct binding. I really don't like magic strings. And "TheProperty"
is a magic string. If one changes the name of the TheProperty
to RenamedProperty
, the whole binding will fail.
So. I'm now looking for a way to set the prefix some-kind dynamically.
[Bind(Prefix = GetOverviewResponse.NameOf(m => m.TheProperty))]
would be really awesome. Maybe some kind of a custom attribute? As of BindAttribute is sealed, there is no chance to create one inherited from this.
Any ideas?
As stated by comments I've created some new structure to achieve what I needed.
I created a new class BaseRequestWrapperResponse<TRequest>
to encapsulate the Request
-object in a Response
public abstract class BaseRequestWrapperResponse<TRequest> : BaseResponse where TRequest : IRequestFromResponse
This class has currently one property:
public TRequest Request { get; set; }
Next I've created an interface:
public interface IRequestFromResponse
from which my Requset
-object will inherit -> will be used for binding.
In my custom modelbinder override of protected override object CreateModel
I check if (modelType.GetInterfaces().Contains(typeof(IRequestFromResponse)))
to see if my Request
needs special handling. If so I create the BindAttribute
dynamically and set it before the normal
binder will do the rest:
var bindAttribute = new BindAttribute {Prefix = GetPropertyName<BaseRequestWrapperResponse<IRequestFromResponse>, IRequestFromResponse>(r => r.Request)};
TypeDescriptor.AddAttributes(modelType, bindAttribute);
where GetPropertyName is defined:
private static string GetPropertyName<TSource, TProperty>(Expression<Func<TSource, TProperty>> propertyLambda)
{
var member = (MemberExpression)propertyLambda.Body;
return member.Member.Name;
}
See also: Get name of property in abstract generic class
这篇关于ASP.NET MVC 4财产为重命名发布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!