代码之家  ›  专栏  ›  技术社区  ›  Mark Brittingham

实现WebApi控制器-为什么IDisposable的使用会干扰路由?

  •  1
  • Mark Brittingham  · 技术社区  · 11 年前

    我已经实现了一个WebApi类:

    public class ControllerCore : ApiController 
    {
        ...do some basic things...
    }
    

    然后在派生类中具有:

    public class LoginController : ControllerCore
    {
        public HttpResponseMessage Get()
        {
           // Get login status
        }
    
        public HttpResponseMessage Post([FromBody]LoginParams login)
        {
           // Do actual log in
        }
     }
    

    这一切都很好。但我愿意 喜欢 为了使ControllerCore是一次性的,这样我就可以创建和清理包含开放数据库连接的托管对象:

    public class ControllerCore : ApiController, IDisposable
    {
        protected DataAccess DAL;
        private bool isDalDisposed;
    
        public ControllerCore()
            : base()
        {
            DAL = new DataAccess();  // opens a connection that will have to be cleaned up
            isDalDisposed = false;
        }
    
        public new void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    
        protected override void Dispose(bool disposing)
        {
            if (!isDalDisposed)
            {
                isDalDisposed = true;
                if (disposing)
                    DAL.Dispose();
            }
            base.Dispose(disposing);
        }
    
        ...other code here...
    }
    

    问题是,虽然LoginController上的“Get”仍然有效,但“Post”从未被调用——但该路线似乎不起作用。由于唯一的区别是Post有参数,我想知道一次性修改是否以某种方式扰乱了从JSON到LoginParams对象的转换。

    任何帮助都是 大大地 非常感谢!

    2 回复  |  直到 11 年前
        1
  •  7
  •   Olav Nybø    11 年前

    我的猜测是,来自Web API的响应是:找到了与请求匹配的多个操作。

    因为您的控制器有两个与Post请求匹配的方法,所以Web API路由被搞砸了。 默认情况下,API控制器上任何与选择操作方法的规则不匹配的公共方法都被视为Post方法。 你可以找到更多关于这个主题的信息 here .

    要解决您的问题,只需将[NonAction]属性添加到Dispose方法中,这样Web API就会忽略它。

        2
  •  2
  •   John C    7 年前

    事实上 System.Web.Http.ApiController 已实现IDisposable:

    因此,如果您的控制器持有数据库连接,请执行以下操作:

    public class ValuesController : ApiController
    {
        private Model1Container _model1 = new Model1Container();
    
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_model1 != null)
                {
                    _model1.Dispose();
                }
            }
            base.Dispose(disposing);
        }
    }