随笔 - 153  文章 - 1  评论 - 1722  阅读 - 215万

oXite源码学习导读二:Action的返回类型与IActionInvoker

我们先来看一下oXite里面一段Controller中Action方法的代码:

namespace Oxite.Controllers
{
    public class AreaController : Controller
    {
        [ActionName("Find"), AcceptVerbs(HttpVerbs.Post)]
        public virtual OxiteModelList<Area> FindQuery(AreaSearchCriteria searchCriteria)
        {
            IList<Area> foundAreas = areaService.FindAreas(searchCriteria);
            OxiteModelList<Area> model = new OxiteModelList<Area> { List = foundAreas };

            model.AddModelItem(searchCriteria);

            return model;
        }

看出上面的Action方法有什么不妥么?怎么Action方法返回的类型为OxiteModelList<Area>的呢?Controller的Action方法返回的不是ActionResult或者为Void的么?难道Action的返回值还可以是任意类型的?相信你看到Controller里面Action方法这些代码的时候,你也会产生这样的疑问。

默认情况下Action的返回值应该是ActionResult(推荐)或者void。那么这里为什么可以返回一个数据集合呢?你或许会想OxiteModelList<Area>会不会是继承自ViewResult呢?很遗憾的OxiteModelList<Area>并没是继承自ViewResult。正当我郁闷的时候,忽然看到ContainerFactory里面对IActionInvoker进行了Ioc注册:

image

于是很兴奋的跑去OxiteControllerActionInvoker里面看个究竟,果然是在这里做了手脚:

namespace Oxite.Infrastructure
{
    public class OxiteControllerActionInvoker : ControllerActionInvoker
    {
        private readonly IFilterRegistry filterRegistry;

        public OxiteControllerActionInvoker(IFilterRegistry filterRegistry)
        {
            this.filterRegistry = filterRegistry;
        }

        protected override ActionResult CreateActionResult
(ControllerContext controllerContext, ActionDescriptor actionDescriptor, object actionReturnValue) { if (actionReturnValue == null) { controllerContext.Controller.ViewData.Model = new OxiteModel { Container = new NotFoundPageContainer() }; return new NotFoundResult(); } if (typeof(ActionResult).IsAssignableFrom(actionReturnValue.GetType())) return actionReturnValue as ActionResult; controllerContext.Controller.ViewData.Model = actionReturnValue; return new ViewResult { ViewData = controllerContext.Controller.ViewData, TempData = controllerContext.Controller.TempData }; }

OxiteControllerActionInvoker的继承关系如下
OxiteControllerActionInvoker =>> ControllerActionInvoker –>> IActionInvoker 。

OxiteControllerActionInvoker重写了ControllerActionInvoker的CreateActionResult方法,该方法有一个命名为actionReturnValue的参数,从参数的命名我们很容易就可以看出这个参数的意义,没错她就是我们Action中返回的结果,从上面的代码我们可以看到将actionReturnValue赋值给了ViewData.Model,然后重新构造一个ViewResult的结果返回。相信看完上面的代码你已经豁然开朗了。

然后在OxiteControllerFactoryController的ActionInvoker修改为OxiteControllerActionInvoker

namespace Oxite.Infrastructure
{
    public class OxiteControllerFactory : DefaultControllerFactory
    {
        private readonly IUnityContainer container;

        public OxiteControllerFactory(IUnityContainer container)
        {
            this.container = container;
        }

        protected override IController GetControllerInstance(Type controllerType)
        {
            IController iController = container.Resolve(controllerType) as IController;

            if (typeof(Controller).IsAssignableFrom(controllerType))
            {
                Controller controller = iController as Controller;

                if (controller != null)
                    controller.ActionInvoker = container.Resolve<IActionInvoker>();

                return iController;
            }

            return iController;
        }
    }
}

前面已经对IActionInvoker进行了注册:

image

 

Enjoy。By Q.Lee.lulu

posted on   Q.Lee.lulu  阅读(2079)  评论(5编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
历史上的今天:
2008-03-30 广州.NET俱乐部的活动
< 2009年3月 >
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 1 2 3 4
5 6 7 8 9 10 11

点击右上角即可分享
微信分享提示