MVC 5 restricts all HTTP requests from POST mode

  • 2021-09-24 21:57:07
  • OfStack

Today, a colleague raised a question that he wanted to limit all HTTP requests received by MVC to POST.

Next, in the following content, I will share my ideas with you. If you have other ways, please leave a message.

1. HttpPostAttribute features

When you first thought of it, MVC provides HttpPostAttribute feature, which is used to restrict HTTP requests to be submitted in POST mode.


public class HomeController : Controller
 { 
 [HttpPost]
 public ActionResult Index()
 {
  return View();
 }
 }

This feature can only be marked on Action methods, which requires us to mark every Action method and make one Coder. In this way, we definitely can't accept it.


//
 //  Summary :
 //  Denote 1 Property, which is used to restrict the operation method so that the method only handles  HTTP POST  Request. 
 [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
 public sealed class HttpPostAttribute : ActionMethodSelectorAttribute
 {

 }

2. Use HttpModule

In the Asp. Net pipeline, HttpModule can control all HTTP requests by registering its own event handler for events in HttpApplication objects.


public class HttpMethodModule : IHttpModule
 {
 public void Init(HttpApplication context)
 {
  context.PostMapRequestHandler += Context_PostMapRequestHandler;
 }

 private void Context_PostMapRequestHandler(object sender, EventArgs e)
 {
  HttpApplication httpApplication = (HttpApplication) sender;
  HttpContext httpContext = httpApplication.Context;


  // Determine whether you are currently using  MVC  Framework to process requests, and other requests are not controlled. 
  MvcHandler mvcHandler = httpContext.Handler as MvcHandler;

  if (mvcHandler != null && httpContext.IsPostMethod() == false) {
  throw new HttpException(404, " The accessed resource does not exist. ");
  }
 }

 public void Dispose()
 {

 }
 }

Add related configuration in Web. config.


<?xml version="1.0" encoding="utf-8"?>
<configuration>
 <system.webServer>
 <modules>
 <add name="HttpMethod" type="HttpPostWebApp.Web.HttpMethodModule, HttpPostWebApp"/>
 </modules>
 </system.webServer>
</configuration>

After testing, it can meet our requirements (there is no demonstration about the test results).

3. MVC Filter

In MVC, requests can be controlled through global filters.


public class HttpPostFilter : IAuthorizationFilter
 {
 public void OnAuthorization(AuthorizationContext filterContext)
 {
  if (filterContext.HttpContext.IsPostMethod() == false) {

  // If not POST Request, return 404 . 
  filterContext.Result = new HttpNotFoundResult();
  }
 }
 }

Register as a global filter when the program starts.


public class FilterConfig
 {
 public static void RegisterGlobalFilters(GlobalFilterCollection filters)
 {
  filters.Add(new HttpPostFilter());
 }
 }

4. Routing constraints

When registering a route, you can define constraints on the route. The request mode can be limited to POST request in the following ways.


public class RouteConfig
 {
 public static void RegisterRoutes(RouteCollection routes)
 {
  routes.MapRoute(
  name: "Default",
  url: "{controller}/{action}/{id}",
  defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
  // Restriction request mode must be POST
  , constraints:new { httpMethod = new HttpMethodConstraint("POST")}
  );
 }
 }

5. Override the Controller method

In MVC, all controllers inherit from Controller by default.

We can define an abstract class of BaseController, override OnActionExecuting, and all other controllers inherit from BaseController.


public abstract class BaseController : Controller
 {
 protected override void OnActionExecuting(ActionExecutingContext filterContext)
 {
  
  if (filterContext.HttpContext.IsPostMethod() == false) {
  // If not POST Request, return 404 . 
  filterContext.Result = new HttpNotFoundResult();
  }
  else {
  base.OnActionExecuting(filterContext);
  }
 }
 }

This method, which requires modifying the base classes of all controllers, is not recommended.

Of course, if you have already defined your own controller base class, the workload of this method is very small.

Summarize

Of the above five methods, 2. 3. 4 is very simple, but I recommend 4 because the maintenance effort is minimal if the requirements change.

If you have other ways, please leave a message, thank you!

Demo Download: mvchttppostwebapp


Related articles: