2013-10-02 178 views
3

在我的索引頁我有一個搜索表單,允許用戶根據3個搜索條件來提取信息。當搜索結果從控制器返回時,它們將作爲List對象返回,該對象是視圖模型的一個屬性,並顯示在搜索表單下方的表格中。視圖模型發佈空的屬性,回控制器

然後用戶可以選擇的記錄了他們想改變的選項。他們將通過選擇指定記錄旁邊的複選框來完成此操作。然後,使用搜索框下方顯示的表單,輸入新值並點擊「更新」按鈕保存更改。

這裏(我們爲了讓用戶進行大規模更新,而無需按行來改變錶行這樣做)是一個屏幕截圖來說明我的意思。這是頁面看起來就像用戶點擊「搜索」按鈕後:

enter image description here

當指示用戶命中的「搜索」的形式回發到控制器的索引方法。當用戶點擊「克隆選定項目」時,表單被指示回發到同一控制器中的「更新」方法。然而,問題是,被調回的​​「更新」的方法是,除了放置在New TerritoryNew DescriptionNew Effective Date文本框中的值完全空視圖模型對象。

我是比較新的ASP MVC所以任何幫助/建議將不勝感激。不知道爲什麼視圖模型會使用「搜索」按鈕從控制器發回相同的值,但使用「克隆選定項目」時不會這樣做。

視圖模型(這是被髮回到控制器)

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>(); 
    } 
} 

模型(它將填充視圖模型的列表對象)

[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"> 
+0

任何型號的錯誤數據綁定? – asawyer

+0

它是你的Model.zipCodeTerritory沒有得到返回? –

+0

不,它是返回的ZipCodeIndex視圖模型。我會在帖子中記下這一點,thx。 – NealR

回答

1

那麼如果加上hiddenfor沒有工作,我會盡量做到這樣的事情。

@for (int i = 0; i < Model.OrdItems.Count; i++) 
{ 

@Html.DisplayFor(model => model.zipCodeTerritory[i].channelCode)@Html.HiddenFor(model => model.zipCodeTerritory[i].channelCode) 
@Html.DisplayFor(model => model.zipCodeTerritory[i].zipCode)@Html.HiddenFor(model => model.zipCodeTerritory[i].zipCode) 

} 
+0

我還需要能夠雖然改變'zipCodeTerritory'列表項的布爾屬性同樣的問題。 – NealR

+0

雅應該仍然是罰款只是@ Html.CheckBoxFor(型號=>模型[zipCodeTerritory [I] .update) –

+0

這工作,感謝您的幫助! – NealR

-2

我會建議嘗試使用KnockoutJS,從服務器發回實際數據,只是更新會容易得多。 如果你想要的例子 - 讓我知道我會很樂意給一些。

如果這不是一個選項 - 注意你創建的表單(BeginForm)裏面的內容,因爲你想要的大部分內容都不在裏面,所以它不會在post中提交給控制器。

+1

任何人都想評論爲什麼這些被低估? – NealR

+0

他仍然有knockoutJS – RiceRiceBaby

-1

以上帖子是解決您問題的一種低效且不正確的方法。 ASP.NET MVC在模型綁定過程中保留並使用單詞「model」作爲關鍵字。您需要在動作結果參數中將名稱「搜索」更改爲「模型」。這應該可以解決您的搜索數據無法回傳的問題。

+0

任何人都想評論爲什麼這些被低估? – NealR

-1

這只不過只是當你在你的控制器返回操作結果來看,創建模型的對象,然後,只有通過它來查看。

+0

任何人都想評論爲什麼這些被低估? – NealR

-1

轉到RouteConfig.csApp_start,然後正確你可以看到url:{controller}/{action}/{id}RegisterRoutes方法。瀏覽器將轉到此路線。您的編輯動作有輸入參數調用id?也許名字是不同的。

+2

任何人想評論爲什麼這些被低估? – NealR

0

當我們使用HTML輔助方法Html.DisplayFor(),它只是顯示的數據爲純文本。您可以通過瀏覽器中的「查看頁面」資源進行檢查。你所做的就是使用Html.HiddenFor輔助方法來綁定發佈後你需要的數據。或者你也可以使用JQuery.Ajax