21

I know, I know, I know. I shouldn't be doing webforms inside of MVC, I completely agree. But, the people who sign my paycheck will not approve a complete conversion of our site to MVC right now. So I am taking incremental steps, page by page, to convert them over while adding new features in MVC.

So my question is how can I access the IsPostBack property from a controller?

Edit: To further clarify, I have a webform user control on my mvc master page which can initiate postbacks. I'm trying to identify these postbacks verses an mvc post. At this point I think I am going to just check the request form keys for a "__viewstate" key and if its found treat it as a postback.

tereško
  • 58,060
  • 25
  • 98
  • 150
chief7
  • 14,263
  • 14
  • 47
  • 80
  • `public static bool IsPostBack(this HttpRequestBase request) { return __viewstate-something-something }` is probably the closest you'll get. But placing Web Form User Controls in MVC Master Pages might break in future versions of ASP.NET MVC. – bzlm Apr 04 '10 at 21:18
  • Why should't we use web forms inside of MVC? I'm using web forms. But I'm not professional. What else can we use other than web forms? – Agah Toruk Mar 09 '18 at 14:09

11 Answers11

51

In case anyone is still interested, you can test for a POST from inside an MVC Action Method like this:

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

}
Nuri
  • 557
  • 4
  • 2
  • Thank you for this, this is the exact way you need to do it in MVC! – Sean Haddy Jun 14 '11 at 20:44
  • 4
    AVOID THIS AT ALL COSTS. Your controller code should be organized by methods. Your HttpGet method ie [HttpGet] should be completely separate than your [HttpPost] method. There are many reasons for this, testability being one, readability, etc. See tvanfosson's answer below. – Adam Tuliper Feb 24 '12 at 17:23
  • 1
    still helpful in 2012 +1 for that – patel.milanb Jul 13 '12 at 14:39
  • 6
    What do you mean "avoid this at all costs"? What if you want a javascript flag whether or not to execute a script? There's no other way of doing this... – Nick Aug 01 '13 at 13:56
  • 1
    -1: This doesn't distinguish between postbacks and AJAX posts. – Vivian River Aug 02 '13 at 19:42
15

There is no IsPostBack -- everything is either a POST or GET (or other HTTP verb). You can limit the HTTP verbs that your action allows, i.e., you'll never see a request from a disallowed verb, using the AcceptVerbsAttribute. For example, the following only allows POSTs.

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

If you need to have the same action name do both GET/POST and they actually do different things, you can either give them separate signatures or use the ActionNameAttribute to alias one of the actions so the methods can have different names.

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

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

OR

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

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

EDIT: Note that I've added the antiforgery token validation to the POST actions. You really should be using this to protect against cross-site scripting attacks.

tvanfosson
  • 524,688
  • 99
  • 697
  • 795
11

You can use this piece of code in Razor

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

I often use this Method (declared on my BaseController class)

 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;
 }
Frank Fajardo
  • 7,034
  • 1
  • 29
  • 47
ibirite
  • 485
  • 4
  • 5
3

Controllers do not inherit from System.Web.UI.Page. There is no isPostback property.

Chad Ruppert
  • 3,650
  • 1
  • 19
  • 19
2

For Asp.net Core 2.x you could create an extension method on HttpRequest. Based on @ibirite answer could be something like this:

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;
        }
    }
}

acromm
  • 880
  • 13
  • 24
0

If you have more than one form in an MVC page, you can add a hidden input within the form with a meaningful ID and test if it has a value. This way you do not need to have two separate handlers (one for get and one for post).

So inf the page and inside the form:

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

And in the controller :

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

Hope it helps!

0

The MVC framework doesn't support the classic postback and viewstate used in the Web forms. So, no, you don't have access to the IsPostBack.

My advice to you is to have two branches: one with the current site where you're adding patches for known errors and another one where you build a new site from scratch. New features should be implemented in this one. I assume that most of your codebase is re-usable in the new site.

When the new site is ready, put it in production.

rguerreiro
  • 2,673
  • 3
  • 22
  • 23
0

Why are you trying to get that value from within a controller? Not sure if this will help you, but you can still use the traditional Request object to get info that was submitted by a form...

Luis Abreu
  • 4,008
  • 9
  • 34
  • 63
0

I'm not sure if I understood your question correctly, but on the controller you would have an action that handles the initial GET from the browser and a second action to handle POSTs.

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

 public ActionResult Create()
 {...}
Nate
  • 71
  • 1
  • 5
0

I would definitely take a look at this blog post by Scott Hanselman where he puts an aspx page in a MVC application.

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

Your controllers will not have access to the ViewState property. Even if you did want to handle the problem of __VIEWSTATE, you would have to do some work in order to get it into a usable form in an mvc controller. Good luck on coming up with a conversion strategy, no matter how it works out a lot of people would be interested to know kind of problems you would face in the process.

Min
  • 2,975
  • 1
  • 19
  • 24