0

我尝试添加一个与大陆有链接的新国家。当我按下“创建”按钮时,它不会添加新记录。我调试了我的项目,我认为这是因为 ValidState 是假的。原因是属性“Continent”为空,但 Continent_Id 不是。当我尝试编辑现有国家/地区时,我遇到了同样的问题。(我在 SQL Management Studio 中使用 SQL 脚本填充了我的数据库)

有人能帮助我吗?

大陆类:

public class Continent
{
    public int Id { get; set; }
    [Required, MaxLength(25)]
    public string Name { get; set; }

    //Navigation
    public virtual List<Country> Countries { get; set; }
}

国家级

public class Country
{
    public int Id { get; set; }
    [Required, MaxLength(25)]
    public string Name { get; set; }
    [MaxLength(5)]
    public string Abbreviation { get; set; }

    public int Continent_Id { get; set; }

    //Navigation
    [Required, ForeignKey("Continent_Id")]
    public virtual Continent Continent { get; set; }

}

控制器类(创建函数)

  //
    // GET: /Countries/Create

    public ActionResult Create()
    {
        ViewBag.Continent_Id = new SelectList(db.Continents, "Id", "Name");
        return View();
    }

    //
    // POST: /Countries/Create

    [HttpPost]
    public ActionResult Create(Country country)
    {
       var errors = ModelState.Values.SelectMany(v => v.Errors); //to check the errors
        if (ModelState.IsValid)
        {
            db.Countries.Add(country);
            db.SaveChanges();
            return RedirectToAction("Index");
        }


        ViewBag.Continent_Id = new SelectList(db.Continents, "Id", "Name", country.Continent_Id);
        return View(country);
4

4 回答 4

4

就在if (ModelState.IsValid)行之前放置这个 ModelState.Remove("v_id"); 在您的情况下,v_id 是您的主键列名称

于 2014-08-08T09:38:44.693 回答
1

我通过关闭 Continent 的必需验证来解决此问题,并将其仅设置为 Continent_Id。现在 ID 属性是必需的,但 Continent 不是。

public class Country
{
public int Id { get; set; }
[Required, MaxLength(25)]
public string Name { get; set; }
[MaxLength(5)]
public string Abbreviation { get; set; }

[Required] //added Required
public int Continent_Id { get; set; }

//Navigation
[ForeignKey("Continent_Id")] //removed Required
public virtual Continent Continent { get; set; }

}

感谢您的回复!

于 2013-04-18T08:55:57.880 回答
0

我不确定,但我相信你的问题是时机。模型验证在绑定期间自动发生;当时,Continent 属性为空。您稍后设置该属性,但在您检查 IsValid 时不会重新评估模型状态。我看到三个选项:

  • 快速而肮脏:从 Continent 中取出所需的验证并验证 Continent_Id,在控制器中添加检查以确保从 Find() 检索到有效的 Continent。
  • 大多数工作:创建自定义模型绑定器以实际使用 Continent_Id 来检索和填充 Continent。你几乎就在那里,因为同时拥有 Continent_Id 和 Continent 作为 Country 的属性是多余的,并且是不一致的机会。
  • 可能是最好的选择:让您的控制器接受一个视图模型,该模型只包含您希望从表单返回的数据并从中填充 Country 对象。
于 2013-04-16T13:05:11.513 回答
-1

ModelState 无效的原因是因为您已将 Continent 属性标记为必需,但我猜在您的视图中您没有将绑定到 Continent 对象的某些属性的表单字段。

因此,要么不根据需要标记 Continent 对象,要么提供名称为 Continent.Id 或 Continent.Name 的隐藏字段,以便模型绑定器将填充 Continent 属性:

@Html.HiddenFor(m => m.Continent.Id)

但这将导致下一个问题:您已根据需要标记了 Continent 类的 Name 属性,因此您也必须为该属性提供一个表单字段。

基本问题是,您尝试将存储库类重用为视图模型类。更好的方法是使用单独的类作为视图模型在控制器和视图之间传递数据:

class CountryViewModel {
    public int Id { get; set; }
    [Required, MaxLength(25)]
    public string Name { get; set; }
    [MaxLength(5)]
    public string Abbreviation { get; set; }

    public int Continent_Id { get; set; }
}

要在 Country 和 CountryViewModel 对象之间进行映射,请使用 AutoMapper 之类的映射器。

于 2013-04-16T13:19:03.223 回答