На моей странице индекса У меня есть форма поиска, которая позволяет пользователям извлекать информацию на основе 3 критериев поиска. Когда результаты поиска возвращаются с контроллера, они возвращаются как объект List
, который является свойством модели представления и отображается в таблице под формой поиска.View Model posting null properties back to controller
Затем пользователь может выбрать, какие записи они хотели бы изменить. Они сделают это, установив флажок рядом с указанными записями. Затем, используя форму, которая появляется под полем поиска, введите новые значения и нажмите кнопку «Обновить», чтобы сохранить изменения. (мы делаем это, чтобы позволить пользователю делать массовые обновления без необходимости изменять таблицу подряд)
Вот скриншот, иллюстрирующий, что я имею в виду. Это то, что страница будет выглядеть после того, как пользователь нажал на кнопку «Поиск»:
Когда Хитом пользователя «Поиск» форма предписывается размещать обратно в индексный метод контроллера. Когда пользователь нажимает «Clone Selected Items», форма получает указание вернуться к методу «Обновить» в том же контроллере. Однако проблема заключается в том, что объект модели представления, который отправляется обратно к методу «Обновить», является полностью нулевым, за исключением значений, помещенных в текстовые поля New Territory
, New Description
и New Effective Date
.
Я относительно новичок в ASP MVC, поэтому любая помощь/предложения будут оценены. Не уверен, почему View Model вернет сообщение с контроллера с теми же значениями, которые были отправлены туда при использовании кнопки «Поиск», но не сделает этого, используя «Clone Selected Items».
View Model (это то, что будет размещена на контроллер)
public class ZipCodeIndex
{
public List<ZipCodeTerritory> zipCodeTerritory { get; set; }
[DisplayName("Zip Code")]
public string searchZip { get; set; }
[DisplayName("Effective on this date")]
public string searchDate { get; set; }
[DisplayName("State")]
public string searchState { get; set; }
[DisplayName("New Territory")]
public string newTerritory { get; set; }
[DisplayName("New Description")]
public string newDescription { get; set; }
[DisplayName("New Effective Date")]
public string newEffectiveDate { get; set; }
public ZipCodeIndex()
{
zipCodeTerritory = new List<ZipCodeTerritory>();
}
}
Модель (Это заполнит объект List в виде модели)
[MetadataType(typeof(ZipCodeTerritoryMetaData))]
public partial class ZipCodeTerritory
{
public bool Update { get; set; }
}
public partial class ZipCodeTerritory
{
public string ChannelCode { get; set; }
public string DrmTerrDesc { get; set; }
public string IndDistrnId { get; set; }
public string StateCode { get; set; }
public string ZipCode { get; set; }
public System.DateTime EndDate { get; set; }
public System.DateTime EffectiveDate { get; set; }
public string LastUpdateId { get; set; }
public Nullable<System.DateTime> LastUpdateDate { get; set; }
public int Id { get; set; }
}
Вид
@model Monet.ViewModel.ZipCodeIndex
@using(Html.BeginForm("Index", "ZipCodeTerritory", FormMethod.Post))
{
<div id="searchBox" class="boxMe">
<div id="zipBox">
@Html.Raw("Zip Code")
@Html.TextAreaFor(model => model.searchZip, new { style = "width: 300px;", placeholder = "Enter up to 35 comma separated zip codes" })
</div>
<div id="dateBox">
@Html.LabelFor(model => model.searchDate)
@Html.TextBoxFor(model => model.searchDate, new { style="width: 80px;"})
</div>
<div id="stateBox">
@Html.LabelFor(model => model.searchState)
@Html.TextBoxFor(model => model.searchState, new { style = "width: 25px;" })
<button type="submit">Search</button>
</div>
</div>
<div id="errorStatus">
@ViewBag.ErrorMessage
</div>
<div style="clear: both;"></div>
}
<br/>
@Html.ActionLink("Create New", "Create")
<br/>
@if (Model != null)
{
using(Html.BeginForm("Update", "ZipCodeTerritory", FormMethod.Post))
{
<div id="cloneBox">
@Html.LabelFor(model => model.newTerritory)
@Html.TextBoxFor(model => model.newTerritory, new { style="width: 30px;padding-left:10px;"})
@Html.LabelFor(model => model.newDescription)
@Html.TextBoxFor(model => model.newDescription, new { style = "width: 250px;padding-left:10px;" })
@Html.LabelFor(model => model.newEffectiveDate)
@Html.TextBoxFor(model => model.newEffectiveDate, new { style = "width: 80px;padding-left:10px;" })
<button type="submit">Clone Selected Items</button>
</div>
}
<table id="thetable" class="tablesorter" >
<thead>
<th></th>
<th>Channel</th>
<th>Territory</th>
<th>Description</th>
<th>State</th>
<th>Zip</th>
<th>Effective</th>
<th>End Date</th>
<th>Last Update By</th>
<th>Last Update Date</th>
<th></th>
</thead>
<tbody>
@foreach (var item in Model.zipCodeTerritory)
{
<tr>
<td>@Html.CheckBoxFor(model => item.Update)</td>
<td>
@Html.DisplayFor(model => item.ChannelCode)
</td>
<td>
@Html.DisplayFor(model => item.IndDistrnId)
</td>
<td>
@Html.DisplayFor(model => item.DrmTerrDesc)
</td>
<td>
@Html.DisplayFor(model => item.StateCode)
</td>
<td>
@Html.DisplayFor(model => item.ZipCode)
</td>
<td>
@Html.DisplayFor(model => item.EffectiveDate)
</td>
<td>
@Html.DisplayFor(model => item.EndDate)
</td>
<td>
@Html.DisplayFor(model => item.LastUpdateId)
</td>
<td>
@Html.DisplayFor(model => item.LastUpdateDate)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.Id })
</td>
</tr>
}
</tbody>
</table>
}
Контроллер
public ViewResult Index(ZipCodeIndex search)
{
try
{
//If search criteria is null page is loading for the first time so send blank view
if (String.IsNullOrWhiteSpace(search.searchZip) &&
String.IsNullOrWhiteSpace(search.searchDate) &&
String.IsNullOrWhiteSpace(search.searchState))
{
return View();
}
//Determine if necessary search criteria has been sent
if (String.IsNullOrWhiteSpace(search.searchZip) && String.IsNullOrWhiteSpace(search.searchState))
{
ViewBag.ErrorMessage = "Either State or Zip Code Must be Specified";
return View(search);
}
DateTime effectiveDate;
//Convert date string to DateTime type
if (String.IsNullOrWhiteSpace(search.searchDate))
{
effectiveDate = DateTime.MinValue;
}
else
{
effectiveDate = Convert.ToDateTime(search.searchDate);
}
//Conduct search by State Code/Date alone
if (String.IsNullOrWhiteSpace(search.searchZip))
{
search.zipCodeTerritory = (from z in db.ZipCodeTerritory
where z.StateCode.Equals(search.searchState) &&
z.EffectiveDate >= effectiveDate
select z).ToList();
return View(search);
}
//Zip codes have been requested to conduct zip search
string[] zipArray;
//Create array and remove white spaces
zipArray = search.searchZip.Split(',').Distinct().ToArray();
for (int i = 0; i < zipArray.Length; i++)
{
zipArray[i] = zipArray[i].Trim();
}
//Determine if state code is being used in search
if (String.IsNullOrWhiteSpace(search.searchState))
{
foreach (var zip in zipArray)
{
var item = from z in db.ZipCodeTerritory
where z.ZipCode.Equals(zip) &&
z.EffectiveDate >= effectiveDate
select z;
search.zipCodeTerritory.AddRange(item);
}
}
else
{
foreach (var zip in zipArray)
{
var item = from z in db.ZipCodeTerritory
where z.ZipCode.Equals(zip) &&
z.EffectiveDate >= effectiveDate &&
z.StateCode.Equals(search.searchState)
select z;
search.zipCodeTerritory.AddRange(item);
}
}
}
catch (DbEntityValidationException dbEx)
{
ViewBag.ErrorMessage = "An error has occurred, we apologize for the incovenience. IT has been notified and will resolve the issue shortly.";
SendEmail.ErrorMail(Common.ErrorCheck.CombineDbErrors(dbEx));
}
catch (Exception ex)
{
ViewBag.ErrorMessage = ErrorCheck.FriendlyError(ex);
SendEmail.ErrorMail(ex);
}
return View(search);
}
[HttpPost]
public ActionResult Update(ZipCodeIndex updateZip)
{
foreach (var zipCode in updateZip.zipCodeTerritory)
{
if (zipCode.Update)
{
try
{
if (!string.IsNullOrEmpty(updateZip.newTerritory)) zipCode.IndDistrnId = updateZip.newTerritory;
if (!string.IsNullOrWhiteSpace(updateZip.newDescription)) zipCode.DrmTerrDesc = updateZip.newDescription;
if (!string.IsNullOrWhiteSpace(updateZip.newEffectiveDate)) zipCode.EffectiveDate = Convert.ToDateTime(updateZip.newEffectiveDate);
db.Entry(zipCode).State = EntityState.Modified;
db.SaveChanges();
}
catch (DbEntityValidationException dbEx)
{
ViewBag.ErrorMessage = "An error has occurred, we apologize for the incovenience. IT has been notified and will resolve the issue shortly.";
SendEmail.ErrorMail(Common.ErrorCheck.CombineDbErrors(dbEx));
}
catch (Exception ex)
{
ViewBag.ErrorMessage = "An error has occurred, we apologize for the incovenience. IT has been notified and will resolve the issue shortly.";
SendEmail.ErrorMail("Zip Code not updated: " + zipCode.ToString() + " |MESSAGE| " + ex.Message);
}
}
}
return RedirectToAction("Index", updateZip);
}
EDIT
Я добавил следующие скрытые поля для второй формы (что сообщения в метод Update
). Это вернет критерии поиска, однако объект List
по-прежнему пуст.
@if (Model != null)
{
using(Html.BeginForm("Update", "ZipCodeTerritory", FormMethod.Post))
{
@Html.HiddenFor(model => model.searchZip)
@Html.HiddenFor(model => model.searchDate)
@Html.HiddenFor(model => model.searchState)
@Html.HiddenFor(model => model.zipCodeTerritory)
<div id="cloneBox">
Любые ошибки модели? – asawyer
Это ваш Model.zipCodeTerritory, который не возвращается? –
Нет, возвращается модель представления ZipCodeIndex. Я запомню это в сообщении, thx. – NealR