新增SwaggerDemo

This commit is contained in:
2025-09-23 16:29:17 +08:00
parent dc42b56bf6
commit dad5b8fb89
27 changed files with 505 additions and 39 deletions

View File

@@ -0,0 +1,43 @@
using Nancy;
using Nancy.Bootstrapper;
using Nancy.Conventions;
using Nancy.Swagger.Services;
using Nancy.TinyIoc;
using Swagger.ObjectModel;
namespace .WebModule
{
public class ApplicationBootstrapper : DefaultNancyBootstrapper
{
protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
{
SwaggerMetadataProvider.SetInfo("API", "v1.0", "电子展板", new Contact
{
EmailAddress = "18862253202@qq.com",
Name = "大师兄法号随缘",
Url = "https://www.cnblogs.com/zjwno1"
}, "http://www.cnblogs.com/zjwno1");
base.ApplicationStartup(container, pipelines);
}
protected override void ConfigureConventions(NancyConventions nancyConventions)
{
base.ConfigureConventions(nancyConventions);
}
/// <summary>
/// 允许跨域
/// </summary>
/// <param name="container"></param>
/// <param name="pipelines"></param>
/// <param name="context"></param>
protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
{
pipelines.AfterRequest.AddItemToEndOfPipeline(x => x.Response.Headers.Add("Access-Control-Allow-Origin", "*"));
pipelines.AfterRequest.AddItemToEndOfPipeline(x => x.Response.Headers.Add("Access-Control-Allow-Headers", "*"));
pipelines.AfterRequest.AddItemToEndOfPipeline(x => x.Response.Headers.Add("Access-Control-Allow-Methods", "*"));
}
}
}

View File

@@ -0,0 +1,104 @@
using Nancy.Metadata.Modules;
using Nancy.Swagger;
using Swagger.ObjectModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using .Models;
using .Utility.Core;
namespace .WebModule
{
public class HomeMetadataModule : MetadataModule<PathItem>
{
public HomeMetadataModule(ISwaggerModelCatalog modelCatalog)
{
//添加模型
modelCatalog.AddModels(typeof(MyConfig));
Describe["getConfig"] = description => description.AsSwagger(
with => with.Operation(
op =>
{
//设置操作id
op.OperationId("getConfig");
//设置tag
op.Tag("getConfig");
//备注
op.Summary("获得当前配置");
//参数配置
//op.BodyParameter(p =>
// p.Description("配置项")
// .Name("Config")
// .Schema<MyConfig>()
//);
//返回值配置
op.Response(r =>
r.Description("返回数据")
//.Example("application/json", JsonHelper.ToJson(GlobalVariable.Config))
.Schema<MyConfig>()
);
}
)
);
Describe["uploadImage"] = description => description.AsSwagger(
with => with.Operation(
op =>
{
//设置操作id
op.OperationId("uploadImage");
//设置tag
op.Tag("uploadImage");
//备注
op.Summary("上传照片");
//文件上传
op.ConsumeMimeType("multipart/form-data");
//参数配置
op.Parameter(p =>
p.In(ParameterIn.Form)
.Name("file")//参数名
.Type("file")//文件类型
.Description("上传文件")
.IsRequired()
);
//返回值配置
op.Response(r =>
r.Description("返回数据")
.Example("application/json", new RetValue { state = 1, message = "上传成功", data = "/upload/123.png" }.ToJson())
.Schema<RetValue>()
);
}
)
);
Describe["save"] = description => description.AsSwagger(
with => with.Operation(
op =>
{
//设置操作id
op.OperationId("save");
//设置tag
op.Tag("save");
//备注
op.Summary("保存配置");
//参数配置
op.BodyParameter(p =>
p.Description("配置项")
.Name("Config")
.Schema<MyConfig>()
);
//返回值配置
op.Response(r =>
r.Description("返回数据")
.Example("application/json", new RetValue { state = 1, message = "保存成功" }.ToJson())
.Schema<RetValue>()
);
}
)
);
}
}
}

View File

