Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么即使属性已设置且有效,TryUpdateModel仍返回false?_C#_Asp.net_Asp.net Mvc 3_Entity Framework_Data Annotations - Fatal编程技术网

C# 为什么即使属性已设置且有效,TryUpdateModel仍返回false?

C# 为什么即使属性已设置且有效,TryUpdateModel仍返回false?,c#,asp.net,asp.net-mvc-3,entity-framework,data-annotations,C#,Asp.net,Asp.net Mvc 3,Entity Framework,Data Annotations,我有一个基于ASP.NETMVC3的web应用程序。我需要一个“创建”视图,在用户从下拉列表中选择要创建的子类型之前,该视图不会知道模型类型。为了解决这个问题,我在Shared/EditorTemplates下为每个派生模型类型创建了一个编辑器模板。这允许我创建一个“create.cs”,它是视图模型的强类型。视图模型只有两个成员,一个枚举和一个复杂类型。其思想是,视图最初仅显示一个下拉列表(枚举成员的编辑器),然后当用户最初提交指定的“模型类型”(下拉选择值)时,POST操作可以检查“模型类型

我有一个基于ASP.NETMVC3的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
{ ... }
我有一个复杂的视图模型如下

public enum MyModelType_e
{
    DerivedType1 = 0,
    DerivedType2 = 1,
    DerivedType3 = 2
}

public class MyModelCreate
{
    public MyModelType_e ModelTypeForSelectList { get; set; }
    public MyModelBase ModelBase { get; set; }
}
My GET controller操作为视图实例化上述视图模型,即,仅显示一个下拉列表,其中包含基于MyModelType_e enum+的项。模型的“ModelBase”属性的值最初为空。所以GET操作方法看起来像这样

[HttpGet]
public ActionResult Create()
{
    return View(new MyModelCreate());
}
请注意下面caps bellow中关于我的问题症结所在的评论,即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...)
}
[HttpPost]
公共操作结果创建(MyModelCreate模型)
{
如果(model.ModelBase==null | |
(int)model.ModelTypeForSelectList!=model.ModelBase.ModelType)
{
开关(model.ModelType)
{
案例MyModelType_e.DerivedType1:
model.ModelBase=新的DerivedType1();
打破
案例MyModelType_e.DerivedType2:
model.ModelBase=新的DerivedType2();
打破
案例MyModelType_e.DerivedType3:
model.ModelBase=新的DerivedType3();
打破
}
返回视图(模型);
}
如果(!TryUpdateModel(model.ModelBase))
返回视图(模型);//model.ModelType)
@* 
有条件地显示正确的编辑器模板。。。
在../Shared/EditorTemplates下,每个文件都有一个
派生类型(DerivedType1、DerivedType2、DerivedType3等)
在正确的编辑器字段
根据用户在上述下拉列表中选择的内容显示。
*@
@if(Model.InputModel!=null)
{  
@EditorFor(model=>model.ModelBase);
}

}
因此,一旦使用了初始POST(选择了模型类型),我的POST操作方法就会通过设计转到TryUpdateModel行,但由于某些原因,验证失败。我真正不明白的是,验证摘要报告“Name is required”,尽管我可以清楚地看到TryUpdateModel在视图模型的ModelBase成员上正确地设置了Name属性

我非常感谢这里的任何帮助或指导。。。我对ASP.NET MVC还相当陌生,我乐于以不同的方式做事,因为我知道可能还有其他方法可以设计我的请求/操作+视图来完成这个“多步骤”问题,但我只想做最简单的事情,我为什么喜欢EditorTemplate方法来处理派生模型类型,等等


提前感谢…

我的解决方案基本上包括增加两个额外的控制器操作(GET和POST)。我在../Shared/EditorTemplates下创建了单独的视图,这些视图是强类型的(每个派生模型类型对应一个视图)。这样,初始的“创建”POST操作仅接收所选类型(模型只是指定所需类型的枚举值),然后重定向到另一个控制器操作,如“CreateByType”,该操作获取请求的具体类型的新实例并返回正确的编辑视图。附加的“CreateByType”控制器操作(GET和POST)只需要处理抽象基,因为它从服务层请求实例(传递枚举值)。然后我所要做的就是在每个具体类型的EditorTemplates下创建一个视图。

我的解决方案基本上包括增加两个额外的控制器操作(GET和POST)。我在../Shared/EditorTemplates下创建了单独的视图,这些视图是强类型的(每个派生模型类型对应一个视图)。这样,初始的“创建”POST操作仅接收所选类型(模型只是指定所需类型的枚举值),然后重定向到另一个控制器操作,如“CreateByType”,该操作获取请求的具体类型的新实例并返回正确的编辑视图。附加的“CreateByType”控制器操作(GET和POST)只需要处理抽象基,因为它从服务层请求实例(传递枚举值)。然后我所要做的就是在EditorTemplates下为每个具体类型创建一个视图。

检查
ModelState
。运行
TryUpdateModel
后应该会设置错误。
我不得不从一些属性中删除
必需的
属性。

检查
ModelState
。运行
TryUpdateModel
后应该会设置错误。
我不得不从一些属性中删除
Required
属性。

在您的
MyModelCreate
类中,您似乎使用了一些未显示的
MyModelBase
类型。你能给我看一下它的定义吗?达林,谢谢你抓住它。。。我错误地重命名了一些内容(修复了上次编辑的问题)。实际上,我最近已经解决了这个问题,但还没有找到时间发布我自己的答案:(在你的
MyModelCreate
类中,你似乎使用了一些你没有显示的
MyModelBase
类型。你能
 @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>
}