一、准备工作

1.visual studio nuget程序包源配置

源地址:
http://47.102.150.59:8087/nuget/

一些辅助功能包,能提高开发效率

2.创建项目

选择项目类型、自定义项目名称

3.基础配置

项目应用端口配置、ioc容器配置、日志配置、数据库配置、map映射配置…

 //program.cs
         public static void main(string[] args)
         {
             var config = new configurationbuilder()
                 .setbasepath(directory.getcurrentdirectory())
                 // 添加端口配置文件
                 .addjsonfile("hosting.json", true)
                 .build();
 
             var host = host.createdefaultbuilder(args)
                 // 添加autofac作为ioc容器
                 .useserviceproviderfactory(appserviceprovider.instance().autofacserviceproviderfactory)
                 .configurewebhostdefaults(webhostbuilder =>
                 {
                     webhostbuilder
                       .usecontentroot(directory.getcurrentdirectory())
                       .useconfiguration(config)
                       .usestartup<startup>();
                 })
                 .build();
 
             host.run();
         }
 //startup.cs
         public void configureservices(iservicecollection services)
         {
             mapperhelper.createmap();//map映射配置
             services.usencoreaspnet<ncoreaspnetoptions>(options =>
             {
                 //日志配置
                 options.log4netconfig = "log4net.config";
                 options.useupload = true;
                 options.useanycors = true;
                 options.apisecurityfilter = false;
                 //数据库配置
                 options.defaultdboptions = new defaultdboptions
                 {
                     dbsectionname = "dbconnectionsetting",
                     defaultconnectionname = "defaultconnection"
                 };
             });
         }

二、api实现

1.创建数据模型(viewmodel)

定义接口需要数据属性(名称、类型、约束等…)【属性命名规则全部用小写,方便前端 js 调用时不用检查某个属性大小写问题】

     /// <summary>
     ///用户基本信息
     /// </summary>
     public class userviewmmodel
     {
         /// <summary>
         /// 用户名
         /// </summary>
         public string user_name { get; set; } = "hanbing";
 
         /// <summary>
         /// 昵称
         /// </summary>
         public string nickname { get; set; } = "老卢聊技术";
 
         /// <summary>
         /// qq号码
         /// </summary>
         public string qq { get; set; } = "81868164";
 
         /// <summary>
         ///微信号码
         /// </summary>
         public string wxid { get; set; } = "hanbing_81868164";
 
         /// <summary>
         /// 地址
         /// </summary>
         public string address { get; set; }
 
         /// <summary>
         /// 年龄
         /// </summary>
         public int age { get; set; }
 
         /// <summary>
         /// 创建时间
         /// </summary>
         public datetime creation_time { get; set; }
 
         /// <summary>
         /// 版本信息
         /// </summary>
         public string version { get; set; }
     }

2.创建控制器(controller),编写逻辑代码

1).设置接口输出数据格式(json或xml)

     [produces("application/json")]//controller中方法默认输出json格式数据
     //[produces("application/xml")]//controller中方法默认输出xml格式数据
     public class testapicontroller : controller

2).设置接口路由(定义接口版本【方便后期和新版本区分】)

     [route("api/v1/testapi")]//固定路由配置
     //[route("api/v1/[controller]")]//固定部分路由配置
     public class testapicontroller  : controller

3).设置接口请求method,常见如下:

get :从服务器取出资源(一项或多项)

post :在服务器新建一个资源

put :在服务器更新资源(客户端提供改变后的完整资源)

patch :在服务器更新资源(客户端提供改变的属性)

delete :从服务器删除资源

         /// <summary>
         /// 返回用户信息接口
         /// </summary>
         /// <returns></returns>
         [httpget]//请求方法为get
         [route("getuser")]//自定义路由
         //[produces("application/xml")]//输出xml格式
         public task<userviewmmodel> index()
         {}

4).返回json数据格式接口

         /// <summary>
         /// 返回用户信息接口
         /// </summary>
         /// <returns></returns>
         [httpget]//请求方法为get
         [route("getuser")]//自定义路由
         //[produces("application/xml")]//输出xml格式
         public task<userviewmmodel> index()
         {
             return task.run(() =>
             {
                 userviewmmodel res = null;
                 //业务逻辑代码....
                 res = new userviewmmodel
                 {
                     address = "上海市浦东区世纪大道200号",
                     age = 23,
                     creation_time = datetime.now,
                     version = "v1.0"
                 };
 
                 return res;
             });
         }

