【问题标题】:ASP.NET MVC - Is IsPostBack still here?ASP.NET MVC - IsPostBack 还在这里吗?
【发布时间】:2010-10-21 02:27:01
【问题描述】:

我知道,我知道,我知道。我完全同意,我不应该在 MVC 中做网络表单。但是,签署我的薪水支票的人现在不会批准我们的网站完全转换为 MVC。因此,我在 MVC 中添加新功能的同时,逐页地采取增量步骤来转换它们。

所以我的问题是如何从控制器访问 IsPostBack 属性?

编辑:为了进一步澄清,我的 mvc 母版页上有一个 webform 用户控件,可以启动回发。我正在尝试识别这些回发与 mvc 帖子。在这一点上,我想我将只检查“__viewstate”键的请求表单键,如果找到,则将其视为回发。

【问题讨论】:

  • public static bool IsPostBack(this HttpRequestBase request) { return __viewstate-something-something } 可能是您最接近的。但是在 MVC 母版页中放置 Web 窗体用户控件可能会在 ASP.NET MVC 的未来版本中中断。
  • 为什么我们不能在 MVC 中使用 Web 表单?我正在使用网络表单。但我不专业。除了网络表单,我们还能使用什么?

标签: asp.net-mvc webforms


【解决方案1】:

如果有人仍然感兴趣,您可以像这样从 MVC 操作方法内部测试 POST:

if (Request.HttpMethod=="POST") { 

}

【讨论】:

  • 谢谢你,这正是你在 MVC 中需要做的事情!
  • 不惜一切代价避免这种情况。您的控制器代码应按方法组织。您的 HttpGet 方法,即 [HttpGet] 应该与您的 [HttpPost] 方法完全分开。这有很多原因,可测试性是一个,可读性等。请参阅下面 tvanfosson 的答案。
  • 在 2012 +1 中仍然有帮助
  • “不惜一切代价避免这种情况”是什么意思?如果你想要一个 javascript 标志是否执行脚本怎么办?没有其他方法可以做到这一点......
  • -1:这不区分回发和 AJAX 帖子。
【解决方案2】:

没有 IsPostBack —— 一切都是 POST 或 GET(或其他 HTTP 动词)。您可以使用 AcceptVerbsAttribute 限制您的操作允许的 HTTP 动词,即,您永远不会看到来自不允许的动词的请求。例如,以下仅允许 POST。

  [AcceptVerbs( HttpVerbs.Post )]
  [ValidateAntiForgeryToken]
  public ActionResult Update( int id )
  {
  }

如果您需要相同的操作名称同时执行 GET/POST 并且它们实际上执行不同的操作,您可以给它们单独的签名或使用 ActionNameAttribute 为其中一个操作设置别名,以便方法可以具有不同的名称。

  [AcceptVerbs( HttpVerbs.Get)]
  public ActionResult List()
  {
  }

  [AcceptVerbs( HttpVerbs.Post )]
  [ValidateAntiForgeryToken]
  public ActionResult List( string filter, int page, int limit )
  {
  }

  [ActionName( "List" )]
  [AcceptVerbs( HttpVerbs.Get)]
  public ActionResult ListDisplay()
  {
  }

  [AcceptVerbs( HttpVerbs.Post )]
  [ValidateAntiForgeryToken]
  public ActionResult List()
  {
  }

编辑:请注意,我已将防伪令牌验证添加到 POST 操作中。你真的应该用这个来protect against cross-site scripting attacks

【讨论】:

  • 其实mvc和webforms页面混用还是有post back的。请参阅上面的编辑。
【解决方案3】:

你可以在 Razor 中使用这段代码

@if(IsPost)
{
//dosomething
}
else
{
//do some other thing
}

