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");
}
}