bli*_*ins 2 c# asp.net entity-framework data-annotations asp.net-mvc-3
我有基于 ASP.Net MVC3 的 Web 应用程序。我需要一个“创建”视图,在用户从下拉列表中选择要创建的子类型之前,该视图不会知道模型类型。为了尝试解决此问题,我在 Shared/EditorTemplates 下为每个派生模型类型创建了一个编辑器模板。这允许我创建一个对视图模型强类型的“Create.cs”。视图模型只有两个成员,一个枚举和一个复杂类型。这个想法是,视图最初仅显示一个下拉列表(枚举成员的编辑器),然后当用户最初提交指定的“模型类型”(下拉选择的值)时,POST 操作可以检查“模型类型” " 为视图模型的单个复杂成员指定并实例化正确的派生模型类型,该成员的类型是所有可能的“模型类型”的基本类型。
抽象+派生类型模型对象...
public abstract class MyModelBase
{
    public MyModelType_e ModelType {get; set; }
    [Required]
    public string Name { get; set; }
}
public class DerivedType1 : MyModelBase
{ ... }
public class DerivedType2 : MyModelBase
{ ... }
public class DerivedType3 : MyModelBase
{ ... }
Run Code Online (Sandbox Code Playgroud)
我有一个复杂的视图模型如下......
public enum MyModelType_e
{
    DerivedType1 = 0,
    DerivedType2 = 1,
    DerivedType3 = 2
}
public class MyModelCreate
{
    public MyModelType_e ModelTypeForSelectList { get; set; }
    public MyModelBase ModelBase { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我的 GET 控制器操作实例化了视图的上述视图模型,即,仅显示一个下拉列表,其中包含基于 MyModelType_e 枚举的项目 + 模型的“ModelBase”属性的值最初为 null。所以 GET 操作方法看起来像这样......
[HttpGet]
public ActionResult Create()
{
    return View(new MyModelCreate());
}
Run Code Online (Sandbox Code Playgroud)
请注意下面大写字母中关于我的问题的关键的评论,即 TryUpdateModel 失败(见下文),即使它将 ModelBase(派生类型)成员的属性按预期设置为相应的表单值...
[HttpPost]
public ActionResult Create(MyModelCreate model)
{
    if (model.ModelBase == null || 
        (int)model.ModelTypeForSelectList != model.ModelBase.ModelType)
    {
        switch (model.ModelType)
        {
            case MyModelType_e.DerivedType1:
                model.ModelBase = new DerivedType1();
                break;
            case MyModelType_e.DerivedType2:
                model.ModelBase = new DerivedType2();
                break;
            case MyModelType_e.DerivedType3:
                model.ModelBase = new DerivedType3();
                break;
        }
        return View(model);
    }
    if (!TryUpdateModel(model.ModelBase))
        return View(model); // <<< THIS HAPPENS EVEN THOUGH ModelBase APPEARS TO BE UPDATED PROPERLY... 
    // For instance, I can see right here with intellisense that model.ModelBase.Name
    // is NOT null or empty but rather is truly updated with the correct form value(s)...
    // TODO: Insert the record, etc... (currently we never get here...)
}
Run Code Online (Sandbox Code Playgroud)
所以上面的部分是问题的根源,但这是我的观点,以帮助理解......
 @model MyNamespace.MyModelCreate
 <h2>Create</h2>
 ...
 @using (Html.BeginForm())
 {
     @Html.ValidationSummary(false)
    <fieldset>
    <legend>Input</legend>
    <div class="editor-label">
    @Html.Label("Select Model Type")
    </div>
    <div>
    @Html.EnumDropDownListFor(model => model.ModelType)
    @Html.ValidationMessageFor(model => model.ModelType)
    </div>
    @* 
    Conditionally show the correct editor template... 
    There is one existing under ../Shared/EditorTemplates for each
    derived type (DerivedType1, DerivedType2, DerivedType3, etc...)
    This much is working in the sense that the correct editor fields
    are displayed based on what the user selects in the above drop-down.
    *@
    @if (Model.InputModel != null)
    {  
        @Html.EditorFor(model => model.ModelBase);
    }
    <p>
        <input type="submit" value="Continue" />
    </p>              
    </fieldset>
}
Run Code Online (Sandbox Code Playgroud)
因此,一旦进行初始 POST(选择模型类型),我的 POST 操作方法就会按设计落入 TryUpdateModel 行,但由于某种原因验证失败。我真正不明白的部分是,验证摘要报告“需要名称”,即使我可以清楚地看到 TryUpdateModel 在视图模型的 ModelBase 成员上正确设置了名称属性。
我非常感谢这里的任何帮助或指导...我对 ASP.NET MVC 相当陌生,并且我愿意以不同的方式做事,因为我知道可能还有其他方法可以设计我的请求/操作 + 视图来完成此任务“多步骤”问题,但我真的只是追求最简单的可能的事情,这就是为什么我喜欢使用 EditorTemplate 方法来处理派生模型类型等。
提前致谢...
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           2974 次  |  
        
|   最近记录:  |