C# 在 ASP.NET MVC 中处理 post 请求

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2321043/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 01:24:14  来源:igfitidea点击:

Handling post requests in ASP.NET MVC

c#.netasp.net-mvcposthttprequest

提问by Alex

Recently I started working with MVC, before that I used "classic" ASP.NET.

最近我开始使用 MVC,在此之前我使用了“经典”的 ASP.NET。

After using Ruby on Rails (RoR), I wonder how to implement POST request handling in MVC similar to how RoR operates. In RoR you use the Postmethod, so you need only one function for a view.

使用 Ruby on Rails (RoR) 后,我想知道如何在 MVC 中实现类似于 RoR 操作的 POST 请求处理。在 RoR 中,您使用该Post方法,因此视图只需要一个函数。

In ASP.NET MVC I need to use 2 separate functions for GETand for POST, so I need to initialize the same data twice, and I don't like to repeat something in my code.

在 ASP.NET MVC 中,我需要使用 2 个单独的函数 forGET和 for POST,所以我需要两次初始化相同的数据,而且我不想在我的代码中重复某些内容。

How can I check if the request is POSTin one method?

如何检查请求是否POST采用一种方法?

Update:

更新:

Solution is found: I have to use Request.HttpMethod.

找到解决方案:我必须使用Request.HttpMethod。

Thank you!

谢谢!

采纳答案by JonoW

You only need separate methods for GET and POST if their method signatures differ, there's no reason why one action method can't handle GET and POST methods.

如果 GET 和 POST 的方法签名不同,您只需要单独的方法,没有理由为什么一种操作方法不能处理 GET 和 POST 方法。

If you need to know whether it was a GET or POST, you could check using Request.HttpMethod in your action, but I would advise using a separate method decorated with the [AcceptVerbs(HttpVerbs.Post)] attribute as suggested by the other posters.

如果您需要知道它是 GET 还是 POST,您可以在您的操作中使用 Request.HttpMethod 检查,但我建议使用其他海报建议的用 [AcceptVerbs(HttpVerbs.Post)] 属性装饰的单独方法.

回答by Darin Dimitrov

You may take a look at the Request.HttpMethodproperty.

您可以查看Request.HttpMethod属性。

回答by David Morton

You don't check in ASP.NET MVC. You decorate your method with the [AcceptVerbs(HttpVerbs.Post)]attribute to indicate that the method applies to post only, and accept the model in the method used to handle the post.

您不检查 ASP.NET MVC。你用[AcceptVerbs(HttpVerbs.Post)]属性装饰你的方法以表明该方法只适用于发布,并在用于处理发布的方法中接受模型。

I'd strongly suggest doing the walkthrough for NerdDinnerto understand more about the ASP.NET MVC framework.

我强烈建议对NerdDinner进行演练,以了解有关 ASP.NET MVC 框架的更多信息。

回答by Amitabh

Correct way to do is using ModelBinding during Post request.

正确的做法是在 Post 请求期间使用 ModelBinding。

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(EmployeeViewModel model)
{
 //validate data, save employee, handle validation errors...
}

This way you will not have to init your data again.

这样您就不必再次初始化您的数据。

回答by Dr. Wily's Apprentice

I came across this question wanting to know the same thing. Below is a detailed description of my situation and the solution that I used (which utilizes the other answers provided here). I originally tried to use the two separate method approach, but I ran into a problem when the method signatures of these methods became identical.

我遇到了这个问题,想知道同样的事情。以下是我的情况和我使用的解决方案的详细描述(利用此处提供的其他答案)。我最初尝试使用两种单独的方法方法,但是当这些方法的方法签名变得相同时,我遇到了问题。

I have a page that displays report data. At the top of the page there is a form with some fields, which allow the user to specify report parameters such as start date, end date, etc.

我有一个显示报告数据的页面。在页面顶部有一个包含一些字段的表单,允许用户指定报告参数,例如开始日期、结束日期等。

I originally approached this by creating two separate methods to handle the Get and the Post methods. The post method would redirect the browser to the get method so that any parameters that were specified would be added to the query string and so that the browser would not prompt the user with a dialog saying that it is going to resend the data that they entered if they refresh. Note: I realized later that I could accomplish this by setting the method attribute of my form element to "Get", but I think ideally a controller shouldn't have knowledge of how a view is implemented, so in my opinion that is irrelevant.

我最初通过创建两个单独的方法来处理 Get 和 Post 方法来解决这个问题。post 方法会将浏览器重定向到 get 方法,以便将指定的任何参数添加到查询字符串中,这样浏览器就不会通过对话框提示用户将重新发送他们输入的数据如果他们刷新。注意:我后来意识到我可以通过将表单元素的 method 属性设置为“Get”来实现这一点,但我认为理想情况下控制器不应该知道视图是如何实现的,所以在我看来这是无关紧要的。

