基于Oracle的EntityFramework的WEBAPI2的实现(三)—— 建立APIController及设置返回类型JSON、XML等

建立普通的ApiControler

右击项目中的controller文件夹·添加·控制器·包含操作的webapi2控制器(使用entity framework),写个名字,如果:Test。然后选择类,就是我们刚刚从数据库映射过来的类,然后选择我们之前设置的连接字符串名称(我前面提到最好以Db开头,Con结尾的那个东西),点确定,然后会发现controller文件夹中多出了一个类TestContoller。

打开TestController.cs,看见里面帮助我们生成了GET,PUT,POST等方法。运行项目,发现已经可以请求到这个项目的GET方法了(我们可以在数据库里面手动加几条数据,我们就会看见返回数据了,正常 情况下,返回的是200我就认为是正确的请求)。

使用Area

前面我们是在默认的Controller中建立的ApiController,但是,我们的项目一般是复杂类型的,不可将所有的东西放在一个文件夹中,所以,我们要使用Area(区域)。右击项目中的Area文件夹,添加·区域,起个名字,然后确定。就会发现,在Area目录中多了那个我们的文件夹(假如名字叫TArea)。目录结构如图:

 

image

其实相当于我们又建立了一个子项目。但是有地方需要我们进行修改,就是路由,原因有如下几点:

  1. 路由可能会请求不到我们自定义的区域。
  2. 我区域中的控制器的命名空间和类名可能会和外部的控制器重复,导致路由找到两个。

那么我们就要做如下几点:

  1. 修改WEBAPI主路由设置类,将WebApiConfig.cs中的路由加上Area这个项。
  2. 修改Area下我们的区域内的AdminAreaRegistration.cs这个文件的内容。

个性WEBAPI主路由设置

代码如下:

public static void Register(HttpConfiguration config)
        {
            // Web API 配置和服务
            config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
            config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
            config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
            // Web API 路由
            config.MapHttpAttributeRoutes();
            config.Routes.MapHttpRoute(
                 name: "DefaultAreaApi",
                 routeTemplate: "Api/{area}/{controller}/{id}",
                 defaults: new { id = RouteParameter.Optional }
             );
            config.Filters.Add(new WebApi.Filters.ExceptionHandlingAttribute());
        }

config.Formatters的三条语句,其实就是在这一步顺便加上的,因为文章没必须再开一个区域写这段代码。config.Formatters是用来设置转换器的,一旦加上了text/plain和application/json等(默认xml已经有了),就可以根据用户请求时的content-type来返回与其一样的格式的内容。如,用户请求时content-type写的是application/json,数据也是application/json格式的,那么得到的返回的值也会是application/json格式。xml和text/html相同的原理。当然,如果用户在Accept头中强写了application/json等指定类型,那么不管用户请求的数据是什么格式以及content-type是如何设置的,asp.net都会根据Accept中的格式进行序列化返回结果给用户。我们加上上面那三句,纯是为了增加对json以及纯文件的支持。

routeTemplate是路由模板的设置,其中Api这个单词可以由我们自己定义,那么在以后,我们请求api的时候,就需要在域名后加上这个自定义的字符,来告诉ASP.NET我们要请求的是API,而不是正常的页面 或者 mvc的普通controller。我们会发现,这里和模板和mvc的模板不一样,因为这里少了{Action}。mvc一般会在{controller}后面跟{action},而这里没有,原因是我们的Action是Get、Post、Put、Delete等Http的Method方法,ASP.NET是直接根据HTTP请求的METHOD内容进行判断是要调用哪个Action的,因此这里根本没有{action}(也不能有啊,大哥)。{id}就不会说了,因为我们使用了EF,所以Id就代码我们的主键,在Put(修改)和Get(根据ID)取数据时是有用的。Defaults中的设置意思是id是可选的,也就是说,可以不填写,即Url中可以不存在这个id。

修改Area下我们的区域内的AdminAreaRegistration.cs

现在,我们需要让我们的Area向主模块中注册,其它这个注册操作是通过AdminAreaRegistration.cs来进行的,而vs本身也为我们自动生成了,但是,还是有地方是需要修改的,不然,会出现一些问题。修改后的代码如下:

public class AdminAreaRegistration : AreaRegistration 
    {
        public override string AreaName 
        {
            get 
            {
                return "Admin";
            }
        }

        public override void RegisterArea(AreaRegistrationContext context) 
        {
            string[] str = new string[]
            {
                "WebApi.Areas.Admin.Controllers"
            };
            context.MapRoute(
                "Admin_default",
                "Api/Admin/{controller}/{action}/{id}",
                new { action = "Index", id = UrlParameter.Optional },
                str
            );
        }
    }

我们继承了AreaRegistration这个父类,然后重写了AreaName这个方法 ,这个方法是主路由用来取我们这个区域的{Area}的(不知道{Area}干什么的请看上一小节的路由部分)。一旦总路由找到了对应的Area是我们的这个,就会把请求转到我们这个Area里面,由我们的Area路由进行处理。如果匹配到了对应的Controller和Action,那么就会调用这个Controller和Action进行处理。但是,需要注意的是,虽然我们区域中的ApiController在我们的区域文件夹中,但是,一旦编译成功,在DLL才不会分文件夹呢,所以,在其它的地方也有可能存在被找到的ApiController,这个会导致异常(如果找到两个的话)以及危险(没找到自己的反而找到别的地方的了)。这时,我们需要用命名空间来限定,这就是那个str数组变量的作用,它的内容是几个(一般是一个)命名空间,然后放到context.MapRoute中去。下次,这个区域的路由就到只在这几个命名空间内寻找。其实还有一个作用,就是你的ApiController在另一外项目或者DLL中,使用这个方法,完全可以将那些在外部的ApiController引用到这里被你的区域调用,是不是很爽?

调试一下,看一下能否请求到这个Area中的Controller吧,祝你成功。

转载请注明作者与出处:张峻崎 博客园

posted @ 2015-10-23 15:31  ensleep  阅读(4045)  评论(0编辑  收藏  举报