using Microsoft.AspNetCore.Mvc; using ProtoBuf.Meta; using System.Collections.Generic; using System.Linq; namespace AsbCloudWebApi.Controllers; /// /// Схемы ProtoBuf /// [Route("api/proto")] [ApiController] public class ProtobufController : ControllerBase { private IEnumerable GetMetaTypes() { var metaTypes = RuntimeTypeModel.Default .GetTypes() .OfType(); var fileteredMetaTypes = metaTypes .Where(t => t.Type.MemberType == System.Reflection.MemberTypes.TypeInfo) .Where(t => !t.Type.IsGenericType) .Where(t => !t.Type.IsArray); return fileteredMetaTypes; } /// /// названия доступных типов /// /// [HttpGet("types")] [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] public IActionResult GetTypes() { var typesNames = GetMetaTypes() .Select(t => t.Type?.Name); return Ok(typesNames); } /// /// .proto файл со всеми доступными типами /// /// [HttpGet("schema")] [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] public IActionResult GetSchema() { var types = GetMetaTypes().Select(mt => mt.Type); SchemaGenerationOptions opts = new() { }; opts.Types.AddRange(types); var protoFileContentString = ProtoBuf.Serializer.GetProto(opts); var protoFileContentBytes = System.Text.Encoding.UTF8.GetBytes(protoFileContentString); return File(protoFileContentBytes, "text/plain", "types.proto"); } /// /// .proto файл со всеми доступными типами /// /// [HttpGet("schema/{typeName}")] [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] [ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)] public IActionResult GetSchema(string typeName) { if (string.IsNullOrEmpty(typeName)) return this.ValidationBadRequest(nameof(typeName), "require typeName"); var type = RuntimeTypeModel.Default .GetTypes() .OfType() .FirstOrDefault(t => t.Type.Name.Equals(typeName, System.StringComparison.InvariantCultureIgnoreCase)); if (type is null) return NoContent(); SchemaGenerationOptions opts = new() { }; opts.Types.Add(type.Type); var protoFileContentString = ProtoBuf.Serializer.GetProto(opts); var protoFileContentBytes = System.Text.Encoding.UTF8.GetBytes(protoFileContentString); return File(protoFileContentBytes, "text/plain", $"{typeName}.proto"); } }