我有接口IInterface
和实现它的类Concrete
我有一个观点
@model IEnumerable<IInterface>
@for (int i = 0; i < Model.Count(); i++)
{
@Html.EditorFor(x => x[i])
}
<span id="result"></span>
编辑器模板Concrete.cshtml
@model Concrete
@Ajax.BeginForm("Action", new AjaxOptions { UpdateTargetId = "result" })
{
@Html.Hidden("ModelType", Model.GetType())
<input type="submit" />
}
采取行动:
public string Action(IInterface interface) { return "success"; }
和模型活页夹:
public class MyModelBinder : DefaultModelBinder
{
protected override CreateModel(
ControllerContext controllerContext,
ModelBindingContext bindingContext,
Type modelType)
{
var typeValue = bindingContext.ValueProvider.GetValue(
bindingContext.ModelName + ".ModelType"
);
...
我以前在ViewModel中使用了IInterface
并且它运行正常,但是,现在当我提交我的Ajax表单时bindingContext.ModelName
为空。
在调试器中检查ValueProvider
我可以看到它包含FormValueProvider
_values
的{{1}}包含密钥[0].Interface.ModelType
。
使用立即窗口我可以确认呼叫.GetValue("[0].Interface.ModelType")
会返回相应的typeValue
。
如何让bindingContext.ModelName
不为空,或者如何获取我需要的字符串"[0].Interface.ModelType"
?
答案 0 :(得分:0)
好的,我找到了一个令人满意的hacky解决方案:
var typeValue = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".ModelType");
if (typeValue == null)
{
var enumerable = (IEnumerable)bindingContext.ValueProvider;
var formValueProvider = enumerable.OfType<FormValueProvider>().Single();
var field = typeof(NameValueCollectionValueProvider).GetField(
"_values",
BindingFlags.NonPublic | BindingFlags.Instance
);
var dictionary = (IDictionary)field.GetValue(formValueProvider);
var keys = (IEnumerable<string>)dictionary.Keys;
var key = keys.FirstOrDefault(x => x.EndsWith(".ModelType"));
typeValue = bindingContext.ValueProvider.GetValue(key);
}