2010-02-09 74 views
51

我只是在寻找转换WebForms为MVC:asp.net c#MVC:如何在没有ViewState的情况下生活?

在.net MVC中,什么概念使ViewState的东西不需要?

如果一个表单被发回iteself等(即回发)? page/usercontrol如何保持其状态?

人们在维护某种状态而不诉诸会话状态方面做了些什么?

当然,一个完全无状态的环境是不存在的?

+0

我确实认识到web是无状态的,我的意思是与asp.net webforms相比... – 2010-02-09 19:59:58

回答

78

但当然可以。实际上,web 是无状态的。事实上,任何相反的想法都是畸变。

Web控件在MVC中消失了。在服务器端没有事件触发。这被两种不同的机制取代 - 网址和发布表单数据。正确使用这些将取代您对ViewState的需求。

在传统的ASP.NET Web应用程序中,您可以在您的网页上放置一个可执行函数X的LinkBut​​ton。ASP.NET会将大量ViewState cruft,javascript和其他内容粘贴到网页中,以便当用户点击按钮并“返回”到网站(通过提交一个没有人知道的表单),ASP.NET重建发生的事情并确定一个特定的按钮事件处理程序必须被执行。

在MVC中,您将构建链接以访问特定路线。该路线描述了用户希望做什么 -/Users/Delinquent/Index(显示所有违规用户的列表)。 MVC中的路由系统确定哪个Controller将处理该路由以及该控制器上的哪个方法将执行。任何附加信息都可以通过URL查询字符串值传递给控制器​​方法(对于第5页的违规操作,?页面= 5)。

除了URL之外,还可以使用HTML表单将POST更复杂的信息(例如表单的数据值)或不适合查询字符串(如文件)的内容。

所以你通过查询字符串“维护”状态并形成POST值。事实上,你会发现最终没有太多的状态要维护。事实上,不得不保持很多状态很好地表明你的设计缺乏,或者你正在尝试做一些不适合网站模型的事情。

+11

非常同意 - 这是没有必要的,而且,在事实上,没有它就容易多了。 – Paddy 2010-02-09 16:25:50

+7

你的网站越少,编码,测试和维护越简单。问题在于,国家是一个如此巨大的拐杖,起初它很难摆脱它。 – Will 2010-02-09 16:26:46

+8

+1为无状态视图层为好设计。无状态的观点被大大误解。 – 2010-02-09 16:46:01

0

状态是数据库中的模型。您可以小心地缓存数据库以减少页面加载时间。

9

viewstate只是一个大的,丑陋的隐藏表单字段。

写出你自己的隐藏表单域,并在必要时加密它们。

幸运的是,现在已经不再有简单的方法来将大量和大量数据转储到页面中,因此您必须对要保存的内容进行审慎。

+6

encrypted?它没有默认加密。你的意思是编码。您可以轻松解码视图状态。 – Steven 2010-02-09 16:36:00

+0

@steven你是对的,它并不总是加密:http://msdn.microsoft.com/en-us/library/aa479501.aspx – 2010-02-09 16:40:35

+0

Html.Serialize() – 2013-12-20 10:53:00

0

自动生成视图状态并不在MVC存在,但你可以编写自己的简单的使用隐藏域,

在MVC中,你不会看到很多加密字符的上,你不要”页面顶部大多数人需要。

4

如果一张表格被发回本身等 (即回发)? page/usercontrol如何保持其状态?人们为维持某种状态而采取什么样的手段而不诉诸会话状态?

发布的ViewData(或绑定到页面的强类型对象)可以再次推送到视图。请参阅this page.中的“使用模型类集成验证和业务规则逻辑”它显示了如何发布表单,验证表单并在发生错误时将表单返回给表单。

在.NET MVC,什么概念,使 ViewState的东西那不是必需的 ?

Representational State Transfer (REST).

12

一些相关的问题:


在最传统的网络语言概念有状态的环境实际上是非常罕见的。 ASP.NET Webforms是规则的一个例外,它通过重新创建许多标准来创建该例外。 Webforms背后的目标主要是抽象概括HTML和Web开发的概念,以便桌面应用程序和Web应用程序之间的界限从开发角度模糊。这通常意味着ASP.NET Webforms提供的解决方案虽然有效,却是一种千斤顶式的交易实现,它会产生一些非常详细的输出,足以满足大多数人的需求。相反,ASP.NET MVC的核心优势在于它将HTML输出控制权交还给开发人员,并允许他们创建强大架构的Web应用程序,这些Web应用程序在实现和呈现时定义得更好,更清晰 - 尽管牺牲了某些级别的方便。

Webforms模型最大的缺点之一就是ViewState,因为它会使输出混乱,在某些场景中显着增加页面大小,而且通常相当于使用手提钻挂图片。与其试图在MVC应用程序中使用ViewState(或任何与之类似的应用程序),您应该开始使用明确控制表单中字段的模式,并仅使用最相关的数据来优化输入和输出操作。除了标记的变化之外,您还将学习如何构建更好的设计解决方案,以便在您的应用程序和外部环境中使用。

我想做的第一个比较就是:Webforms构建Web页面,但MVC构建Web应用程序。如果您的日常工作主要是构建网站的各个部分,或者添加小块功能,您通常会发现Webforms更容易,更省时;另一方面,如果你想构建一个可测试,可扩展且灵活的完整应用程序,那么MVC就是你的调用。

0

其实它确实如此。你必须忘记视图状态的持久性。

您还需要将您的想法回发转换到页面以“调用控制器”。这种方式事后会更容易理解。不是调用页面,而是调用返回视图的控制器。因此,无论是在每次通话中一次又一次地构建您的整个“页面”,还是您决定只处理受该行为影响的内容。如果按钮正在更改div,为什么要重新加载整个页面。只要让你打电话给你的控制器,并返回你的div中应该是什么新数据。

