如何在项目MVC WebAPI上的控制器中应用拦截器?

时间:2015-07-29 10:14:09

标签: asp.net-web-api aop interceptor spring.net

我尝试在项目中使用拦截器

当我尝试调用控制器方法

时,我在spring.net中收到错误经典

堆栈跟踪:

  An error has occurred.","ExceptionMessage":"Unable to cast object of type 'CompositionAopProxy_f2b2933019534ca9be66f06255ab2271' to type 'xxx.API.Controllers.UserController'.","ExceptionType":"System.InvalidCastException","StackTrace":"   at lambda_method(Closure , Object , Object[] )
 at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass10.<GetExecutor>b__9(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"}

有不同文件的描述

Controller.cs:

[RoutePrefix("rest/users")]
public class UserController : BaseController,IUserController
{
    private static ILog log = LogManager.GetLogger(typeof(UserController));
private UserLogic userLogic { get; set; }


    public UserController() 
    {
       // userLogic = (UserLogicBase)xxx.ExceptionHandlingAspect.ExceptionHandlingAspect.GetProxy(new UserLogicImpl(), "GetAll|Get|Save|Update|Delete");
    }

     // GET: /api/users
    [HttpGet]
    [Authorize]
    [Route("",Name = "UserRoute")]
    public IHttpActionResult GetAll()
    {
      //  var start = DateTime.Now;
        Criterias criterias = InitContextFilter();
     //   var end = DateTime.Now;

      //  var res = end - start; 

        try
        {

            ICollection<User> users = userLogic.GetAll(criterias);
            ICollection<UserDTO> dtos = DTOFactory.convertUserDTOList(users);
            HttpContext.Current.Response.AppendHeader("total-count", criterias.Count.ToString());
            return Ok(dtos);
        }
        catch (Exception)
        {

            return new StatusCodeResult(HttpStatusCode.InternalServerError, this);
        }

    }


    // GET: /api/users/{Id}
    [HttpGet]
    [Authorize]
    [Route("{Id}")]          
    public IHttpActionResult Get(long Id)
    {           
        log.Debug("Get User");  

        User user = userLogic.Get(Id);
        if (user == null)
        {
            return NotFound();
        }
        UserDTO dto = DTOFactory.createDTO(user,false);

        return Ok(dto);
    }


    [HttpPost]
    [Route("")]
    public IHttpActionResult Create([FromBody] UserDTO dto)
    {
        try
        {
            User user = Mapper.Map<User>(dto);
            user = userLogic.Save(user);


            dto = DTOFactory.createDTO(user, false);
           return Created(Url.Route("UserRoute", null), dto);
        }
        catch (Exception)
        {

            return new StatusCodeResult(HttpStatusCode.Unauthorized, this);
        }

    }

    [HttpPut]
    [Authorize]
    [Route("{Id}")]
    public IHttpActionResult Update(long Id, [FromBody] UserDTO dto)
    {
        try
        {
            User update = userLogic.Get(Id);
            if (update != null || Id != dto.id.Value)
            {
                DTOFactory.applyPropertiesTo(dto, update);
               update = userLogic.Update(update);

                dto = DTOFactory.createDTO(update);
                return Ok(dto);
            }
            else
            {
                return new StatusCodeResult(HttpStatusCode.NotFound, this);
            }
        }
        catch (Exception)
        {
            return new StatusCodeResult(HttpStatusCode.InternalServerError, this);
        }

    }

    [HttpDelete]
    [Authorize]
    [Route("{Id}")]
    public IHttpActionResult Delete(long Id)
    {

        try
        {
            User update = userLogic.Get(Id);
            if (update != null)
            {
                var user = userLogic.Delete(Id);

                UserDTO dto = DTOFactory.createDTO(user);
                return Ok(dto);
            }
            else
            {
                return new StatusCodeResult(HttpStatusCode.NotFound, this);
            }
        }
        catch (Exception)
        {
            return new StatusCodeResult(HttpStatusCode.InternalServerError, this);
        }
    }

}

界面:

interface IUserController
{

    IHttpActionResult GetAll();
    IHttpActionResult Get(long Id);
    IHttpActionResult Create([FromBody] UserDTO dto);
    IHttpActionResult Update(long Id, [FromBody] UserDTO dto);
    IHttpActionResult Delete(long Id);

}

config xml:

&#13;
&#13;
  <object id="debugInterceptor" type="xxx.API.Interceptors.DebugInterceptor, xxx.API"/>

  <object id="UserController" singleton="false" type="xxx.API.Controllers.UserController, xxx.API">
    <property name="userLogic">
      <ref object="UserLogicImpl" />
    </property>
  </object>

 <object id="ProxyCreator" type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop">
    <property name="ObjectNames">
      <list>
        <value>*Controller</value>
      </list>
    </property>
    <property name="InterceptorNames">
      <list>
        <value>debugInterceptor</value>
      </list>
    </property>
  </object>
&#13;
&#13;
&#13;

Startup.cs

  public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {            
        var config = new HttpConfiguration();
        config.DependencyResolver = new SpringDependencyResolver(ContextRegistry.GetContext());
        WebApiConfig.Register(config);
        app.UseCors(CorsOptions.AllowAll);  // TODO: change option to only allow the web application domain
        ConfigureAuth(app);
        app.UseWebApi(config);

    }
}

public class SpringDependencyResolver : IDependencyResolver
{
    private readonly IApplicationContext _appContext;

    public SpringDependencyResolver(IApplicationContext appContext)
    {
        _appContext = appContext;
    }

    public void Dispose()
    {
        _appContext.Dispose();
    }

    public object GetService(Type serviceType)
    {
        IDictionary<string, object> objects = _appContext.GetObjectsOfType(serviceType);
        return objects.Values.FirstOrDefault();
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        IDictionary<string, object> objects = _appContext.GetObjectsOfType(serviceType);
        return objects.Values;
    }

    public IDependencyScope BeginScope()
    {
        return new SpringDependencyResolver(_appContext);
    }
}

拦截器:

 public class DebugInterceptor : IMethodInterceptor
{
    public object Invoke(IMethodInvocation invocation)
    {
        Console.WriteLine("Before: " + invocation.Method.ToString());
        object rval = invocation.Proceed();
        Console.WriteLine("After:  " + invocation.Method.ToString());
        return rval;
    }

}

任何人都可以解释真正的问题并帮助我找到在控制器网络上添加拦截器的解决方案Api

1 个答案:

答案 0 :(得分:0)

您需要创建基于继承的代理, WebAPI 将尝试强制转换为控制器,使用您创建的代理不会从您的类派生的默认值。

只需添加到您的代理创建者:

<property name="ProxyTargetType" value="true" />

像这样:

<object id="ProxyCreator" type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop">
<property name="ObjectNames">
  <list>
    <value>*Controller</value>
  </list>
</property>
<property name="ProxyTargetType" value="true" />
<property name="InterceptorNames">
  <list>
    <value>debugInterceptor</value>
  </list>
</property>
</object>

ProxyTargetType设置为true时,您需要确定,您的方法为virtual,否则将不会被拦截