2011-09-08 59 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

相关问题