ASP.NET MVC Web Api重用

时间:2012-09-12 15:45:49

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

在有“web api”之前,必须执行JsonResult GetPersons(..)类型的操作。现在,使用web api,可以有List<Person> GetPersons(..)

我认为这一点的重点在于重新使用这些动作,即:从另一个动作调用GetPersons(也许是ActionResult GetPersons(..))。

但在经历了许多序列化问题后,我发现这不是一个选择。例如,就像对象内部有一个枚举一样简单,它不能被序列化为json。

所以我最终得到了许多dynamic X(...)返回的匿名类型,我无法重用我的API的许多东西。 Anny的建议?

重复代码的示例如下:

JSON:

from a in b select new { ... }

不是json

from a in b

另外,我在很多论坛中都读到了不适合返回EF对象本身的内容,而这正是web api的动机(以及[ScriptIgnore]的存在)

问题:如何在API和普通控制器中重用查询?

1 个答案:

答案 0 :(得分:3)

  

如何在API和普通控制器中重用查询?

不在API或MVC控制器中定义查询。您可以在MVC项目外部的共享程序集中定义查询,并让控制器调用该层。

示例:

<强>外部化

public interface IQuery<TResult> {}

public interface IQueryProcessor
{
    TResult Execute<TResult>(IQuery<TResult> query)
}

public class MyQueryObject : IQuery<MyEntity[]>
{
    public string QueryParam1 { get; set; }
    public int QueryParam2 { get; set; }
}

API控制器

public class MyApiController : ApiController
{
    private readonly IQueryProcessor _queryProcessor;

    public MyApiController(IQueryProcessor queryProcessor)
    {
        _queryProcessor = queryProcessor
    }

    public IEnumerable<MyApiModel> Get
        ([FromUri] string queryParam1, int queryParam2)
    {
        var query = new MyQueryObject
        {
            QueryParam1 = queryParam1,
            QueryParam2 = queryParam2,
        };
        var results = _queryProcessor.Execute(query);
        return Mapper.Map<IEnumerable<MyApiModel>>(results);
    }
}

MVC控制器

public class MyMvcController : Controller
{
    private readonly IQueryProcessor _queryProcessor;

    public MyMvcController(IQueryProcessor queryProcessor)
    {
        _queryProcessor = queryProcessor
    }

    public ViewResult Index(string queryParam1, int queryParam2)
    {
        var query = new MyQueryObject
        {
            QueryParam1 = queryParam1,
            QueryParam2 = queryParam2,
        };
        var results = _queryProcessor.Execute(query);
        var models = Mapper.Map<IEnumerable<MyViewModel>>(results);
        return View(models);
    }
}