2014-10-15 2 views
0

Я пишу приложение MVC, которое заканчивает доступ к базе данных SQL. На моей странице редактирования у меня ранее был доступный для редактирования элемент, который находится в модели. Недавно меня попросили больше не разрешать пользователю редактировать первичные ключи. Я сделал быстрое изменение для изменения полей первичных ключей (в этом примере их 2) из ​​редактора для DisplayFor. Новая точка зрения:MVC submit не возвращает все данные

@model App.Data.Item 
@{ 
    ViewBag.Title = "Edit"; 
} 

<h2>Edit</h2> 

@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken() 

    <div class="form-horizontal"> 
     <h4>Item</h4> 
     <hr /> 
     @Html.ValidationSummary(true) 

     <div class="form-group"> 
      <strong>ID:</strong> 
      <div class="col-md-10"> 
       <p>@Html.DisplayFor(model => model.ID)</p> 
      </div> 
     </div> 

     <div class="form-group"> 
      <strong>ID2:</strong> 
      <div class="col-md-10"> 
       <p>@Html.DisplayFor(model => model.ID2)</p> 
      </div> 
     </div> 

     <div class="form-group"> 
      <strong>Description:</strong> 
      <div class="col-md-10"> 
       <p>@Html.EditorFor(model => model.Description) 
       @Html.ValidationMessageFor(model => model.Description)</p> 
      </div> 
     </div> 

     <br /> 
     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <button type="submit" class="btn btn-primary">Submit <i class="fa fa-caret-right"></i></button> 
      </div> 
     </div> 
    </div> 
} 

Используется для полного редактирования. Теперь данные отображаются правильно, как и ожидалось. Однако, когда нажата кнопка отправки, значения Null передаются обратно контроллеру для отображаемых значений.

Это функции редактирования в моем контроллере. ItemService.Edit() просто сохраняет данные на сервере. Он работает правильно.

[Authorize] 
    public ActionResult Edit(string id) 
    { 
     if (id == null) 
     { 
      //return new HttpStatusCodeResult(HttpStatusCode.BadRequest); 
     } 
     string[] vals = id.Split('|'); 
     ItemAttribute itemAttribute = itemAttributeService.Find(int.Parse(vals[0]), vals[1]); 
     if (itemAttribute == null) 
     { 
      return HttpNotFound(); 
     } 
     return View(itemAttribute); 
    } 

    [HttpPost] 
    [ValidateAntiForgeryToken] 
    [Authorize] 
    public ActionResult Edit([Bind(Include = "ID,ID2,Description")] 
     Item item) 
    { 
     if (item.Description == null) 
     { 
      ModelState.AddModelError("Description", "Description cannot be null."); 
     } 
     if (ModelState.IsValid) 
     { 
      itemService.Edit(item); 
      return RedirectToAction("../Home/Index/"); 
     } 
     return View(item); 
    } 

Наконец, моя модель данных:

public class Item 
{ 
    public int ID { get; set; } 
    public string ID2 { get; set; } 
    public string Description { get; set; } 
} 

Почему данные больше не передаются обратно на вторую функцию, и как я могу заставить его пройти правильно, так что я могу сохранить его база данных?

+1

Включите скрытые поля, используя '@ Html.HiddenFor()', чтобы они отправляли назад или лучше создавали модель представления только с теми свойствами, которые вы хотите редактировать, а затем, когда вы отправляете назад, получите модель данных и обновите ее на основе свойства модели представления. Обратите внимание, что вам не нужен атрибут «Bind» –

+0

Спасибо, что я не знал о HiddenFor. Кроме того, я думал, что мне понадобится привязка. Что это значит? – NerdyFool

+0

В этом случае вы отправляете назад и хотите связать все свойства.Вы использовали бы только «Bind» из того, что хотите связать только с некоторыми из свойств, которые вы разместили назад, поэтому, если вы использовали '[Bind (Include =« ID, ID2 »)], то все, что было отправлено назад для' Description', было бы быть проигнорированным и не привязанным к вашей модели. –

ответ

1

Для элементов, которые вы хотите вернуть, необходимо создать элемент ввода. В настоящее время вы показываете только два элемента модели и не имеете никакого связанного с ними ввода. В результате они не будут отправляться обратно на сервер.

Чтобы отправить сообщение на сервер, а не «редактировать» из текстового поля, добавьте помощник Html.HiddenFor() для каждого из предметов, которые вам нужны.

<div class="form-group"> 
     <strong>ID:</strong> 
     <div class="col-md-10"> 
      <p>@Html.DisplayFor(model => model.ID)</p> 
      <p>@Html.HiddenFor(model => model.ID)</p> 
     </div> 
    </div> 

    <div class="form-group"> 
     <strong>ID2:</strong> 
     <div class="col-md-10"> 
      <p>@Html.DisplayFor(model => model.ID2)</p> 
      <p>@Html.HiddenFor(model => model.ID)</p> 
     </div> 
    </div> 

Однако, имейте в виду, что любой может редактировать HTML с помощью Firebug или Chrome консольных инструментов и представить любое значение, которое они хотят для любого поля, даже если вы не хотите, чтобы изменить его. Убедитесь, что при сохранении изменений в базе данных вы являетесь NOT, включая эти поля как часть обновления.

+0

Спасибо. Я не знал о HiddenFor. – NerdyFool

0

Попробуйте это, как раз перед этой строки кода:

@Html.DisplayFor(model => model.ID) 

проставленными это для отладки:

@Html.LabelFor(model => model.ID) 

Сообщите нам, что вы видите ...

Если вы видите затем проверьте свой контроллер, в частности параметр, который требуется для сообщения. Он должен взять и элемент типа ITEM для вашей модели.

Прежде чем контроллер получит данные, MVC должен попытаться заполнить данные ... Он преобразует пары имени/значения в типы моделей со значениями тайно. Если вы не видите никаких данных после того, как находитесь в контроллере, это обычно потому, что имена не были найдены!

+0

Это не ответ. Если вам нужна дополнительная информация, используйте раздел комментария под вопросом. – Tommy

+0

Ответ просто не правильный. – mikek3332002

+0

Я хотел использовать опцию форматирования, недоступную в комментариях, чтобы помочь пользователю. Нет, это не ответ, это отладочная точка, которая приведет к ответу. Мысли? –

Смежные вопросы