72

当我尝试在 Asp.Net MVC 2 中使用 Create 样式操作创建实体时,就会发生这种情况。

POCO 具有以下属性:

public int Id {get;set;}

[Required]
public string Message {get; set}

在创建实体时,会自动设置 Id,因此在 Create 操作中不需要它。

ModelState 说“需要 Id 字段”,但我还没有这样设置。这里有什么自动发生的吗?

编辑 - 原因揭晓

Brad Wilson 通过 Paul Speranza 在下面的评论之一中回答了这个问题的原因,他说(为 Paul 欢呼):

你为 ID 提供了一个值,你只是不知道你是。它在默认路由(“{controller}/{action}/{id}”)的路由数据中,默认值为空字符串,对int无效。使用操作参数上的 [Bind] 属性来排除 ID。我的默认路由是:new { controller = "Customer", action = "Edit", id = " " } // 参数默认值

编辑 - 更新模型技术

实际上,我通过使用 TryUpdateModel 和与之关联的排除参数数组再次更改了执行此操作的方式。

    [HttpPost]
    public ActionResult Add(Venue collection)
    {
        Venue venue = new Venue();
        if (TryUpdateModel(venue, null, null, new[] { "Id" }))
        {
            _service.Add(venue);
            return RedirectToAction("Index", "Manage");
        }
        return View(collection);
    }
4

16 回答 16

90

您可以添加属性:

 [Bind(Exclude = "Id")] 

在方法中的参数而不是类上,这样在创建时您可以将其排除在外,在编辑时它仍然是强制性的:

public ActionResult Create([Bind(Exclude = "Id")] User u)
{
    // will exclude for create
}

public ActionResult Edit(User u)
{
    // will require for edit
}
于 2010-01-27T04:45:20.920 回答
18

我遇到了这个问题,我在其中动态地将“对象”添加到列表中。因此,我们的用户能够添加、删除或更新。除了创建新项目的情况外,一切都运行良好。出于这个原因,就我而言,排除 Id 属性不是一个选项解决方案是使 ID Nullable

public int? Id { get; set; }

这样,现有项目将具有值,而新项目将具有 null 值。好东西。

于 2012-11-15T04:30:09.477 回答
11

很好的问题和答案,拯救了我的……落后。不过,我需要添加一些东西:

代替

[Bind(Exclude = "Id")]

我认为最好使用

[Bind(Include = "Prop1, Prop2, Prop3, etc")]

.. 其中 Prop1、Prop2 和 Prop3 是您希望在操作级别绑定的唯一属性。

因为这是白名单而不是黑名单。白名单更好,更安全。这样,您还可以解决过度发布和发布不足的风险。请参阅布拉德威尔逊的帖子

于 2010-06-14T21:37:53.883 回答
7
[Bind(Exclude = "Id")]
public class Hebe
{
      public int Id {get;set;}

      [Required]
      public string Message {get; set}
}

顺便说一句,它不会在创建时为您的模型绑定 Id 属性

于 2010-01-26T23:09:29.420 回答
7

客户端发送的Id应该为0。模型Id=0没有问题,这是int的默认值。问题是他没有看到来自客户端的值,或者它带有空格或空值。我有一个隐藏的输入,它代表 Id(或在复杂对象 NestedPropertyId/NestedProperty.Id 中),所以我确保它以零值开头。

<input type="hidden" id="id" value="0" />
<input type="hidden" id="eventId" value="0"/>
<input type="hidden" id="contactId" value="0"/>

此外,当将表单重新设置为在客户端添加新实体时,我确保将隐藏的初始化为零。

希望这对某人有所帮助。

埃菲

于 2015-12-31T18:00:41.710 回答
2

我有同样的问题,使用带有 POCO 的 RC2。如果您命名一个属性 Id 但没有在其上放置验证属性但 IsValid 说它是必需的。如果我将一个属性命名为除 ID 之外的任何名称,则不会发生这种情况。为什么我必须排除 Id?

谢谢

于 2010-01-28T17:00:40.470 回答
2

添加 ?到 int

[Key]
[HiddenInput(DisplayValue = false)]
public int? ID { get; set; }
于 2012-02-17T21:58:56.140 回答
2

检查您的视图。如果您的 id 字段有隐藏字段,请删除。这仅用于编辑。@Html.HiddenFor(Model => Model.Id)

于 2016-02-01T05:21:26.780 回答
1

我刚刚创建了一个新的 MVC2 项目,并添加了一个简单的 POCO 以及一个控制器和一个视图。据我了解,您正在使用模型绑定来创建对象,即

using System.ComponentModel.DataAnnotations;
public class SimpleObject
{
    public int Id {get;set;}
    [Required]
    public string Message { get; set; }
}

在控制器中我们有

[HttpPost]
public ActionResult Create(SimpleObject created)
{
    /// do something
}

在视图中,没有 ID 字段的编辑器?

这不应以任何错误消息告终。相反,Id 应该设置为 default(int),即 0。这对我有用。您使用的是哪个版本的 MVC2(我假设的 RC)?

不要误解我的意思:防止 Id 被模型绑定器绑定很重要,因为这将允许攻击者篡改对象的 Id。尽管如此,默认模型绑定器不应显示您描述的行为。

于 2010-01-27T07:31:13.900 回答
1

就我而言,问题出在 ID 属于 type 的事实string。更改为int(不可为空)为我修复了它。该string类型是对设计不良的数据库进行逆向工程的结果。

于 2013-05-08T14:42:28.093 回答
0

我有同样的问题,除了我的模型上有三个整数字段。我设法通过将错误地需要的所有整数属性设置为可空整数来解决它。

于 2010-02-01T14:14:07.780 回答
0

以上答案都是正确的。无论如何,每个人都遵循不同的场景。对于相同的问题,我的解决方案如下。如果您的 ID 是主键,那么您需要启动它我的意思是说,当您在 get 方法中传递模型以查看时,只需在它之前创建新对象。它会将 0 设置为您的 ID,而不是 null。

于 2015-01-29T05:23:11.860 回答
0

我遇到了同样的问题,并通过在我的 Create 方法的 GET 调用期间简单地将视图模型的一个空实例传递给视图来解决它。

//GET: DocumentTypes/{Controller}/Create
    public ActionResult Create()
    {
        return View(new DocumentTypeViewModel());
    }

    //POST: DocumentTypes/{Controller}/Create
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(DocumentTypeViewModel viewModel)
    {
        if(ModelState.IsValid) {

            var result = AddDocumentType(viewModel);
            if(!result.HasValidationErrors) {
                return RedirectToAction("Index");
            }

            ModelState.Update(result);

        }

        return View(viewModel);
    }

然后在我看来,我确保我有

@Html.HiddenFor(m => m.ID)

这样我就不必显式指定 Bind 属性

于 2015-06-08T17:36:34.250 回答
0

我也遇到了同样的问题,现在我已经解决了这个问题。使用 HttpGet 您需要返回一个 View 将是空模型。如

[HttpGet]
public ActionResult Add()
{
    //Your code here
    return View(new Venue);
}

我希望它对你有用。

于 2016-06-08T04:32:39.717 回答
0

您可以通过在 上添加以下内容来设置AddImplicitRequiredAttributeForValueTypes选项来禁用此隐式验证:DataAnnotationsModelValidatorProviderApplication_Start

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

延伸阅读

于 2017-12-05T18:38:14.757 回答
0

在检查 ModelState.IsValid 之前,从 ModelState 中删除“Id”。

ModelState.Remove("Id");
于 2019-11-12T12:56:44.360 回答