使用隐藏字段保存数据的困惑
我对如何在 MVC 应用程序中使用隐藏字段来保存数据感到有点困惑。 (如果有意义的话,我也愿意使用 Session。)
基本上,我有一个应用程序会提出一系列问题(根据用户给出的答案,这些问题可以以不同的顺序到达)。这些问题作为单个控制器的部分视图提供(该控制器调用一个帮助器方法,该方法了解应该如何提出问题的顺序)。当用户回答问题时,我使用 Ajax 提交当前答案,并用当前答案更新侧边栏。 (他们可以随时返回更改问题的答案。)我的问题的所有答案都存储在单个“答案”模型对象中(每个答案都有一个属性)。
根据我对隐藏字段的理解,我必须在每个视图中为每个问题提供隐藏字段,以便保留该数据。这是正确的吗?
如果这是正确的,那么使用 Session 对象是否更有意义?我认为每次都必须使用所有模型类型更新每个视图是低效的(而且非常不干燥)。似乎人们对此有相互矛盾的看法,而且我在持久数据(并且不使用某些数据源)方面没有受过足够的教育来确定我的决定。
I'm a little confused on how to use hidden fields for persisting data in my MVC application. (I am also open to using Session if that makes sense.)
Basically, I have an application that asks a series of questions (which can arrive in different orders depending on the answers given by the user). These questions are provided as a partial view from a single controller (which calls a helper method that understands the order of how the questions should be asked). When the user answers the question, the I use Ajax to submit the current answer which, updates the sidebar with their current answers. (They can go back at any time to change an answer to a question.) All the answers to my questions are stored in a single "Answers" model object (with a property for each answer).
Based on my understanding of hidden fields, I have to provide hidden fields in every single view for every single question in order to persist that data. Is this correct?
If this is correct, would it make more sense to use a Session object? I would think it would be inefficient (and very not DRY) to have to update every view with all the model types every single time. It seems people have conflicting opinions on this and I am not educated well enough in persisting data (and not using some data source) to be sure of my decision.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您最终为每个字段/问题都有一个隐藏字段,请意识到这也会添加到您从(DOM 本身)向下发送并向上发送到(表单变量)服务器的有效负载。虽然这对于一些隐藏字段来说可能还不错,但我认为一段时间后它会变得相当难以管理且效率低下。
会话在这里可能是一个很好的解决方案,因为您不必使用隐藏字段重复您的问题。缺点是每次将数据发送到服务器以补充会话时,您都需要进行一次网络跳跃(或从内存缓存中读取)。
在不太了解您的情况的情况下,我想我会更倾向于会议的想法。
我的另一个想法是使用单个隐藏字段,但在其中保留模型的 JSON 序列化版本,并在客户端上使用 JavaScript 来更新它,并在服务器端使用 Json.NET 来读取它并工作与它。同样,这实际上取决于数据的大小以及您用它做什么。
我希望这有帮助。祝你好运!
更新
基于评论中的问题,以下是如何使用 JSON 来保存和传输数据...注意:我更喜欢 jQuery,所以我使用它来代替纯 JavaScript 来演示。
在 JavaScript 中,您将有一个变量来保存您的对象:
回答问题时,您可以将它们添加到 JavaScript 对象文字中:
当您提交表单时,在实际操作之前将对象文字分配给表单中的隐藏字段提交...
在服务器端,从表单变量中提取隐藏字段并使用 Json.NET(或其他 Json 反序列化器)来反序列化 JSON 字符串...
希望这会有所帮助。
If you end up with a hidden field for every field/question, realize that this will also add to the payload that you're sending down from (the DOM itself) and sending up to (form variables) the server. While this may not be bad for a few hidden fields, I think it becomes fairly unmanageable and inefficient after a while.
Session may be a good solution here, since you don't have to duplicate your questions with a hidden field. The downside is that you need to make a network hop (or read from an in-memory cache) each time you send data to the server to rehydrate your session.
Without knowing a lot about your situation, I think I'd lean more towards the session idea.
The other thought I had would be to use a single hidden field, but keep a JSON-serialized version of your model in it and use JavaScript on the client to update it and use Json.NET on the server-side to read it and work with it. Again, that really depends on the size of the data and what you're doing with it.
I hope this helps. Good luck!
UPDATE
Based on a question in a comment, here's how you could use JSON to hold and transmit the data.... Note: I'm more of a jQuery person, so I'm using that instead of pure JavaScript to demonstrate.
In JavaScript, you'd have a variable to hold your object:
As questions are answered, you'd add them to the JavaScript object literal:
When you submit the form, assign the object literal to a hidden field in the form before you actually submit...
On the server side, pull the hidden field out of your form variables and use Json.NET (or other Json deserializer) to deserialize the JSON string...
Hope this helps.
由于您似乎已经在处理隐藏元素,因此只需序列化您的表单并使用 ajax 提交它即可。对加载的每个表单使用 ajax 加载的部分视图。
就我个人而言,我会让答案对象真正成为问题/答案的集合。将所有问题作为属性根本无法自定义,并且每次添加问题时都需要更改代码。
我会保存每一步的进度,而不是依赖表单来存储。
如果您选择该路线,则重新序列化表单:
http://api.jquery.com/jQuery.post /
Since you are already dealing with hidden elements it seems, simply serialize your form and ajax submit it. Use ajax loaded partial views for each form loaded.
Personally, I would make the answer object really a collection of questions/answers. Having all questions as properties isn't customizable at all and code changes are required any time a question is added.
I would save the progress at each step instead of relying on the form for storage.
re serializing the form, if you choose that route:
http://api.jquery.com/jQuery.post/
按照布伦特·安德森的评论,您是否只在问卷末尾保存一次?如果是这样,你能用充分的理由支持这个决定吗?我赞同 Adam Tuliper 的建议,即保存每一步的进度,而不是依赖表单进行存储。
考虑隐藏字段和会话的波动性:它们相对容易丢失,从而导致用户体验失败。用户重定向离开 HTTP-POST 链,或者意外关闭浏览器选项卡,纸牌屋就会倒塌。没有办法把矮胖子重新组装起来。
我的选择是为每次提交使用持久数据存储。这样,如果隐藏字段或会话丢失,您可以恢复调查问卷。如果用户已登录,您可以将数据与Principal.Name 相关联。如果没有,您可以打开匿名配置文件(也使用 cookie)并将其存储在该配置文件中。无论哪种方式,如果您从 Web 服务器带外保存数据,即使用户重新启动计算机,您也可以恢复调查问卷。
Along the lines of Brent Anderson's comment, are you only saving once, at the end of the questionnaire? If so, can you back up that decision with good reasons? I second Adam Tuliper's suggestion to save the progress at each step instead of relying on the form for storage.
Consider the volatility of hidden fields and Session: it's relatively easy to lose either, resulting in a UX failure. User redirects away from the HTTP-POST chaining, or accidentally closes browser tab, and the house of cards collapses. There is no way to put Humpty Dumpty back together again.
My choice would be to use a persistent data store for each submit. This way you can recover the questionnaire if hidden fields or session are lost. If the user is signed in, you can associate the data with the Principal.Name. If not, you can turn on anonymous profile (which also uses cookie) and store it against that. Either way, if you save the data out of band from the web server, you can recover a questionnaire even after a user reboots their machine.