@@ -0,0 +1,132 @@
using Nancy;
using Nancy.ModelBinding;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using .Base;
using .Models;
using .Utility;
using .Utility.Core;
using .Utility.Extension;
using .Utility.Logs;
using .Utility.Other;
namespace .WebModule
{
public class HomeModule : NancyModule
{
public HomeModule()
{
//默认页面
Get("", Index);
Get("/", Index);
Get("/index.html", Index);
//全局静态资源
Get("/static/{name*}", StaticResource);
//获得配置
Get("/getConfig", GetConfig, null, "getConfig");
//获得上传的文件
Get("/upload/{id}", GetUploadFiles);
//上传图片
Post("/uploadImage", UploadImage, null, "uploadImage");
//保存配置
Post("/save", SaveConfig, null, "save");
}
//默认页面
private object Index(dynamic dynamic)
{
return Resouce("Views/Index.html");
}
//全局静态资源
private object StaticResource(dynamic dynamic)
{
string name = dynamic.name;
return Resouce(name);
}
/// <summary>
/// 获得配置
/// </summary>
/// <param name="dynamic"></param>
/// <returns></returns>
private object GetConfig(dynamic dynamic)
{
//保留JSON KEY首字母大写这里就不用 Response.AsJson();
//AsJson会将首字母小写
return Response.AsText(JsonHelper.ToJson(GlobalVariable.Config), "application/json", Encoding.UTF8);
}
/// <summary>
/// 获得上传的文件
/// </summary>
/// <param name="dynamic"></param>
/// <returns></returns>
private object GetUploadFiles(dynamic dynamic)
{
string id = dynamic.id;
string contentType = System.Web.MimeMapping.GetMimeMapping(id);
return Response.AsFile(MyEnvironment.Root("/Upload/" + id), contentType);
}
/// <summary>
/// 上传图片
/// </summary>
/// <param name="dynamic"></param>
/// <returns></returns>
private object UploadImage(dynamic dynamic)
{
string uploadPath = MyEnvironment.Root("/Upload/");
if (!Directory.Exists(uploadPath))
{
Directory.CreateDirectory(uploadPath);
}
List<string> filePathList = new List<string>();
foreach (var file in Request.Files)
{
string ext = Path.GetExtension(file.Name);
string fileName = UUID.StrSnowId + ext;
var filePath = uploadPath + fileName;
using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
{
file.Value.CopyTo(fileStream);
}
filePathList.Add($"/Upload/{fileName}");
}
RetValue result = new RetValue { state = 1, message = "上传成功", data = filePathList.GetStrArray() };
return Response.AsJson(result);
}
private object SaveConfig(dynamic dynamic)
{
MyConfig config = this.Bind<MyConfig>();
//string str = Request.Body.AsString();
//MyConfig config = JsonHelper.ToObject<MyConfig>(str);
LogHelper.Instance.Info($"用户保存了配置:{JsonHelper.ToJson(config)}");
//保存
PropertyInfo[] propertyInfos = typeof(MyConfig).GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
object value = propertyInfo.GetValue(config);
propertyInfo.SetValue(GlobalVariable.Config, value);
}
GlobalVariable.SaveConfig();
//保存并修改界面
EventBus.Instance.Publish("save", "");
RetValue result = new RetValue { state = 1, message = "保存成功" };
return Response.AsJson(result);
}
private object Resouce(string resourcePath)
{
string packUri = $"pack://application:,,,/Assets/{resourcePath}";
string contentType = System.Web.MimeMapping.GetMimeMapping(packUri);
return Response.FromStream(System.Windows.Application.GetResourceStream(new Uri(packUri, UriKind.RelativeOrAbsolute)).Stream, contentType);
}
}
}

View File

@@ -0,0 +1,24 @@
using Nancy.Swagger;
using Nancy.Swagger.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using .Models;
using .Utility.Swagger;
namespace .WebModule.ModelMetadata
{
public class MyConfigModelDataProvider : ISwaggerModelDataProvider
{
/// <summary>
/// 使用自定义特性注解完成配置
/// </summary>
/// <returns></returns>
public SwaggerModelData GetModelData()
{
return SwaggerModelDataUtils.GetModelData<MyConfig>();
}
}
}

View File

@@ -0,0 +1,19 @@
using Nancy.Swagger;
using Nancy.Swagger.Services;
using .Models;
using .Utility.Swagger;
namespace .WebModule.ModelMetadata
{
public class RetValueDataProvider : ISwaggerModelDataProvider
{
/// <summary>
/// 使用自定义特性注解完成配置
/// </summary>
/// <returns></returns>
public SwaggerModelData GetModelData()
{
return SwaggerModelDataUtils.GetModelData<RetValue>();
}
}
}