2011-09-08 93 views
4

我想在Asp.Net MVC 3.0中顯示一個RadioButtonList。這是我的擴展方法:爲什麼列表<SelectListItem>在發佈後變爲空?

using System; 
using System.Collections.Generic; 
using System.Web; 
using System.Web.Mvc; 
using System.Web.Mvc.Html; 
using System.Linq.Expressions; 
using System.Text; 

public static class HtmlExtensions 
{ 
    public static MvcHtmlString RadioButtonForSelectList<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, 
     Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList) 
    { 
     StringBuilder stringBuilder = new StringBuilder(); 
     var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); 
     if (selectList != null) 
     { 
      foreach (var item in selectList) 
      { 
       var id = string.Format("{0}_{1}", metaData.PropertyName, item.Value); 
       var label = htmlHelper.Label(id, HttpUtility.HtmlEncode(item.Text)); 
       var radio = htmlHelper.RadioButtonFor(expression, item.Value, new { id = id }); 

       stringBuilder.AppendFormat("<div class=\"RadioButton\">{0}{1}</div>",radio.ToHtmlString(),label.ToHtmlString()); 
      } 
     } 
     return new MvcHtmlString(stringBuilder.ToString()); 
    } 
} 

這些都是我的HomeController action方法:

public ActionResult Index() 
{ 
    return View(GetIndexViewModel()); 
} 

private IndexViewModel GetIndexViewModel() 
{ 
    List<SelectListItem> list = new List<SelectListItem> 
    { 
     new SelectListItem{ Selected = true, Value = "1", Text = "Sunday" }, 
     new SelectListItem{ Selected = false, Value = "2", Text = "Monday" }, 
     new SelectListItem{ Selected = false, Value = "3", Text = "Tuesday" }, 
     new SelectListItem{ Selected = false, Value = "4", Text = "Wednesday" }, 
     new SelectListItem{ Selected = false, Value = "5", Text = "Thursday" }, 
     new SelectListItem{ Selected = false, Value = "6", Text = "Friday" }, 
     new SelectListItem{ Selected = false, Value = "7", Text = "Saturday" }, 
    }; 
    return new IndexViewModel { SelectLists = list, SelectedItem = list[0] }; 
} 

[HttpPost] 
public ActionResult Index(IndexViewModel indexViewModel) 
{ 
    return View(GetIndexViewModel()); //this works 

    return View(indexViewModel); //why this doesn't work?? 
} 

這是我index.cshtml:

@model IndexViewModel  

@using (Html.BeginForm()) 
{ 
    <h2>Select any one item</h2> 

    @Html.RadioButtonForSelectList(model => model.SelectedItem.Value, Model.SelectLists) 

    <br /> 

    <input type="submit" value="Submit" /> 
} 

我評論過這一個工作,哪一個沒有。基本上我的列表變爲空。我究竟做錯了什麼?如果我必須每次都這樣做,那麼最好使用webforms,因爲webforms可以保留回發中的數據。使用MVC基本上意味着每次發佈值時都必須進行數據庫調用。我是正確的還是在我的代碼中有一些錯誤?

+1

是否很難將參數編寫爲camelCase? – Phill

+0

@菲爾:對不起,我沒有明白你的意思;) – Jaggu

回答

7

因爲你勢必東西在GET行動並不意味着在所有這將是勢必返回到POST操作相同的屬性。默認模型聯編程序僅綁定它在請求中看到的內容。所以如果這些信息在發佈時沒有發送到服務器,它將會丟失。

您的自定義助手會生成一堆單選按鈕和標籤,但我無法在任何地方看到爲文本屬性生成輸入字段。結果他們將會迷路。

這是說你的助手看起來是正確的,並在您的文章,你的行動應該簡單地重新獲取從數據存儲這些信息,您feteched它最初,如果你想重新顯示了同樣的觀點。所以正確的做法如下:

[HttpPost] 
public ActionResult Index(IndexViewModel IndexViewModel) 
{ 
    return View(GetIndexViewModel()); 
} 
+0

謝謝達林。所以,基本上你說我必須每次都進行數據庫調用。對? – Jaggu

+1

@Jaggu,這不是我所說的。我說你應該查詢你的存儲庫層。這個存儲庫層是否進行數據庫調用是不感興趣的。它可以進行Web服務調用或其他任何方式。它也可以處理緩存,因此在一天結束時您將從緩存中重新獲取這些值。控制器操作並不關心這一點。您的數據訪問層被抽象出來。所以它應該做的就是執行一個存儲庫方法調用。 –

+0

右達林。得到它了。謝謝。緩存是這裏的關鍵。我明白。 – Jaggu

相關問題