As I developed these two methods I eventually found myself in a situation where the method signatures became identical. Furthermore, my code for these two methods became nearly identical, so I decided to merge them into a single method and to just check the request verb so that I could do something slightly different when the request is not a "Get". A distilled example of my two methods is shown below:

当我开发这两种方法时,我最终发现自己处于方法签名变得相同的情况。此外,我为这两种方法编写的代码变得几乎相同,因此我决定将它们合并为一个方法并只检查请求动词,以便在请求不是“Get”时可以做一些稍微不同的事情。我的两种方法的蒸馏示例如下所示:

    // this will not compile because the method signatures are the same

    public ActionResult MyReport(DateRangeReportItem report)
    {
        // if there are no validation errors and the required report parameters are completed
        if (ModelState.IsValid && report.ParametersAreComplete)
        {
            // retrieve report data and populate it on the report model
            report.Result = GetReportData(report.CreateReportParameters());
        }

        return View(report);
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult MyReport(DateRangeReportItem report)
    {
        if (ModelState.IsValid && report.ParametersAreComplete)
        {
            // redirect to the same action so that if the user refreshes the browser it will submit a get request instead of a post request
            // this avoids the browser prompting the user with a dialog saying that their data will be resubmitted
            return RedirectToAction("MyReport", new { StartDate = report.StartDate, EndDate = report.EndDate });
        }
        else
        {
            // there were validation errors, or the report parameters are not yet complete
            return View(report);
        }
    }

Why am I accepting a model object as the parameter to my get method? The reason is that I wanted to take advantage of the validation logic already built into the model object. If someone navigates to my page directly with all parameters already specified in the query string, then I want to go ahead and retrieve the report data and display it on the page. However, if the parameters specified in the query string are invalid then I also want validation errors to appear on the page. By putting my model object as the parameter, the MVC framework will automatically attempt to populate it and will capture any validation errors without any additional work on my part.

为什么我接受模型对象作为我的 get 方法的参数?原因是我想利用已经内置到模型对象中的验证逻辑。如果有人使用查询字符串中已经指定的所有参数直接导航到我的页面,那么我想继续检索报告数据并将其显示在页面上。但是,如果查询字符串中指定的参数无效,那么我还希望页面上出现验证错误。通过将我的模型对象作为参数,MVC 框架将自动尝试填充它并捕获任何验证错误,而无需我做任何额外的工作。

I used the other answers posted for this question to create a RequestHttpVerb property on a base controller class in my project:

我使用针对此问题发布的其他答案在我的项目中的基本控制器类上创建 RequestHttpVerb 属性:

    public HttpVerbs RequestHttpVerb
    {
        get { return (HttpVerbs)Enum.Parse(typeof(HttpVerbs), this.Request.HttpMethod, true); }
    }

So finally my consolidated method looks like the following:

所以最后我的综合方法如下所示:

    [AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
    public ActionResult MyReport(DateRangeReportItem report)
    {
        // check if there are any validation errors in the model
        // and whether all required report parameters have been completed
        if (ModelState.IsValid && report.ParametersAreComplete)
        {
            // this is unnecessary if the form method is set to "Get"
            // but within the controller I do not know for sure if that will be the case in the view
            if (HttpVerbs.Get != this.RequestHttpVerb)
            {
                // redirect to the same action so that if the user refreshes the browser it will submit a get request instead of a post request
                // this avoids the browser prompting the user with a dialog saying that their data will be resubmitted
                return RedirectToAction("MyReport", new { StartDate = report.StartDate, EndDate = report.EndDate });
            }

            // there were no validation errors and all required report parameters are complete
            // retrieve report data and populate that data on the model
            report.Result = GetReportData(report.CreateReportParameters());
        }

        // display the view with the report object
        // Any model state errors that occurred while populating the model will result in validation errors being displayed
        return View(report);
    }

That's my current solution to the problem. I would prefer not to have to check the Request.HttpMethod property in order to determine whether I needed to perform the redirect, but I didn't see another solution to my problem. I would have been fine with keeping two separate methods to handle Get and Post requests, but the identical method signature prevented this. I would have preferred to rename my Post action handler method to avoid the method signature conflict and to use some mechanism to indicate to the MVC framework that my renamed method should still handle the "MyReport" action, but I am not aware of any such mechanism in the MVC framework.

这是我目前解决问题的方法。我不想检查 Request.HttpMethod 属性以确定是否需要执行重定向,但我没有看到我的问题的其他解决方案。我本来可以保留两个单独的方法来处理 Get 和 Post 请求,但是相同的方法签名阻止了这一点。我宁愿重命名我的 Post 操作处理程序方法以避免方法签名冲突,并使用某种机制向 MVC 框架指示我重命名的方法仍应处理“MyReport”操作,但我不知道任何此类机制在MVC框架中。