Почему viewmodel modelstate проверяет свойство навигации объекта?
У меня проблема с простой проверкой во время контроллера Создать действие для объекта ARTICLE. Я использую базу данных EF 4 в первую очередь. Объект ARTICLE используется в качестве внешнего ключа в объекте ACTION(ACTION.ARTICLE_id). Вот почему инструмент генерации кода добавляет свойство навигации к объекту ARTICLE, даже если оно не имеет особого смысла. Каждый раз, когда я обновляю сущности, выражение появляется в форме ниже (СТАТЬЯ). Я проверял весь внешний ключ много раз снова. Я действительно не знаю, что делать с этой ошибкой, чтобы сделать чистый солутон, а не просто очистить ошибку в действии контроллера. Все - даже вид - леса.
Действие:
[HttpPost]
[Authorize(Roles = "ARTICLE_ADMIN")]
public ActionResult Edit(ARTICLE article)
{
if (ModelState.IsValid)
{
article.date_modified = DateTime.Now;
string newimage = this.Request.Form["preview_image_filename"];
string oldimage = this.Request.Form["original_image_filename"];
if (newimage.NotNullOrEmpty())
{
article.preview_image = newimage;
}
else
{
article.preview_image = oldimage;
}
db.Entry(article).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
article.date_modified = DateTime.Now;
ViewBag.ARTICLE_CATEGORY_id = new SelectList(db.ARTICLE_CATEGORY, "ARTICLE_CATEGORY_id", "description", article.ARTICLE_CATEGORY_id);
ViewBag.ARTICLE_STATUS_id = new SelectList(db.ARTICLE_STATUS, "ARTICLE_STATUS_id", "description", article.ARTICLE_STATUS_id);
ViewBag.WEB_USER_id = new SelectList(db.WEB_USER, "WEB_USER_id", "login", article.WEB_USER_id);
return View(article);
}
Я использую эту модель сущности, созданную с помощью инструмента генерации кода с добавленными аннотациями в классе метаданных, это не может быть проще
public partial class ARTICLE
{
public ARTICLE()
{
this.PROGRAM_WEEK_DAY_ITEM = new HashSet<PROGRAM_WEEK_DAY_ITEM>();
this.STORAGE = new HashSet<STORAGE>();
this.SHOW = new HashSet<SHOW>();
this.ACTION = new HashSet<ACTION>();
}
public int ARTICLE_id { get; set; }
public System.DateTime date_created { get; set; }
public Nullable<System.DateTime> date_modified { get; set; }
public string title { get; set; }
public string html { get; set; }
public int WEB_USER_id { get; set; }
public int ARTICLE_STATUS_id { get; set; }
public int ARTICLE_CATEGORY_id { get; set; }
public Nullable<System.DateTime> date_published { get; set; }
public string preview_image { get; set; }
//code generation tool added those navigation props
public virtual ARTICLE_CATEGORY ARTICLE_CATEGORY { get; set; }
public virtual ARTICLE_STATUS ARTICLE_STATUS { get; set; }
public virtual WEB_USER WEB_USER { get; set; }
public virtual ICollection<PROGRAM_WEEK_DAY_ITEM> PROGRAM_WEEK_DAY_ITEM { get; set; }
public virtual ICollection<STORAGE> STORAGE { get; set; }
public virtual ICollection<SHOW> SHOW { get; set; }
//this one causes trouble I think, but no clue why
public virtual ICollection<ACTION> ACTION { get; set; }
}
класс метаданных - просто отображать имена и форматы:
public class ARTICLE_Metadata
{
[Key]
public int ARTICLE_id { get; set; }
[Display(Name="Vytvořeno")]
public System.DateTime date_created { get; set; }
[Display(Name = "Změněno")]
public Nullable<System.DateTime> date_modified { get; set; }
[Display(Name = "Publikováno")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
public Nullable<System.DateTime> date_published { get; set; }
[Display(Name = "Titulek článku")]
public string title { get; set; }
[Display(Name = "Obsah článku")]
[UIHint("tinymce_full"), AllowHtml]
public string html { get; set; }
[Display(Name = "Vytvořil")]
public int WEB_USER_id { get; set; }
[Display(Name = "Status")]
public int ARTICLE_STATUS_id { get; set; }
[Display(Name = "Kategorie")]
public int ARTICLE_CATEGORY_id { get; set; }
[Display(Name = "Náhledový obrázek")]
public string preview_image { get; set; }
}
и, наконец, в виде бритвы:
@using (Html.BeginForm("Create", "Articles", FormMethod.Post, new { @class = "base-form" }))
{
@Html.ValidationSummary(true)
<fieldset>
<legend>Nový článek</legend>
@Html.DatePickerFor(model => model.date_published, false)
@Html.HiddenFor(model => model.WEB_USER_id)
<p class="editor-label">
@Html.LabelFor(model => model.ARTICLE_STATUS_id)
@Html.DropDownList("ARTICLE_STATUS_id")
@Html.ValidationMessageFor(model => model.ARTICLE_STATUS_id)
</p>
<p class="editor-label">
@Html.LabelFor(model => model.ARTICLE_CATEGORY_id)
@Html.DropDownList("ARTICLE_CATEGORY_id")
@Html.ValidationMessageFor(model => model.ARTICLE_CATEGORY_id)
</p>
<p class="editor-label">
@Html.LabelFor(model => model.title)
@Html.EditorFor(model => model.title)
@Html.ValidationMessageFor(model => model.title)
</p>
<div class="html-editor">
@Html.EditorFor(model => model.html)
</div>
<p>
<input type="submit" value="Vytvořit" class="submit" />
</p>
</fieldset>
}
Когда модель проверяет и приходит к действию контроллера, ModelState.IsValid == false, ModelState сообщает об ошибке в свойстве ACTION, которого даже нет в таблице и не должно быть там, это свойство навигации.
Исключением является ошибка: преобразование параметра из типа "System.String" в тип "namespace.ACTION" не выполнено, поскольку преобразователь типов не может преобразовать эти типы.
Я пытался прикрепить изображение в режиме отладки, но эта сеть не позволила мне это сделать. У меня есть другие объекты, управляемые через контроллеры, и я смотрю так же - около 30, где этого не происходит.
Как избавиться от этой проблемы, не создавая дополнительную модель с теми же свойствами, но без навигационных? Или просто запретите включение этого свойства навигации в проверку. Или это новая ерунда от Microsoft?
1 ответ
Иногда эти странные ошибки в db-first происходят из-за того, что имя свойства навигации в объекте совпадает с именем другого объекта. Я сам иногда сталкивался с этими проблемами, и я не знаю точно, в чем причина.
В любом случае, переименование этого свойства навигации должно избавить вас от этой странной ошибки...