【问题标题】:Using .net MVC why don't my lists survive a post?使用 .net MVC 为什么我的列表无法在帖子中保留?
【发布时间】:2015-02-03 12:27:41
【问题描述】:

我刚开始使用 .net MVC,但遇到了一些我无法解决的问题。我显然缺少一些基本原则,但希望得到一些帮助。

我有一个带有两个 IEnumerables 的 ViewModel,我想用它们来创建 dropdownlistfors。我的 GET 工作正常,列表按预期填充。

现在我将 ViewModel 发布回 POST 方法,不是为了做任何有用的事情,而是为了尝试了解 mvc 的工作原理。我希望我能够简单地从回发的模型中重新填充 dropdownlistfors - 但我得到一个空引用异常。

ViewModel 中的其他值(例如partyid)在 POST 中仍然存在,所以我很困惑。

如果我重新填充列表,我可以让它工作,但这似乎是错误的。

谁能给我指点一下?

我的视图模型

public class DemoViewModel
{
    //properties
    public IEnumerable<tbl_server_lookup> servers { get; set; }
    public int serverId { get; set; }

    public IEnumerable<tbl_site_lookup> sites { get; set; }
    public int siteId { get; set; }

    public int partyid { get; set; } 

    public string message { get; set; }

    public DemoViewModel()
    {

    }

}

我的控制器

// GET: /Demos/Test/
[HttpGet]
public ActionResult Test()
{

DemoViewModel demo = new DemoViewModel();

using (var dbContext = new ADAPI.Models.db_ad_apiEntities2())
{
    var serverList = dbContext.tbl_server_lookup.Where(s => s.server_name != null);
    demo.servers = serverList.ToList();
    var siteList = dbContext.tbl_site_lookup.Where(w => w.site_name != null);
    demo.sites = siteList.ToList();
}
demo.message = "Enter the user id you would like to look up in the box below.";

return View(demo);
}

//
//POST: /Demos/Test/
[HttpPost]
[ValidateAntiForgeryToken] 
public ActionResult Test(DemoViewModel demo)
{

//It works if I uncomment this block...
/*using (var dbContext = new ADAPI.Models.db_ad_apiEntities2())
{
    var myQuery = dbContext.tbl_server_lookup.Where(s => s.server_name != null);
    demo.servers = myQuery.ToList();
    var siteList = dbContext.tbl_site_lookup.Where(w => w.site_name != null);
    demo.sites = siteList.ToList();

}*/

demo.message = "the user id you posted is: " + demo.partyid + ". The Server you selected is: ";// +demo.serverId;
return View(demo);

}

我的观点

@model ADAPI.ViewModels.DemoViewModel


<h2>Demos</h2>
<h3>@Model.message</h3>

@using (Html.BeginForm("Test","Demos"))
{
@Html.AntiForgeryToken()
<div class="">
<h4>Party ID</h4>
@Html.ValidationSummary(true)
<!-- input box for party id-->

@Html.TextBoxFor(model => model.partyid)



<!-- dropdown list of server types eg live vs test-->
@Html.DropDownListFor(model => model.serverId, new SelectList(Model.servers, "server_Id","server_name"))
@Html.DropDownListFor(model => model.siteId, new SelectList(Model.sites, "site_short_name","site_name"))



<input type="submit" value="Try" />

</div>
}

错误

【问题讨论】:

  • 因为在post调用中没有贴出那个列表,顺便说一下这是完全正常的。在您的 [HttpPost] Test() 函数中,您应该重新加载列表项。
  • 只是为了扩展 Marthijn 已经指出的内容,您不想将服务器已经拥有的内容发送到服务器。所以只有选中的下拉项是应该发送到服务器的。
  • 回传到视图的值应该是用户为字段选择的值。由于用户不提供此数据,因此在下拉列表中传回可用选项列表是没有意义的。只需在您的 post 方法中重新填充原始来源的数据。
  • 知道了,谢谢大家。我必须记住,对于 MVC,html 中的内容几乎就是所有内容。很简单。顺便说一句,我知道我不应该将整个模型发布回来,但我很想知道它是否有效,如果无效,为什么无效。
  • @Will - 我意识到我最初对这个问题应用了错误的标签,但我不认为我将 MVVM 和 MVC 混为一谈。在 .Net MVC 中使用“ViewModel”似乎是公认的做法。然而,这是一种不同于 MVVM 中使用的“ViewModel”类型。请参阅此链接stackoverflow.com/questions/1939403/… 您的 cmets 真的让我思考,我现在将着眼于创建具有淘汰赛或类似功能的测试应用程序版本。谢谢!

标签: c# .net asp.net-mvc http


【解决方案1】:

在 MVC 中,视图上的模型在控制器操作中加载,它们不会与发布操作一起回发

如果你习惯了ASPX的viewstate,MVC中没有这种东西,你需要在当前action中为每个view加载你需要的东西。

【讨论】:

  • Joanvo,这正是我的问题,我在考虑视图状态。上面的 cmets 帮助我理清思路,你已经完美地描述了这个问题。
【解决方案2】:

下拉列表被渲染成 html 作为标签,并作为纯单值返回给服务器。

您必须在服务器上重新绑定/重新填充它们,这在验证等场景中很烦人,在这种情况下应该将相同的模型返回给客户端。

框架中不支持这一点 - 你必须自己做。

还有一件事 - 如果您绝对必须返回列表项并希望它们回到服务器上,您可以序列化 tham 并隐藏在某个隐藏字段中。但它丑陋且不安全,因为任何人都可以改变它的价值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-26
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    • 2010-11-28
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    相关资源
    最近更新 更多