简体   繁体   中英

Append Schema to Json data returned from controller

I am trying to add schema to JSON that is returned from every controller and every endpoint inside it.

Let's say I have an endpoint "localhost/values/get", and it returns a JSON as below.

{
    Filed1:'Field1Value',
    Field2:'Field2Value',
    Field3:3
}

I want to convert it to as follows

{
    Schema:[{
        Field:'Filed1',
        DataType:'String'
    },
    {
        Field:'Field2',
        dataType:'String'
    },
    {
        Field:'Field3',
        DataType:'int'
    }],
    Data:{
        Filed1:'Field1Value',
        Field2:'Field2Value',
        Field3:3
    }
}

Is there a way to add this for every return object at one place instead of doing it for every controller?

something like the attributes does.

I have tried the WriteResponseBodyAsync using

Options.OutputFormatters.Insert(0, new OutputFormatter());

in the startup.cs , but I was unable to get the properties of the type that I am sending in the response. Can someone please help me with this.

This is how I achieved the output formatting in my Web API.

My Startup.cs looks like below. Inside the ConfigureServices

services.AddMvc(Options =>
{
    Options.OutputFormatters.Insert(0, new OutputFormatter());
});

Create an OutputFormatter.cs class as follows.

public OutputFormatter()
{
    SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/json"));
    SupportedEncodings.Add(Encoding.GetEncoding("iso-8859-1"));
}

public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
{
    var response = context.HttpContext.Response;
    var responseData = Encoding.UTF8.GetBytes(LoadSchema(context));
    return response.Body.WriteAsync(responseData, 0, responseData.Length);
}

private string LoadSchema(OutputFormatterWriteContext context)
{
    var schema = new List<SchemaModel>();
    var returnData = new ReturnModel();
    foreach (var Field in (context.Object as IEnumerable<dynamic>).FirstOrDefault().GetType().GetProperties())
    {
        schema.Add(new SchemaModel
        {
            FieldName = Field.Name,
            DataType = Field.PropertyType.Name
        });
    }
    returnData.Schema = schema;
    returnData.ReturnData = context.Object;
    return JsonConvert.SerializeObject(returnData);
}

You can make changes to the way the schema is generated by changing the logic in the above code. Write all your controllers as is, and return the model and this OutputFormatter will take care of adding the schema to the JSON.

The JSON data would look like below.

{
    "Schema": [
        {
            "FieldName": "FirstProp",
            "DataType": "String"
        },
        {
            "FieldName": "SecondProp",
            "DataType": "Int32"
        },
        {
            "FieldName": "ThirdProp",
            "DataType": "Decimal"
        },
        {
            "FieldName": "FourthProp",
            "DataType": "Boolean"
        },
        {
            "FieldName": "FifithProp",
            "DataType": "DateTime"
        }
    ],
    "ReturnData": [
        {
            "FirstProp": "value0",
            "SecondProp": 0,
            "ThirdProp": -0.9,
            "FourthProp": true,
            "FifithProp": "2018-03-06T15:26:08.8428651-06:00"
        },
        {
            "FirstProp": "value1",
            "SecondProp": 1,
            "ThirdProp": 0.1,
            "FourthProp": false,
            "FifithProp": "2018-03-07T15:26:08.8428702-06:00"
        },
        {
            "FirstProp": "value2",
            "SecondProp": 2,
            "ThirdProp": 1.1,
            "FourthProp": true,
            "FifithProp": "2018-03-08T15:26:08.8428713-06:00"
        },
        {
            "FirstProp": "value3",
            "SecondProp": 3,
            "ThirdProp": 2.1,
            "FourthProp": false,
            "FifithProp": "2018-03-09T15:26:08.8428724-06:00"
        },
        {
            "FirstProp": "value4",
            "SecondProp": 4,
            "ThirdProp": 3.1,
            "FourthProp": true,
            "FifithProp": "2018-03-10T15:26:08.8428735-06:00"
        }
    ]
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM