我有一个双视图我的申请,这两个显示用于我的模型的项目之一相同的编辑器模板;这两种视图(“添加”和“编辑”),“编辑”工作正常,但“添加”为模型返回null当我控制器操作处理后。

我发现,如果我给“添加”查看自定义视图模型,并呼吁Html.EditorFor(p => p.PageContent)而不是简单地对整个模型调用EditorFor()对象 - Html.EditorFor(p => p),然后形式返回正确的,非空模型,但其产生属于我的客户端脚本和控件ID其他问题(如现在所有的领域都与“PageContent_”为前缀)。我使用的是相同的编辑模板技术在整个我的应用几个不同的地方,并没有其他人都表现出一个ViewModel这个奇怪的依赖。

有没有其他人经历过类似的问题?

修改视图

<%@ Page Title="" Language="C#" MasterPageFile="~/Areas/Admin/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<PageContent>" %>

<% using (Html.BeginForm())
   { %>
<%=Html.Hidden("PageID", Model.Page.ID) %>
<%=Html.EditorFor(p => p)%>
<input type="submit" name="btnSave" value="Save" />
<input type="submit" name="btnCancel" value="Cancel" class="cancel" />
<% }

<强>动作(工作)

[HttpPost, ValidateInput(false)]
public ActionResult EditContent(int id, FormCollection formCollection) {}

添加视图

<%@ Page Title="" Language="C#" MasterPageFile="~/Areas/Admin/Views/Shared/Site.Master"
Inherits="System.Web.Mvc.ViewPage<PageContent>" %>

<% using (Html.BeginForm())
   { %>
<%=Html.Hidden("PageID", ViewData["PageID"]) %>
<%=Html.EditorFor(p => p)%>
<input type="submit" name="btnSave" value="Save" />
<input type="submit" name="btnCancel" value="Cancel" class="cancel" />
<% } %>

<强>动作(失败)

// content is ALWAYS null
[HttpPost, ValidateInput(false)]
public ActionResult AddContent(PageContent content, FormCollection formCollection) {}

之前你哭 “复制”

此问题确实与这一个,但这个问题旨在针对我遇到,而不是要求有更普遍的问题,具体的问题。

有帮助吗?

解决方案

我找到了问题所在,这是一个相当有趣的一个。

当的DefaultModelBinder尝试解析模型项的它的第一件事是检查以查看是否有在数据被绑定任何前缀字段;它通过检查与模型对象的名称开头的任何形式的项目(这似乎的非常随意的,如果你问我)。如果找到任何“为前缀”字段则它导致被调用不同的结合逻辑。

<强> ASP.NET MVC 2预览2 BindModel()来源

public virtual object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) {
    if (bindingContext == null) {
        throw new ArgumentNullException("bindingContext");
    }
    bool performedFallback = false;
    if (!String.IsNullOrEmpty(bindingContext.ModelName) && !DictionaryHelpers.DoesAnyKeyHavePrefix(bindingContext.ValueProvider, bindingContext.ModelName)) {
        // We couldn't find any entry that began with the prefix. If this is the top-level element, fall back
        // to the empty prefix.
        if (bindingContext.FallbackToEmptyPrefix) {
             /* omitted for brevity */
            };
            performedFallback = true;
        }
        else {
            return null;
        }
    }

    // Simple model = int, string, etc.; determined by calling TypeConverter.CanConvertFrom(typeof(string))
    // or by seeing if a value in the request exactly matches the name of the model we're binding.
    // Complex type = everything else.
    if (!performedFallback) {
       /* omitted for brevity */
    }
    if (!bindingContext.ModelMetadata.IsComplexType) {
        return null;
    }
    return BindComplexModel(controllerContext, bindingContext);
}

我定义来处理添加操作控制器动作定义被称为“内容”一PageContent项和在我的域PageContent有一个称为“内容”的“匹配”与“内容”的型号名称属性从而导致DefaultModelBinder到假设我有一个预先指定的值时,实际上它只是PageContent的成员。通过改变签名 -

发件人:

[HttpPost, ValidateInput(false)]
public ActionResult AddContent(PageContent content, FormCollection formCollection) {}

[HttpPost, ValidateInput(false)]
public ActionResult AddContent(PageContent pageContent, FormCollection formCollection) {}

在DefaultModelBinder再一次能够正确地绑定到我的PageContent模型项目。我不知道为什么编辑观点也没显示此行为,但无论哪种方式,我已经找到了问题的根源。

在我看来,这个问题属于非常接近“错误”状态。这是有道理的,我的观点与视图模型开始工作,因为“内容”是越来越有“PageContent_”为前缀,但像这样的核心框架的特性/错误不应该是没有得到解决恕我直言。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top