叫另一个api控制器

时间:2014-01-31 17:12:10

标签: c# asp.net-mvc asp.net-web-api

当我调用用户控制器(api / user)时,我能够传递用户凭据,但应用程序在值控制器中崩溃时出现空异常错误(值不能为空):

   public class ValuesController : ApiController
   {
   private cdwEntities db = new cdwEntities();

   public HttpResponseMessage Get([FromUri] Query query)
   {
       var data = db.database.AsQueryable();

       if (query.name != null)
       {
           data = data.Where(c => c.Name == query.name);
       }

       if (query.price != null)
       {
           data = data.Where(c => c.Price == query.price);
       }


       if (!data.Any())
       {
           var message = string.Format("error");
           return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
       }

       ***return Request.CreateResponse(HttpStatusCode.OK, data);***
   }

}

我认为这个错误是因为valuescontroller方法无法传递空值,因为它总是传递参数(即api / values / name = tom),因此当我调用用户控制器时,它会抛出null错误,因为系统没有传递任何参数从用户控制器进入Valuescontroller。

public class UserController : ApiController
{
    [Authorize]
    public HttpResponseMessage Get([FromUri] Query query)
    {
        if (User.IsInRole("user"))
        {
            var result = new itemController();
            return result.Get(query);
        }

        var message = string.Format("No data was found");
        return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
    }

}

他们可以使用一些内置函数来解决这个问题或我应该研究的任何框架/库吗? 非常感谢你的帮助和时间。

2 个答案:

答案 0 :(得分:1)

其他人已经指出你不应该经常(永远?)从另一个调用一个视图控制器端点,但是在你需要/想要的情况下,你需要确保目标已经正确初始化。这是使用ControllerBuilder完成的。

所以而不是:

var result = new itemController();
return result.Get(query); // this will blow up!

你会这样做:

IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
itemController c = (itemController) factory.CreateController(
    ControllerContext.RequestContext, "item");
return c.Get(query);

这将确保已使用所有必要的上下文初始化目标视图控制器。

答案 1 :(得分:-1)

您不应该从其他API端点调用一个API端点方法。相反,您需要在API,业务逻辑层和数据访问层之间进行适当的代码隔离。我会这样做 -

API -

    public class UserController : ApiController
    {
        [Authorize]
        public HttpResponseMessage Get([FromUri] Query query)
        {
            BusinessLayer layer = new BusinessLayer();
            if (User.IsInRole("user"))
            {
                var result = layer.GetData(query);
                // use result here and return HttpResponseMessage
                var message = string.Format("No data was found");
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
            }
        }
    }

在您的业务逻辑层 -

   public ResultModel Get(Query query)
   {
       // Process your model Query here... and then return some meaningful result here...
       // Also call Data Access Layer Methods from here, instead of making direct database
       // (entity framework) calls...
   }

对于更好的灵活和松散耦合的系统,您需要Dependency Injection (probably using Unity, but there are many other options like Autofac, Ninject etc.)