Я использую EF4 CTP5 и у меня проблемы с сохранением записей обратно в базу данных.У меня есть объекты Contact и ContactType.Как говорится в заголовке записи, я установил свойство навигации «многие ко многим» между таблицами.
Проблема заключается в проверке значений ContactType.ModelState.IsValid имеет значение false, поскольку не может преобразовать значения, переданные обратно из формы (строковый массив идентификаторов ContactType в объекты ContactType.
POCO *
public partial class Contact
{
public Contact()
{
this.ContactTypes = new HashSet<ContactType>();
}
// Primitive properties
public int ContactId { get; set; }
public string ContactName { get; set; }
// Navigation properties
public virtual ICollection<ContactType> ContactTypes { get; set; }
}
public partial class ContactType
{
public ContactType()
{
this.Contacts = new HashSet<Contact>();
}
// Primitive properties
public int ContactTypeId { get; set; }
public string Name { get; set; }
// Navigation properties
public virtual ICollection<Contact> Contacts { get; set; }
}
Контроллер
//
// GET: /Contact/Edit/5
public virtual ActionResult Edit(int id)
{
Contact contact = context.Contacts.Include(c => c.ContactTypes).Single(x => x.ContactId == id);
ViewData["ContactTypesAll"] = GetTypesList();
return View(contact);
}
//
// POST: /Contact/Edit/5
[HttpPost]
public virtual ActionResult Edit(Contact contact)
{
if (ModelState.IsValid)
{
context.Entry(contact).State = EntityState.Modified;
context.SaveChanges();
return RedirectToAction("Index");
}
ViewData["ContactTypesAll"] = GetTypesList();
return View(contact);
}
Просмотр
<div class="field-block">
@Html.LabelFor(model => model.ContactId)
@Html.EditorFor(model => model.ContactId, new { fieldName = "ContactId" })
@Html.ValidationMessageFor(model => model.ContactId)
</div>
<div class="field-block">
@Html.LabelFor(model => model.OrganizationNameInternal)
@Html.EditorFor(model => model.OrganizationNameInternal)
@Html.ValidationMessageFor(model => model.OrganizationNameInternal)
</div>
<div class="field-block">
@Html.LabelFor(model => model.ContactTypes)
@Html.ListBoxFor(modelContactType,
new MultiSelectList((IEnumerable<TDAMISObjects.ContactType>)ViewData["ContactTypesAll"],
"ContactTypeId",
"Name",
Model.ContactTypes))
@Html.ValidationMessageFor(model => model.ContactTypes)
</div>
Ошибка ModelState
ModelState.Values.ElementAt(2).Value
{System.Web.Mvc.ValueProviderResult}
AttemptedValue: "5"
Culture: {en-US}
RawValue: {string[1]}
ModelState.Values.ElementAt(2).Errors[0]
{System.Web.Mvc.ModelError}
ErrorMessage: ""
Exception: {"The parameter conversion from type 'System.String' to type 'ProjectObjects.ContactType' failed because no type converter can convert between these types."}
Так что, кажется, довольно ясно, в чем проблема, но я не могу найти решение. Я пыталсявручную преобразовать идентификаторы ContactType в объекты ContactType и добавить их в объект Contact, передаваемый в функцию Edit (называемую «contact»):
contact.ContactTypes.Clear();
string[] ids = this.HttpContext.Request.Form["ContactTypes"].Split(',');
for(int i = 0; i< ids.Length; i++)
{
int x = Convert.ToInt32(ids[i]);
ContactType selectedType = context.ContactTypes.Single(t => t.ContactTypeId == x);
contact.ContactTypes.Add(selectedType);
}
, но ошибка сохраняется. Я также попытался вызвать
context.ChangeTracker.DetectChanges();
но это не сработало. Я также вручную установил ValueProviderResult для значения, которое не будет проверяться, используя
ModelState.SetModelValue("ContactTypes", val);
, что также не сработало. Я чувствую, что я 'Мне здесь не хватает чего-то простого. Есть идеи?
Спасибо, Стив