5).返回文件(输出文件)接口

         /// <summary>
         /// 输出文件接口
         /// </summary>
         /// <returns></returns>
         [httpget]//请求方法为get
         [route("getfile")]//自定义路由
         public fileresult download()
         {
             var filedata = $"{directory.getcurrentdirectory()}/wwwroot/css/site.css";
             var actionresult = new filestreamresult(filedata.getfiledata().tostream(), "text/css");
             actionresult.filedownloadname = "site.css";
             return actionresult;
         }

6).裁剪图片接口

         /// <summary>
         /// 裁剪图片接口
         /// </summary>
         /// <param name="width"></param>
         /// <param name="name"></param>
         /// <returns></returns>
         [httpget]//请求方法为get
         [route("getimage/{width}/{name}")]//自定义路由
         public iactionresult getimage(int width, string name)
         {
             var imgpath = $@"{directory.getcurrentdirectory()}/wwwroot/imgs/{name}";
 
             //缩小图片
             using (var imgbmp = new bitmap(imgpath))
             {
                 //找到新尺寸
                 var owidth = imgbmp.width;
                 var oheight = imgbmp.height;
                 var height = oheight;
                 if (width > owidth)
                 {
                     width = owidth;
                 }
                 else
                 {
                     height = width * oheight / owidth;
                 }
                 var newimg = new bitmap(imgbmp, width, height);
                 newimg.setresolution(72, 72);
                 byte[] bytes;
                 using (var ms = new memorystream())
                 {
                     newimg.save(ms, imageformat.bmp);
                     bytes = ms.getbuffer();
                 }
                 return new filecontentresult(bytes, "image/jpeg");
             }
         }

7).上传单个文件接口

         /// <summary>
         /// 上传文件,需要指定name值为fromfile,如:form-data; name="fromfile"; filename="8.png"
         /// </summary>
         /// <param name="fromfile"></param>
         /// <returns></returns>
         [route("upfile")]//自定义路由
         [httppost]//请求方法为post
         [allowanonymous]
         public upfileviewmodel uplodefile([fromform] iformfile fromfile)
         {
             if (fromfile != null)
             {
                 using (var sm = fromfile.openreadstream())
                 {
                     string savepath = $"{directory.getcurrentdirectory()}/wwwroot/temp/{id.longid()}{fromfile.filename.getextension()}";
                     sm.save(savepath);
                 }
                 return new upfileviewmodel { code = 0, msg = "保存成功" };
             }
             return new upfileviewmodel { code = 1, msg = "保存失败" };
         }

8).上传多个文件接口

         /// <summary>
         /// 上传多个文件,需要指定name值为files,如:form-data; name="files"; filename="8.png"
         /// </summary>
         /// <param name="fromfile"></param>
         /// <returns></returns>
         [route("upfiles")]//自定义路由
         [httppost]//请求方法为post
         [allowanonymous]
         public upfileviewmodel uplodefiles([fromform] iformfilecollection files)
         {
             if (files != null)
             {
                 files.foreach(fromfile =>
                 {
                     using (var sm = fromfile.openreadstream())
                     {
                         string savepath = $"{directory.getcurrentdirectory()}/wwwroot/temp/{id.longid()}{fromfile.filename.getextension()}";
                         sm.save(savepath);
                     }
                 });
                 return new upfileviewmodel { code = 0, msg = "保存成功" };
             }
             return new upfileviewmodel { code = 1, msg = "保存失败" };
         }

9).上传多文件接口,上传时不需要指定name参数

         /// <summary>
         /// 上传时不需要指定name参数:form-data; name=""; filename="222222222222.jpg"
         /// </summary>
         /// <returns></returns>
         [route("upfiles2")]//自定义路由
         [httppost]//请求方法为post
         [allowanonymous]
         public upfileviewmodel uplodefiles2()
         {
             var files = this.request.form?.files;
             if (files != null)
             {
                 files.foreach(fromfile =>
                 {
                     using (var sm = fromfile.openreadstream())
                     {
                         string savepath = $"{directory.getcurrentdirectory()}/wwwroot/temp/{id.longid()}{fromfile.filename.getextension()}";
                         sm.save(savepath);
                     }
                 });
                 return new upfileviewmodel { code = 0, msg = "保存成功" };
             }
             return new upfileviewmodel { code = 1, msg = "保存失败" };
         }

4).待续…

3.进行接口调用测试

4.增加日志记录功能

5.发布接口程序到服务器(windows & linux)