当我尝试使用Asp.Net MVC 2中的创建样式操作创建实体时,会发生这种情况。
POCO具有以下属性:
public int Id {get;set;}
[Required]
public string Message {get; set}
在创建实体时,会自动设置Id,因此在“创建”操作中不需要它。
ModelState表示“需要Id字段”,但我没有将其设置为如此。 这里有自动发生的事吗?
编辑 - 显示原因
Brad Wilson通过Paul Speranza在下面的一条评论中回答了这个问题的原因(保罗为他们欢呼):
您正在为...提供价值 身份证,你只是不知道你是谁。 它在默认的路由数据中 route(“{controller} / {action} / {id}”), 并且其默认值为空 string,对int无效。 使用您的[Bind]属性 用于排除ID的action参数。我的 默认路由是:new {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);
}
答案 0 :(得分:86)
您可以添加属性:
[Bind(Exclude = "Id")]
关于方法中的参数而不是类,在创建时你可以排除它并在编辑它时仍然是强制性的:
public ActionResult Create([Bind(Exclude = "Id")] User u)
{
// will exclude for create
}
public ActionResult Edit(User u)
{
// will require for edit
}
答案 1 :(得分:18)
我遇到了一个表单,其中我正在动态地将“对象”添加到列表中。因此,我们的用户可以添加,删除或更新。除了创建新项目的情况外,这一切都运行良好。出于这个原因,在我的情况下,排除Id属性不是一个选项。 解决方案是使ID为Nullable :
public int? Id { get; set; }
这样,现有项目将具有值,而新项目将具有null。好东西。
答案 2 :(得分:11)
很棒的问题和答案,拯救了我......落后。我需要添加一些东西:
而不是
[Bind(Exclude = "Id")]
我认为最好使用
[Bind(Include = "Prop1, Prop2, Prop3, etc")]
..其中Prop1,Prop2和Prop3是您想要在操作级别绑定的唯一属性。
由于这是白名单,而不是黑名单。白名单更好,更安全。这样您也可以解决过度发布和过度发布的风险。请参阅Brad Wilson's post。
答案 3 :(得分:7)
[Bind(Exclude = "Id")]
public class Hebe
{
public int Id {get;set;}
[Required]
public string Message {get; set}
}
顺便说一句,它不会在创建
上绑定模型的Id属性答案 4 :(得分:6)
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"/>
此外,当我在客户端将表单添加到“添加新实体”时,我确保将隐藏初始化为零。
希望这有助于宣传。
EFY
答案 5 :(得分:2)
我有同样的问题,使用带有POCO的RC2。如果您为属性Id命名但不在其上放置验证属性,但IsValid表示它是必需的。如果我将一个属性命名为Id,那么这不会发生。我为什么要排除ID?
由于
答案 6 :(得分:2)
添加?到int
[Key]
[HiddenInput(DisplayValue = false)]
public int? ID { get; set; }
答案 7 :(得分:2)
检查你的观点。如果你有id字段的hiddenfield,请删除。这仅用于编辑。 @ Html.HiddenFor(Model =&gt; Model.Id)
答案 8 :(得分:1)
我刚创建了一个新的MVC2项目,并添加了一个简单的POCO以及一个Controller和一个View。据我所知,你正在使用模型绑定来创建对象,即
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。尽管如此,默认模型绑定器不应显示您描述的行为。
答案 9 :(得分:1)
在我的情况下,问题来自ID是string
类型的事实。更改为int
(不可为空)为我修复了它。 string
类型是对设计糟糕的数据库进行逆向工程的结果。
答案 10 :(得分:0)
我有同样的问题,除了我的模型上有三个整数字段。我设法通过将所有错误需要的整数属性设置为可为空的整数来解决它。
答案 11 :(得分:0)
以上答案是正确的。任何一个人如何遵循不同的场景。对于同样的问题,我的解决方案如下。 如果您的ID是主键,那么您需要启动它我的意思是说当您在get方法中传递模型时只需在它之前创建新对象。它会将0设置为您的ID而不是null。
答案 12 :(得分: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属性
答案 13 :(得分:0)
我也遇到了同样的问题,现在我已经解决了这个问题。 使用HttpGet,您需要返回一个View将为空模型。如
[HttpGet]
public ActionResult Add()
{
//Your code here
return View(new Venue);
}
我希望它对你有用。
答案 14 :(得分:0)
您可以通过在Application_Start
上添加以下内容,在AddImplicitRequiredAttributeForValueTypes
上设置DataAnnotationsModelValidatorProvider
选项来停用此隐式验证:
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
进一步阅读:
答案 15 :(得分:0)
在检查ModelState.IsValid之前,请从ModelState中删除“ Id”。
ModelState.Remove("Id");