首页 > 解决方案 > ASP.NET Core MVC 中不同 HttpGet 方法之间的控制器属性不一致

问题描述

我有一个控制器,它具有页面使用的两种操作方法:

在浏览器中访问页面时调用的标准 OnGet 以及使用锚标记调用的另一个方法 SortData。

这两个方法都与控制器的同一个属性进行交互,但似乎每个方法都有两个不同的对象引用到该属性,因为 SortData 中的数据与 OnGet 中的日期不一致。

此外,如果我不在 Controller 的构造函数中而是在 OnGet 方法中初始化该属性,则它在 SortData 中将为 null,即使已首先调用 OnGet。

我的问题是如何让 SortData 使用与 OnGet 相同的属性?

代码如下所示:

public class MyController : Controller
{
    private MyClass Property {get; set;}

    public SearchController()
    {
        Property = new MyClass()
    }

    [HttpGet("sortdata")]
    public IActionResult SortData(string sortAttribute)
    {
        Property.SortData(sortAttribute);
        return View("Index", Property);
    }

    public IActionResult OnGet([FromQuery]string requeststring)
    {
        ViewData["Message"] = requeststring;
        Property.Datas = requeststring == null ?
            searchService.GetAll() :
            searchService.searchByRequestString(requeststring);
        return View("Index", Property);
    }
}

当然,OnGet 中使用的服务也在 Controller 中初始化,但我从示例中删除了它以保持它相当简单。

所以可以看到 OnGet 修改了 Property 并返回了 Index 页面。在该页面上,有一个调用 SortData 的锚点,它也修改了属性。但它与 OnGet 中的属性不同,它仍处于初始化状态。但我希望修改实际的属性,然后返回带有排序数据的索引页面。

标签: c#asp.net-coreasp.net-core-mvc

解决方案


是的,这是正确的行为。每个 Web 请求都存在于它自己的上下文中。您有两个 Web 请求,它为每个请求实例化一个新控制器,因此您当然没有相同的属性实例。

既然您知道这是正确的行为,您将需要提出一个新问题,即如何在多个请求之间共享一个属性。然而,这是一个错误的问题。答案是“你没有”。Web 请求应该是无状态的。相反,您应该将排序参数添加到查询参数中。


推荐阅读