MVC异步方法在构造函数控制器中

9 浏览
0 Comments

MVC异步方法在构造函数控制器中

我正在尝试制作一个动态菜单(存储在数据库中),它将显示在所有Web应用程序页面上。

使用Google搜索,我发现最好将菜单视图作为主视图(_Layout.cshtml)的一部分。因此,控制器的每个操作方法都必须包含菜单模型的数据。为了避免代码重复,我找到了创建基本控制器并使用其构造函数提供数据的解决方案:

https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/views/passing-data-to-view-master-pages-cs

另外,我正在尝试使用异步/等待的可能性,我的PageService(菜单)正在使用ToListAsync()从数据库获取数据。所以现在我有一个问题,BaseController构造函数有一个异步方法:

public class BaseController : AsyncController, IBaseController
{
    private readonly IPageService _pageService;
    public BaseController(IPageService pageService)
    {
        _pageService = pageService;
        SetBaseViewModelAsync();
    }
    private async Task SetBaseViewModelAsync()
    {
        ViewData["Pages"] = await _pageService.GetAllAsync();
    }
}

我知道这是糟糕的代码,但我不知道如何正确设计这种情况。也许有另一种更好的方法来创建动态菜单,或者以异步方式获取数据的另一种方法?

此外,我找到了这篇文章,但我不知道是否可以应用其解决方案,因为我不知道是否可以处理控制器实例的创建:

http://blog.stephencleary.com/2013/01/async-oop-2-constructors.html

0
0 Comments

问题的原因是Html.RenderAction方法无法与异步控制器操作一起使用,这导致了"HttpServerUtility.Execute blocked..."异常的出现。解决方法是将控制器操作改为同步调用。

在这个问题中,作者在视图中使用了Html.RenderAction方法来调用控制器的Index操作。控制器是一个异步控制器,实现了AsyncController接口,并且依赖于IPagesService接口。在控制器的构造函数中,通过参数注入的方式将IPagesService的实例赋值给_pagesService字段。

控制器中的IndexAsync操作是一个异步方法,它调用了_pagesService的GetAllAsync方法来获取数据,并将数据传递给MenuPartial部分视图。然而,由于Html.RenderAction不支持异步控制器操作,所以会出现"HttpServerUtility.Execute blocked..."异常。

根据作者提供的链接,可以看到有人在Stack Overflow上提出了同样的问题,并得到了解答。解答中指出,Html.RenderAction方法只能与同步的控制器操作一起使用。因此,解决方法是将异步控制器操作改为同步调用。

经过修改后的控制器代码如下所示:

public class PagesController : Controller, IPagesController
{
    private readonly IPagesService _pagesService;
    public PagesController(IPagesService pagesService)
    {
        _pagesService = pagesService;
    }
    [HttpGet]
    [Route("")]
    public ActionResult Index()
    {
        var viewModel = _pagesService.GetAll();
        return PartialView("MenuPartial", viewModel);
    }
}

通过将控制器操作改为同步的Index方法,并在其中直接调用_pagesService的同步方法GetAll来获取数据,就可以解决Html.RenderAction与异步控制器操作不兼容的问题。

本文介绍了在MVC应用程序中使用Html.RenderAction方法时遇到的问题以及解决方法。问题的原因是Html.RenderAction不支持异步控制器操作,解决方法是将异步控制器操作改为同步调用。通过将控制器操作改为同步方法,可以避免"HttpServerUtility.Execute blocked..."异常的出现。

0
0 Comments

问题出现的原因:

- ASP.NET MVC(1-5)中没有很好的解决方案来运行异步代码。

- 子操作(Child Actions)无法是异步的。

- 渲染(Render)和局部视图(Partials)无法是异步的。

解决方法:

- 不要将所有内容都派生自基本控制器,而是创建一个名为MenuController的控制器。

- 创建一个名为Default的方法,并从布局中调用它。

- 在布局中使用RenderAction方法调用Default方法。

- 调用异步方法,但它将以同步方式运行。

这是最简单和最干净的解决方案。最大的优点是可以控制菜单的缓存,与调用方法分开。为了保持代码同步,决定不使用子操作。调用同步方法似乎是无法解决异步代码的问题。

文章如下:

在ASP.NET MVC中,如果要从一个基本控制器中派生出所有内容,可能需要进行很多的额外工作和测试。但是,有一种更简单和更干净的解决方案。您只需创建一个名为MenuController的控制器,创建一个名为Default的方法,并从布局中调用它。

[ChildActionOnly]
public Default()
{
  var viewModel = _pageService.GetAllAsync();
  return Partial(viewModel);
}

在布局中使用RenderAction方法调用Default方法。

@{Html.RenderAction("Default", "Menu");}

这是最简单和最干净的解决方案。最大的优点是可以控制菜单的缓存,与调用方法分开。在ASP.NET MVC(1-5)中,没有很好的解决方案来运行异步代码。子操作无法是异步的,渲染和局部视图无法是异步的。尽管可以调用异步方法,但它将以同步方式运行。

在调用同步方法中调用异步代码并不是一个好主意。因此,决定不使用子操作。调用同步方法似乎是无法解决异步代码的问题。

希望这篇文章对您有所帮助!感谢您的阅读!

0