using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Sers.Core.Module.Api;
using Sers.Core.Module.Api.LocalApi.StaticFileTransmit;
using Sers.Core.Module.Api.Rpc;
using Sers.Core.Module.Message;
using Sers.Core.Module.Rpc;
using Sers.SersLoader;
using Sers.SersLoader.ApiDesc.Attribute.RpcVerify;
using Sers.SersLoader.ApiDesc.Attribute.Valid;
using Vit.Core.Util.ComponentModel.Api;
using Vit.Core.Util.ComponentModel.Data;
using Vit.Core.Util.ComponentModel.Model;
using Vit.Core.Util.ConfigurationManager;
using Vit.Extensions;
using Vit.Net.Http.FormFile;
namespace Did.SersLoader.Demo.Controllers.Demo
{
//站点名称,可多个。若不指定,则从 配置文件中LocalApiService中的"apiStationNames"获取
[SsStationName("demo")]
//[SsStationName("demo2"), SsStationName("demo3")]
//路由前缀,可不指定
[SsRoutePrefix("v1/api")]
public class SampleController
: IApiController
{
#region (x.1)route
///
/// route示例
///
///
[SsRoute("101/route"), SsRoute("102/route")]
[SsRoute("/demo/v1/api/103/route")] //使用绝对路径路由
public ApiReturn Route()
{
return new { url = RpcContext.RpcData.http_url_Get() };
}
///
/// route示例-泛接口
///
///
[SsRoute("104/route/*")] //使用泛接口路径路由
public ApiReturn Route4()
{
var rpcData = RpcContext.RpcData;
var route = rpcData.route;
var http_url = rpcData.http_url_Get();
var http_url_search = rpcData.http_url_search_Get();
var http_url_RelativePath = rpcData.http_url_RelativePath_Get();
var http_method = rpcData.http_method_Get() ;
var data = new
{
route,
http_url,
http_url_search,
http_url_RelativePath,
http_method
};
return new ApiReturn(data);
}
///
/// HttpMethod示例GET
///
///
[SsRoute("105/route",HttpMethod ="GET")]
public ApiReturn Route5_Get()
{
return new { apiName = "Route5_Get", rpcData = RpcContext.RpcData };
}
///
/// HttpMethod示例POST
///
///
[SsRoute("105/route", HttpMethod = "POST")]
public ApiReturn Route5_POST()
{
return new { apiName = "Route5_POST", rpcData = RpcContext.RpcData };
}
#endregion
#region (x.2)Name和Desc
///
/// 演示 如何使用Name 和 Description。
/// 函数注释和使用SsDescription是一样的效果。
///
///
[SsRoute("201/NameDesc")]
[SsName("NameDesc1")]
public ApiReturn NameDesc()
{
return new ApiReturn();
}
///
///
///
///
[SsRoute("202/NameDesc")]
[SsDescription("演示 如何使用Name 和 Description。\n函数注释和使用SsDescription是一样的效果。")]
public ApiReturn NameDesc2()
{
return new ApiReturn();
}
#endregion
#region (x.3)参数
#region (x.x.1)无参
///
/// 无参
///
///
[SsRoute("310/arg")]
public ApiReturn Arg301()
{
return new ApiReturn();
}
#endregion
#region (x.x.2)首个参数为参数实体
///
/// 首个参数为参数实体(引用类型)
///
/// arg1注释
/// ArgModelDesc-returns
[SsRoute("320/arg")]
public ApiReturn Arg320(
[SsExample("{\"arg\":\"arg\",\"arg2\":\"arg2\"}"), SsDefaultValue("{\"arg\":\"arg\",\"arg2\":\"arg2\"}"), SsDescription("argDescription")]ArgModel args
)
{
return args;
}
///
/// 首个参数为参数实体(引用类型)
///
///
///
[SsRoute("321/arg")]
public ApiReturn Arg321(
[SsExample("[\"arg1\",\"arg2\"]"), SsDefaultValue("[\"arg1\",\"arg2\"]"), SsDescription("argDescription")]string[] args)
{
return args;
}
///
/// 标识函数第一个参数为Api的参数实体。(忽略其他参数(若存在),调用函数时其他参数(若存在)为空)
///
/// args注释
///
[SsRoute("322/arg")]
public ApiReturn Arg322(
[SsExample("argExample"), SsDefaultValue("argDefaultValue"), SsDescription("argDescription"),SsArgEntity]string args)
{
return args;
}
///
/// 标识函数第一个参数为Api的参数实体。(忽略其他参数(若存在),调用函数时其他参数(若存在)为空)
///
///
///
///
[SsRoute("323/arg")]
public ApiReturn Arg323([SsArgEntity]string args,string arg2)
{
return args;
}
#endregion
#region (x.x.3)函数参数列表为参数实体
///
/// 函数参数列表为参数实体
///
///
///
[SsRoute("330/arg")]
public ApiReturn Arg330([SsExample("argExample"), SsDefaultValue("argDefaultValue"), SsDescription("argDescription")]string arg1)
{
return new { arg1 };
}
///
/// 函数参数列表为参数实体
///
/// arg1注释
/// arg2注释
///
[SsRoute("331/arg")]
public ApiReturn Arg331(
[SsExample("example1"), SsDefaultValue("default1"), SsDescription("desc1")]string arg1,
[SsExample("6"), SsDefaultValue("1")]int arg2)
{
return new { arg1 , arg2 };
}
///
/// 函数参数列表为参数实体
///
/// arg1注释
/// arg2注释
///
[SsRoute("332/arg")]
public ApiReturn Arg332(ArgModel arg1,
[SsExample("6"), SsDefaultValue("1")]int arg2)
{
return new { arg1, arg2 };
}
///
/// 函数第一个参数为Api的参数实体的属性之一。(一般放置在第一个参数上,代表第一个参数不为参数实体)
///
/// arg1注释
///
[SsRoute("333/arg")]
public ApiReturn Arg333([SsArgProperty]ArgModel arg1)
{
return new { arg1};
}
#endregion
public class ArgModel
{
///
/// 姓名
///
[SsExample("lith"), SsDefaultValue("NoName")]
[JsonProperty("arg")]
public string name { get; set; }
///
///
///
[SsExample("20"), SsDefaultValue("0"), SsDescription("年龄,请指定在16-50中间的整数")]
public int age;
}
#endregion
#region (x.4)返回值
///
/// Return1
///
/// Return注释-FromXml
[SsRoute("401/ret")]
public ApiReturn Return1()
{
return new ReturnData { name = "张三" };
}
///
/// Return2
///
///
[SsRoute("402/ret")]
[return: SsExample("{\"data\":12}"), SsDescription("成功个数")]
public ApiReturn Return2()
{
return 5;
}
///
///
///
///
[SsRoute("403/ret")]
public ApiReturn> Return3()
{
return new List{ "1","2"};
}
///
///
///
///
[SsRoute("404/ret")]
[return: SsExample("test"), SsDescription("返回test1")]
public string Return4()
{
return "test1";
}
///
///
///
///
[SsRoute("405/ret")]
[return: SsExample("5"), SsDescription("返回5")]
public int Return5()
{
return 5;
}
///
///
///
///
[SsRoute("406/ret")]
[return: /*SsExample("{\"name\":\"张三\"}"),*/ SsDescription("返回模型数据")]
public ReturnData Return6()
{
return new ReturnData { name = "张三" };
}
///
/// Return注释-FromType
///
public class ReturnData
{
///
/// 姓名
///
[SsExample("lith"), SsDefaultValue("NoName")]
public string name { get; set; }
}
#endregion
#region (x.4-2)指定参数或返回值类型
///
/// 指定参数或返回值类型
///
///
[SsRoute("409/type")]
[return: SsType(typeof(List)), SsExample("[5,6]"), SsDescription("返回原值")]
public string Type(
[SsType(typeof(List)), SsExample("[5,6]"), SsDescription("id数组")]string ids
)
{
return ids;
}
#endregion
#region (x.5) Rpc
///
/// rpc示例
///
///
[SsRoute("501/GetRpcOriData")]
public ApiReturn GetRpcOriData()
{
return new ApiReturn(RpcContext.RpcData);
}
///
/// rpc示例
///
///
[SsRoute("502/RpcDemo")]
public ApiReturn RpcDemo()
{
var rpcData = RpcContext.RpcData;
var data = new
{
rpcData.route,
http_url = rpcData.http_url_Get(),
userInfo = rpcData.user_userInfo_Get(),
serviceId= DateTime.Now.ToString("sss")
};
return new ApiReturn(data);
}
///
/// rpc示例
///
///
[SsRoute("503/RpcReplyDemo")]
public ApiReturn RpcReplyDemo([SsArgEntity,SsExample("requestContent")]string request)
{
#region reply header
RpcContext.Current.apiReplyMessage.rpcContextData_OriData =
RpcFactory.CreateRpcContextData()
.http_statusCode_Set(201)
//.http_header_Set("Content-Type", "application/json")
.http_header_ContentType_Set("application/json")
.http_header_Set("testHeader", "abc")
.PackageOriData();
//var replyRpcData = RpcFactory.Instance.CreateRpcContextData();
//var header = new JObject();
//header["testHeader"] = "abc";
//header["Content-Type"] = "application/json";s
//replyRpcData.http_headers_Set(header);
//RpcContext.Current.apiReplyMessage.rpcContextData_OriData = replyRpcData.PackageOriData();
#endregion
var data = new
{
RpcContext.RpcData,
request
};
return data;
}
#endregion
#region (x.6) ApiClient
#region (x.x.1)ApiClient示例,调用其他接口
///
/// ApiClient示例,调用其他接口
///
///
[SsRoute("610/ApiClient")]
public ApiReturn ApiClient610(
[SsExample("/demo/v1/api/332/arg")]string apiRoute,
[SsExample("{\"arg1\":\"dd\",\"arg2\":\"33\"}")]object arg)
{
var apiRet = ApiClient.CallRemoteApi>(apiRoute, arg);
return new ApiReturn(new
{
RpcContext.RpcData,
apiRet
});
}
#endregion
#region (x.x.2) ApiClient示例,传输二进制数据
///
/// ApiClient示例,传输二进制数据
///
///
///
[SsRoute("620/ApiClient")]
[SsName("ApiClient demo")]
[return:SsExample("1122AAFF"), SsDescription("二进制数据")]
public byte[] ApiClient620(
[SsExample("1122AAFF"), SsDescription("二进制数据")]byte[] ba) // 使用ArraySegment 会减少一步复制的操作,若传输大数据建议使用ArraySegment
{
return ba;
}
///
/// ApiClient示例,传输二进制数据
///
///
///
[SsRoute("621/ApiClient")]
[SsName("ApiClient demo")]
[return: SsExample("1122AAFF"), SsDescription("二进制数据")]
public ArraySegment ApiClient621(
[SsExample("1122AAFF"), SsDescription("二进制数据")]ArraySegment ba)
{
return ba;
}
///
/// ApiClient示例,传输二进制数据
///
///
[SsRoute("622/ApiClient")]
public ApiReturn ApiClient622()
{
var apiRet = ApiClient.CallRemoteApi>("/demo/v1/api/621/ApiClient", new byte[] { 3, 2, 3, 4, 5 });
return new ApiReturn();
}
#endregion
#region (x.x.3) ApiClient示例,传输额外数据
///
/// ApiClient示例,二进制数据和ReplyRpc
///
///
[SsRoute("630/ApiClient")]
public ApiReturn ApiClient630()
{
var apiReply = RpcContext.Current.apiReplyMessage;
var file1 = new byte[] { 1, 2, 3, 4, 5 };
var file2 = new byte[] { 2, 3, 3, 4, 5 };
apiReply.AddFiles(file1.BytesToArraySegmentByte(), file2.BytesToArraySegmentByte());
#region file from request
var apiRequest = RpcContext.Current.apiRequestMessage;
if (apiRequest.Files.Count >= 3)
{
var file3 = apiRequest.Files[2];
apiReply.AddFiles(file3);
}
#endregion
apiReply.rpcContextData_OriData = RpcContext.Current.apiRequestMessage.rpcContextData_OriData;
return new ApiReturn();
}
///
/// ApiClient示例,传输二进制数据和ReplyRpc
///
///
[SsRoute("631/ApiClient")]
public ApiReturn ApiClient3_2()
{
var apiRequestMessage = new ApiMessage().InitAsApiRequestMessage("/demo/v1/630/ApiClient", null);
var fileToSend = new byte[] { 3, 2, 3, 4, 5 };
apiRequestMessage.AddFiles(fileToSend.BytesToArraySegmentByte());
var apiReplyMessage = ApiClient.CallRemoteApi(apiRequestMessage);
var file1 = apiReplyMessage.Files[2];
var file2 = apiReplyMessage.Files[3];
var file3 = apiReplyMessage.Files[4];
//var replyRpcData = RpcFactory.Instance.CreateRpcContextData();
//replyRpcData.UnpackOriData(apiReplyMessage.rpcContextData_OriData);
return new ApiReturn();
}
#endregion
#endregion
#region (x.7) UseStaticFiles
// wwwroot 路径从配置文件获取
static StaticFileMap staticFileMap = new StaticFileMap(ConfigurationManager.Instance.GetByPath("Demo.staticFiles"));
///
/// UseStaticFiles
///
///
[SsRoute("700/static/*")]
public byte[] UseStaticFiles()
{
return staticFileMap.TransmitFile();
}
#endregion
#region (x.8) RpcVerify
#region (x.8.1) 自定义限制 SsRpcVerify
///
/// 810自定义限制 SsRpcVerify
///
///
[SsRoute("810/SsRpcVerify")]
[SsRpcVerify( condition = "{\"type\":\"==\",\"path\":\"http.method\",\"value\":\"PUT\"}", verifiedWhenNull = false , errorMessage = "只接受PUT请求", errorCode = 1000)]
// condition: SsExp,参考 rpcVerify2.md
// path: RpcData中被验证的值,(参考 RpcContextData.md)。如 http.url 、http.method 、 http.headers.Authorization
// verifiedWhenNull: 当出现空值时,是否通过验证(默认不通过,false)。例如,为fakse时,若没有指定值http.method,则禁止调用接口,返回错误消息;
// 为true时,在没有指定http.method时可以调用哦接口
//
// errorMessage: 校验不通过时的提示消息,若不指定则使用默认提示消息
// errorCode: 校验不通过时的errorCode, 如 1000。可不指定
public ApiReturn SsRpcVerify()
{
return new ApiReturn();
}
#endregion
#region (x.8.2) CallerSource
///
/// 820限制只可内部调用
///
///
[SsRoute("820/CallerSource")]
[SsNotEqual(path = "caller.source", value = "Internal", errorMessage = "无权限")]
//[SsNotEqual(type="!=",path = "caller.source", value = "Internal", errorMessage = "无权限")]
public ApiReturn CallerSource820()
{
return new ApiReturn();
}
///
/// 821限制只可内部调用
///
///
[SsRoute("821/CallerSource")]
//[SsCallerSource(ECallerSource.Internal)]
//[SsCallerSource(ECallerSource.Internal| ECallerSource.OutSide)]
[SsCallerSource(callerSourceString = "Internal,OutSide")]
public ApiReturn CallerSource821()
{
return new ApiReturn();
}
///
/// 822限制只可外部调用
///
///
[SsRoute("822/CallerSource")]
[SsCallerSource(ECallerSource.OutSide, errorMessage = "只可外部调用")]
public ApiReturn CallerSource822()
{
return new ApiReturn();
}
#endregion
#region (x.8.3) SsCmp
///
/// 830 SsCmp
///
///
[SsRoute("830/SsCmp")]
[SsCmp(path = "http.method", type = "==" , value="PUT")]
public ApiReturn SsCmp830()
{
return new ApiReturn();
}
#endregion
#region (x.8.4) SsEqual
///
/// 840 SsEqual
///
///
[SsRoute("840/SsEqual")]
[SsEqual(path = "http.method", value = "PUT")]
public ApiReturn SsEqual840()
{
return new ApiReturn();
}
#endregion
#region (x.8.5) SsNotEqual
///
/// 850 SsNotEqual
///
///
[SsRoute("850/SsNotEqual")]
[SsNotEqual(path = "http.method", value = "PUT",errorMessage = "不可为PUT请求")]
public ApiReturn SsNotEqual850()
{
return new ApiReturn();
}
#endregion
#region (x.8.6) SsNotNull
///
/// 860 SsNotNull
///
///
[SsRoute("860/SsNotNull")]
[SsNotNull(path = "http.headers.Authorization", errorMessage = "必须指定Authorization")]
public ApiReturn SsNotNull860()
{
return new ApiReturn();
}
#endregion
#region (x.8.7) SsRegex
///
/// 870 SsRegex(请求地址 /demo/v1/api/870/SsRegex/a.html )
///
///
[SsRoute("870/SsRegex/*")]
[SsRegex(path = "http.url", value = "(?<=\\.html)$", errorMessage = "url后缀必须为 .html")]
public ApiReturn SsRegex870()
{
return new ApiReturn();
}
#endregion
#endregion
#region (x.9)特殊示例
#region (x.x.1) 递归demo
///
/// 递归。 f(n) = f(n-1) + f(n-2)
///
///
[SsRoute("901/Recursive")]
public ApiReturn Recursive([SsExample("4")]int n)
{
if (n <= 2) return 1;
var task1 = ApiClient.CallRemoteApiAsync>(RpcContext.RpcData.route, new { n = n - 1 });
var task2 = ApiClient.CallRemoteApiAsync>(RpcContext.RpcData.route, new { n = n - 2 });
Task.WaitAll(task1, task1);
var apiRet1 = task1.Result;
var apiRet2 = task2.Result;
if (!apiRet1.success) return apiRet1.error;
if (!apiRet2.success) return apiRet2.error;
return apiRet1.data+ apiRet2.data;
}
#endregion
#region (x.x.2) Sleep
///
/// 睡眠指定时间
///
///
[SsRoute("902/sleep")]
public ApiReturn Sleep(
[SsExample("2"),SsDescription("单位:s")]int s)
{
Thread.Sleep(s * 1000);
return s;
}
#endregion
#region (x.x.3) Upload
///
/// 上传文件(测试地址 /demo/v1/api/700/static/upload.html)
///
///
[SsRoute("903/upload",HttpMethod = "POST")]
public ApiReturn Upload(byte[] data)
{
MultipartForm result=new MultipartForm(data, RpcContext.RpcData.http_header_ContentType_Get());
return result;
}
#endregion
#endregion
}
}