Asp.net mvc &引用;Id字段是必填的";创建时的验证消息;Id未设置为[必需]

Asp.net mvc &引用;Id字段是必填的";创建时的验证消息;Id未设置为[必需],asp.net-mvc,asp.net-mvc-2,data-annotations,Asp.net Mvc,Asp.net Mvc 2,Data Annotations,当我尝试在Asp.NETMVC2中使用创建样式操作创建实体时,就会发生这种情况 POCO具有以下属性: public int Id {get;set;} [Required] public string Message {get; set} 在创建实体时,会自动设置Id,因此在创建操作中不需要该Id ModelState说“Id字段是必需的”,但我还没有这样设置。 这里有什么自动的事情吗 编辑-显示原因 布拉德·威尔逊(Brad Wilson)通过保罗·斯佩兰扎(Paul Speranza)

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

POCO具有以下属性:

public int Id {get;set;}

[Required]
public string Message {get; set}
在创建实体时,会自动设置Id,因此在创建操作中不需要该Id

ModelState说“Id字段是必需的”,但我还没有这样设置。 这里有什么自动的事情吗

编辑-显示原因

布拉德·威尔逊(Brad Wilson)通过保罗·斯佩兰扎(Paul Speranza)在下面的评论中回答了这个问题的原因,他说(为保罗干杯):

你为我们提供了价值 身份证,你只是不知道你是。 它位于默认的路由数据中 路由(“{controller}/{action}/{id}”), 其默认值为空 字符串,该字符串对int无效。 在您的服务器上使用[Bind]属性 排除ID.My的操作参数 默认路由是:新建{controller= “客户”,action=“编辑”,id=“” }//参数默认值

编辑-更新模型技术

实际上,我改变了我再次这样做的方式,使用了TryUpdateModel和与之关联的exclude参数数组

    [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);
    }

通过以上方式,它不会在创建时绑定模型的Id属性。您可以添加以下属性:

 [Bind(Exclude = "Id")] 
在方法中的参数而不是类中,通过这种方式,在创建时可以将其排除,而在编辑时,它仍然是必需的:

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

public ActionResult Edit(User u)
{
    // will require for edit
}

我刚刚创建了一个新的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设置为默认值(int),即0。这对我有用。您使用的是哪个版本的MVC2(我假设的RC)


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

我也有同样的问题,将RC2与POCO一起使用。如果您命名了一个属性Id,但没有在其上放置验证属性,但IsValid表示它是必需的。如果我为一个属性命名Id以外的任何东西,则不会发生这种情况。为什么我必须排除Id


谢谢

我也有同样的问题,只是我的模型上有三个整数字段。我通过将所有被错误地要求为可为null的整数的整数属性设置为null,成功地解决了这个问题。

很好的问题和答案,保存了我的。。。在…的后面不过,我需要补充一点:

而不是

[Bind(Exclude = "Id")]
我觉得还是用这个比较好

[Bind(Include = "Prop1, Prop2, Prop3, etc")]
。。其中,Prop1、Prop2和Prop3是要在操作级别绑定的唯一属性

因为这是白名单而不是黑名单。白名单更好、更安全。这样,您也可以解决过账和过账不足的风险。请参阅。

添加?整型

[Key]
[HiddenInput(DisplayValue = false)]
public int? ID { get; set; }

我在一个表单中遇到了这个问题,在这个表单中,我动态地将“对象”添加到列表中。因此,我们的用户能够添加、删除或更新。除了创建新项目的情况外,所有这些都运行良好。因此,在我的例子中,排除Id属性不是一个选项解决方案是使ID为空

public int? Id { get; set; }

这样,现有项将有一个值,而新项将改为null。好东西。

在我的例子中,问题来自于ID是字符串类型的事实。更改为
int
(不可为空)为我修复了它。
字符串
类型是对设计糟糕的数据库进行反向工程的结果

以上答案是正确的。任何一种方法都会遵循不同的场景。对于相同的问题,我的解决方案如下。
若你们的ID是一个主键,那个么你们需要初始化它,我的意思是当你们在get方法中传递模型到视图时,在它之前创建一个新的对象。它会将0设置为您的ID,而不是null。

我也遇到了同样的问题,并设法通过在我的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)

这样,我就不必显式地指定绑定属性,Id应该作为0从客户端发送。 模型没有Id=0的问题,这是int的默认值。 问题是他看不到来自客户端的值,或者它带有空格或null。 我有一个表示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"/>

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

希望这对某人有帮助


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

我也遇到了与您相同的问题,现在我已经解决了这个问题。 使用HttpGet,您需要返回一个视图,该视图将清空模型。比如

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

我希望它对您有用。

您可以通过在上设置选项来禁用此隐式验证,方法是将以下内容添加到您的
应用程序\u Start

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes=false;
进一步阅读

public int? Id { get; set; }

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

ModelState.Remove("Id");

你可能会发现这篇博文很有趣:我确实觉得很有趣。这并不能解决这个问题,但可以帮助我想到我将要拥有的其他一些东西。如何才能使“Id”类型安全?类似于()=>id?在更新时,您需要记录和我们