【讨论】:

    【解决方案4】:

    我经常使用这个方法(在我的 BaseController 类上声明)

     protected bool IsPostBack()
     {
         bool isPost = string.Compare(Request.HttpMethod, "POST", 
            StringComparison.CurrentCultureIgnoreCase) == 0;
         if (Request.UrlReferrer == null) return false;
    
         bool isSameUrl = string.Compare(Request.Url.AbsolutePath, 
            Request.UrlReferrer.AbsolutePath, 
            StringComparison.CurrentCultureIgnoreCase) == 0;
    
         return isPost && isSameUrl;
     }
    

    【讨论】:

      【解决方案5】:

      控制器不继承自 System.Web.UI.Page。没有 isPostback 属性。

      【讨论】:

      • ASP.NET 视图引擎视图确实继承自 Page。
      【解决方案6】:

      对于 Asp.net Core 2.x,您可以在 HttpRequest 上创建扩展方法。基于@ibirite 的答案可能是这样的:

      using System;
      using System.Linq;
      using Microsoft.AspNetCore.Http;
      using Microsoft.AspNetCore.Http.Extensions;
      
      namespace MyApp
      {
          public static class HttpRequestExtensions
          {
              public static bool IsPostBack(this HttpRequest request)
              {
                  var currentUrl = UriHelper.BuildAbsolute(request.Scheme, request.Host, request.PathBase, request.Path, request.QueryString);
                  var referrer = request.Headers["Referer"].FirstOrDefault();
      
                  bool isPost = string.Compare(request.Method, "POST",
                     StringComparison.CurrentCultureIgnoreCase) == 0;
                  if (referrer == null) return false;
      
                  bool isSameUrl = string.Compare(currentUrl,
                     referrer,
                     StringComparison.CurrentCultureIgnoreCase) == 0;
      
                  return isPost && isSameUrl;
              }
          }
      }
      
      

      【讨论】:

        【解决方案7】:

        MVC 框架不支持 Web 表单中使用的经典回发和视图状态。所以,不,您无权访问 IsPostBack。

        我对您的建议是创建两个分支:一个用于为已知错误添加补丁的当前站点,另一个用于从头开始构建新站点。新功能应该在这个中实现。我假设您的大部分代码库都可以在新站点中重用。

        新网站准备就绪后,将其投入生产。

        【讨论】:

          【解决方案8】:

          您为什么要尝试从控制器中获取该值?不确定这是否会对您有所帮助,但您仍然可以使用传统的 Request 对象来获取表单提交的信息...

          【讨论】:

            【解决方案9】:

            我不确定我是否正确理解了您的问题,但是在控制器上,您将有一个处理来自浏览器的初始 GET 的操作和一个处理 POST 的第二个操作。

             [AcceptVerbs(HttpVerbs.Post)]
             public ActionResult Create(MyModel model)
             {...}
            
             public ActionResult Create()
             {...}
            

            【讨论】:

              【解决方案10】:

              我肯定会看看 Scott Hanselman 的这篇博文,他在 MVC 应用程序中放置了一个 aspx 页面。

              http://www.hanselman.com/blog/PlugInHybridsASPNETWebFormsAndASPMVCAndASPNETDynamicDataSideBySide.aspx

              您的控制器将无权访问 ViewState 属性。即使您确实想处理 __VIEWSTATE 的问题,您也必须做一些工作才能在 mvc 控制器中将其转换为可用的形式。祝你好运,想出一个转换策略,不管结果如何,很多人都会有兴趣知道你在这个过程中会遇到什么样的问题。

              【讨论】:

                【解决方案11】:

                如果您在 MVC 页面中有多个表单,您可以在表单中添加一个带有有意义 ID 的隐藏输入,并测试它是否有值。这样您就不需要有两个单独的处理程序(一个用于获取,一个用于发布)。

                所以在页面和表单内部:

                 <input type="hidden" id="testForm" name="testForm" value="1"/>
                

                在控制器中:

                if (Request.Form["testForm"] != null)
                        { 
                        // ACTIONS FOR THE POSTED FORM
                        }
                

                希望对你有帮助!

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2016-10-19
                  • 2011-10-07
                  • 2017-04-11
                  • 1970-01-01
                  • 2011-10-11
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-02-14
                  相关资源
                  最近更新 更多