例如,让我们设想一个主/详细情形:

<h2>Groups</h2> 
    <div id="GroupList"> 
    </div> 
    <div id="GroupDetail" title="Detail Group"> 
</div> 

组名单在div加载一次,有 为组的列表的每个项的AJAX调用可以将控制器:

<%= Ajax.ActionLink("Edit", "DetailLocalisationGroup", 
        new { id = group.Id }, 
        new AjaxOptions() { 
         UpdateTargetId = "DetailLocalisationGroup", 
         OnSuccess = "InitialisationDetailGroup" })%> 

它调用这个动作DetailLocalisationGroup这是饲料div的GroupDetail与HTML。

[AcceptVerbs("POST")] 
public ActionResult DetailLocalisationGroup(int id) 
{ 
    LocalisationGroup group = servicelocalisation.GetLocalisationGroup(id); 
    return View("DetailGroup", group); 
} 

现在有在div形式,推动这种形式的提交按钮的时候,我们只是给我们真的需要一个控制器,这将然后保存在数据库中的数据信息。

在所有这些事件中,组列表中弥漫着这是显示在客户机屏幕上的东西,但需要有没有互动等何苦自己与这些一视图状态...

+0

嗨,好吧,我正在通过一些教程,并认为我掌握你在说什么......但是不知道如何你可以列出的东西没有在UI上的模板布局设计,你必须硬编码一些控制器中的Html模板?那看起来似乎并不是一个问题? – 2010-02-10 09:35:34

+0

..或我错过了什么... – 2010-02-10 09:35:51

+0

希望它不是太晚...嗯,你不需要控制器中的Html模板。您唯一需要的是说出要使用哪个视图,并将该对象给予此视图。它与用户控件的工作方式相同。 – Arthis 2010-03-29 15:14:11

3

MVC有一定的优势通过WebForms,但它也有一些缺点,以及我在this answer中涵盖的细节。我认为你必须问自己的根本问题是ViewState现在是否为问题 - 是否必须重写你的应用程序是一个这样的问题?如果没有,那么Learning MVC是一个有价值的目标(它确实很酷),但不是我冒这个险的商业目标。

就这么说,ViewState实际上可以在令人惊讶的大量情况下被禁用。它主要用于通过后期持续控制的价值。因此,例如,如果您有一个文本框,其值必须在服务器端以及一堆其他字段中进行检查,ViewState将允许您处理回发,捕获错误(并显示标签),然后将用户返回到其表单完好无损的表单。但是,如果表单是只有需要填写并发回,然后您将重定向到另一个页面,您可以安全地禁用它。

最后,你问人们在做什么以避免会话状态。是否有理由避免会话状态?当然,你不需要太多的信息,但完全避免它是真的没有必要,实际上,你会花费你的武器库中最强大的工具之一。

2

考虑一下这样的事实,即网络编程中的REST运动是基于对于程序的状态是不好的想法。维基百科有一个体面的描述与参考:http://en.wikipedia.org/wiki/Representational_State_Transfer

来自传统的ASP.NET和它提供的丰富的事件模型,MVC可以相当震撼。它确实需要管理一些以前看不见的东西,但我认为在可测试性方面的价值(REST页面可以很容易地触发而不需要创建复杂的视图状态,并且根据定义,服务器没有保持状态,所以我可以单独测试页面/特性)会抵消学习曲线。

有关ASP中MVC的一些讨论。NET和REST:http://blog.wekeroad.com/2007/12/06/aspnet-mvc-using-restful-architecture/

3

所有说ASP.NET MVC不使用状态的答案是非常正确的。但是ASP.NET MVC实际上使用了一些状态,尽管它不能像ViewState一样工作。

通常,当某人将数据发布到您的应用程序时,您将希望验证数据并在数据无效时显示错误。但是,如果您立即返回包含错误消息的页面,当用户点击F5重新加载页面时,数据将被重新提交。这通常不是你想要的。因此,当你意识到发布的数据无效时,你想告诉用户GET页面(或者另一个页面)并显示一条错误消息。你通过返回一个HTTP重定向状态代码来做到这一点。但是,一旦用户的GET请求进入,您如何知道要显示的错误消息?你必须记得从你(服务器)处理POST开始直到你处理GET为止。

为此,请使用名为TempData的ASP.NET MVC功能。这实际上只是Session的一个包装器,它确保无论你插入TempData字典中的什么东西都会一直存在,直到下一个请求而不再存在。

+1

+1旧帖子缺乏“宗教”。我们的技术人员很容易订阅某种超级模型 - 直到它碰到**用户**为止。我很乐意看到一个“无国籍的应用程序”,它会告诉你,通过**来征税。更简单 - 如何通过自定义产品+结帐流程以及两者之间的导航进行定制。 – EdSF 2012-05-19 01:45:44

0

您可以用MVC3Futures project模仿查看状态。它将保存整个模型。

您只需序列化模型并在视图中对其进行加密即可。

@Html.Serialize("Transfer", Model, SerializationMode.EncryptedAndSigned) 

并在控制器中添加反序列化属性。

public ActionResult Transfer(string id,[Deserialize(SerializationMode.EncryptedAndSigned)]Transfer transfer) 
0

阅读所有这些职位后,这听起来像MVC是不好的LOB类型的应用,在这里你将有大量的管制,以及CRUD操作,你想保持控制的状态。在完成提交操作后,您希望用户保持相同视图&的状态有很多原因。例如显示错误,服务器端验证消息,成功消息或执行任何其他操作。将用户重定向到某个其他视图以显示这些消息是不实际的。

0

您可以在会话状态下存储任何对象。

HttpContext.Session["userType"] = CurrentUser.GetUserType(); 
相关问题