You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
4.8 KiB
124 lines
4.8 KiB
using CSharpObjectJsonSchema.Models;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
|
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
|
|
using Microsoft.AspNetCore.Routing;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.Diagnostics;
|
|
using System.Dynamic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
|
|
namespace CSharpObjectJsonSchema.Controllers
|
|
{
|
|
public class HomeController : Controller
|
|
{
|
|
private readonly ILogger<HomeController> _logger;
|
|
|
|
public HomeController(ILogger<HomeController> logger)
|
|
{
|
|
_logger = logger;
|
|
}
|
|
|
|
public string Index()
|
|
{
|
|
var metadata = this.HttpContext.RequestServices.GetRequiredService<IModelMetadataProvider>().GetMetadataForType(new TestModel().GetType()) as DefaultModelMetadata;
|
|
var json = CreateJson(metadata);
|
|
return JsonConvert.SerializeObject(json, Formatting.Indented);
|
|
}
|
|
|
|
private object CreateJson(DefaultModelMetadata metadata)
|
|
{
|
|
try
|
|
{
|
|
dynamic json = new ExpandoObject();
|
|
var dictionary = (IDictionary<string, object>)json;
|
|
//type
|
|
if (metadata.IsComplexType && metadata.IsCollectionType)
|
|
{
|
|
json.type = "array";
|
|
json.items = new { type = metadata.ModelType.GenericTypeArguments[0].Name };
|
|
}
|
|
else if (metadata.IsNullableValueType)
|
|
{
|
|
json.type = metadata.ModelType.GenericTypeArguments[0].Name;
|
|
}
|
|
else
|
|
{
|
|
json.type = metadata.ModelType.Name;
|
|
}
|
|
if (!metadata.IsComplexType && !metadata.IsNullableValueType && metadata.ModelType != typeof(string))
|
|
{
|
|
json.required = true;
|
|
}
|
|
if (metadata.DisplayName != null)
|
|
{
|
|
json.title = metadata.DisplayName;
|
|
}
|
|
foreach (var attribute in metadata.Attributes.Attributes)
|
|
{
|
|
if (attribute is DescriptionAttribute descriptionAttribute)
|
|
{
|
|
json.description = descriptionAttribute.Description;
|
|
}
|
|
else if (attribute is RegularExpressionAttribute regularExpressionAttribute)
|
|
{
|
|
json.pattern = regularExpressionAttribute.Pattern;
|
|
}
|
|
else if (attribute is RequiredAttribute requiredAttribute)
|
|
{
|
|
json.required = true;
|
|
}
|
|
//
|
|
else if (attribute is CompareAttribute compareAttribute)
|
|
{
|
|
json.compare = compareAttribute.OtherProperty;
|
|
}
|
|
else if (attribute is RemoteAttribute remoteAttribute)
|
|
{
|
|
var routeData = attribute.GetType().GetProperty("RouteData", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(remoteAttribute) as RouteValueDictionary;
|
|
json.remote = new
|
|
{
|
|
url = Url.Action(routeData["action"].ToString(), routeData["controller"].ToString(), new { Area = routeData["area"].ToString() }),
|
|
remoteAttribute.AdditionalFields,
|
|
//remoteAttribute.
|
|
};
|
|
}
|
|
}
|
|
dynamic properties = new ExpandoObject();
|
|
var propertiesDictionary = (IDictionary<string, object>)properties;
|
|
if (metadata.IsComplexType && !metadata.IsCollectionType && metadata.Properties.Any())
|
|
{
|
|
foreach (var item in metadata.Properties)
|
|
{
|
|
propertiesDictionary[item.PropertyName] = CreateJson(item as DefaultModelMetadata);
|
|
}
|
|
json.properties = properties;
|
|
}
|
|
return json;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return null;
|
|
}
|
|
//Console.WriteLine(metadata.DataTypeName);
|
|
}
|
|
|
|
public IActionResult Privacy()
|
|
{
|
|
return View();
|
|
}
|
|
|
|
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
|
public IActionResult Error()
|
|
{
|
|
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
|
}
|
|
}
|
|
} |