我用的是MVC,在控制器里面有两个action,A()和C(),A里面有一个List集合,需要将他传递到C里面,大家一般都是如何传递的?
A()是会return view()到 A 页面上的,然后 A页面上有表单提交到 C()。我现在是利用TempData实现的,大神们有什么其他的方法,给点意见。谢谢!
可能我问题描述的不是很清楚,我说仔细一点,首先有一个 Index页面展示的是一个列表,然后用户选择要操作的选择项,通过表单提交 数据Id 到 A(),A()得到的就是数据Id的数组,然后返回A页面,A页面需要用户选择一些模版和内容,此时就需要保存得到的 Id数组,然后把用户选择的模版和内容还有保存下来的 Id数组一起提交到 C(),C()做一系列的逻辑处理,最后跳转到成功页。
要简单的、完整的传递,最好走viewbag,当然,通过session也可以(一般人都不会这样做)。
走ViewDictionary也可以,只是在理解上会麻烦点:
Html.Action("c", new {data=aData})//代码供参考。
嗯,谢谢您提供的思路,我先自己试试,遇到问题再回复您。:)
@晓菜鸟: 你的这个设计其实不好,不应该有这样的数据在Action之间传递。
@519740105: 怎么说?再多说点.
@519740105: 对于Html.Action,他是会直接调用对应的方法返回视图的,我需要的是用户点击一下提交按钮,然后把这个list传递到C()里,所以我换成了Html.ActionLink,问题又出现了,我是这样传递的:@Html.ActionLink("提交","C",new{bookIds=list})
list 就是一个存放主键的集合,这样写后台是接受不到这个参数的。
@晓菜鸟:
list数据复杂,传递的时候会影响性能。
MVC通过控制传递数据,一般都是把数据对象序列化到一个字典里,然后再把数据传递给控制器,控制器再对字典数据进行组合。
根据我的YY(未经证实ACTION是否真这样),LIST数据在传递的时候,如果把整个List都进行序列化再反序列化,这样会大大的影响性能,所以,我在设计的时候都不这样传递数据,或者传递数据ID由新的ACTION获取ID后查询数据,或者自己把list字符串化后再传递。
@晓菜鸟: 如果你的后台的Action参数类型定义为IList兼容的,就不会有这样的问题。
如果你的list其实只是一个id集合,这个也就跟我这里的实现方案是类似的,这里,你把这个list转换为id数组再传递就可以了。
@519740105: 嗦嘎,我现在传递的就是数据的Id,不过我没有拼接成字符串,而是直接想把存放多个Id的集合直接传递,用@Html.ActionLink不能实现对吗?
@519740105: 您是说传递数组的话用@Html.ActionLink就能实现?但是我的运行结果接收到的参数是null.
@Html.ActionLink("提交","C",new{bookIds=arrayIds})
@晓菜鸟: 给你几段参考代码:
public class HomeController : Controller { public ActionResult A() { return View(new int[] { 1, 2, 3, 4, 5 }); } public ActionResult C(int[] ids) { return View(ids); } }
A.CSHTML:
@model int[] @{ Layout = null; } <div> <span>Page A</span> @if (Model == null) { <text>null model</text> } else if (Model.Length == 0) { <text>Empty model</text> } else { foreach (var item in Model) { <text>@item,</text> } } </div> @Html.Action("C", new {ids = Model}) @Html.Action("C") @Html.Action("C", new { ids = (int[])null }) @Html.Action("C", new { ids = new int[0] }) @Html.Action("C", new { ids = new int[]{3,6,9,0,4 } })
C.CSHTML:
@model int[] @{ Layout = null; } <div> <span>Page C</span> @if (Model == null) { <text>null model</text> } else if (Model.Length == 0) { <text>Empty model</text> } else { foreach (var item in Model) { <text>@item,</text> } } </div>
@519740105: 以前是我根据您的代码理解到的意思,不知道对不对,说出来您听听。
Html.Action他是会直接调用C()方法的,您的意思是让我直接调用C()进行逻辑处理,然后返回操作结果进行展示,对吗?
1.如果是:C()里面的业务逻辑处理有点多,如果直接在A页面上直接调用的话A页面加载会很慢。
2.如果不是:请恕我愚昧,望您指点一二。
我补充了问题声明,您可以看看,我哪里设计得有问题,谢谢!
@晓菜鸟: 你这种是没问题的,就参考我上面的代码使用就好。
至于C的逻辑复杂的问题,试问:如果单独运行C就不复杂了吗?
当然,如果C过于复杂,需要很长时间,而此时把页面嵌入到A里面,是不好,但可以考虑用进度条、等待的方式显示。
特别的,按照你这个需求,调用C执行的仅仅是获取ids后保存数据,那么,你可以考虑把C当作一个服务存在(比如WebApi),通过异步调用(如ajax)来执行。
@519740105: 嗯,您的建议都很好,我一开始考虑的是单独运行C()只会在提交数据的时候卡一下,如果直接在加载A页面的时候调用C()的话,会延迟A页面的加载,我现在考虑使用异步或者直接把Id数组字符串化进行传递,随便问一下,我使用TempData进行传递有什么不好的吗?
@晓菜鸟: tempdata类似数据库的临时库的概念吧,我用这个比较少,按照你的需求来说也是可以的,因为tempdata在一个会话请求生命周期内是唯一的。
@519740105: 嗯嗯,非常感谢您的回答,对我很有帮助,谢谢!
最好的办法是只传递一个一组主键或者什么标记到A页面。再传递到C()中。最后根据这组主键或者什么进行查询List集合。尽量不要把集合到处传递。
那这组主键我在A页面上怎么才能传递到C()中呢?
@晓菜鸟: ViewData[""]或者ViewBag传递到页面的Hidden控件保存。或者View()参数中传递。
@ArnoldZhang: 1.ViewData[""]:您是说在页面上直接ViewData[""]=list;这样不行吧?
2.Hidden:那我不是得用好多个Hidden保存?
3.View()参数中传递,怎么传递不太明白。
重新调用一遍产生list啊,aciton不是给你作业务处理的。如果重复度大那就放缓存咯
我这个list是用户在页面上选择产生的,没法通过调用再得到。
@晓菜鸟: 那这就是你程序设计不好。你没有真正MVC分离才会导致这样的结果。
@Cherbim: 我补充了问题,您给看看,我应该怎么设计?
你还是没有明白什么是WEB编程。我知道这不能怪你,得怪微软。
象你问的这个问题,他是这样的
1、对象LIST --------- 生存在服务器IIS环境中,并由IIS解析为结果传送给浏览器
2、浏览器,当页面生成时,对象其实已经不存在,除非是JAVASCRIPT对象,否则大部份是以文本形式存在于HTML控件中。
3、浏览器提交,这时候,浏览器要向上级(IIS)报告,你想保留1状态的对象或是2状态通过AJAX向后台取到的对象,这都是不明智的,因为对象其实已经不存在。
4、你提交的基本上都是字符串。
5、WEB编程要记住一点,WEB是无状态的。(简单几个字,真正理解并不容易)
嗯,谢谢大叔,还是得不停的学习啊!
请问大叔,我该如何理解Razor视图里的Model?又该如何理解Model里的这些对象?
@晓菜鸟: Model就是对象。你没有理解的是WEB的运行机制。
纯粹的WEB,与NET无关的WEB。
说起来Winform的运行机制还简单一些,WEB已经属于进阶的编程思维了。
WEB编程已经相当于Winform编程中实现Socket通讯或者P2P这个难度系数了,
思维要能够在IE和IIS之间切换。
我当年大概用了半年左右时间,才恍然大悟,原来WEB是这样的。(开始学编程是Client端编程)
一开始容易把JAVASCRIPT和ASP搞混。
@爱编程的大叔: 嗯嗯,多谢大叔,听完您的这段话我有种恍然大悟的感觉,至少又多懂得了一点,我有时候确实搞不清楚,还是得多学习,多谢大叔指点!
跨页面的调取的话。要门通过session 或者同URL 这个都可以实现的。
同URL?什么意思,没太明白。
@晓菜鸟: 用url 传值
@我是糖糖: 你用URL把一个List集合传过去?没跟我开玩笑吧?