Запрос JSON на C # с сервера SQL

#c# #sql #json #sql-server #audit.net

#c# #sql #json #sql-сервер #audit.net

Вопрос:

Я использовал Аудит.Сеть для аудита моего ASP.NET Приложение Razor и результаты хранятся в формате JSON в базе данных SQL Server. Имя таблицы называется AuditTrail а результаты JSON хранятся в столбце с именем jsonData Типичный вывод JSON показан ниже:

 {
    "EventType": "GET /Account/Menu",
    "Environment": {
        "UserName": "xxx",
        "MachineName": "xxx-MacBook-Pro",
        "DomainName": "xxx-MacBook-Pro",
        "CallingMethodName": "xxx.Areas.Identity.Pages.Account.MenuModel.OnGet()",
        "AssemblyName": "xxx, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
        "Culture": ""
    },
    "StartDate": "2020-12-10T14:44:47.067556Z",
    "EndDate": "2020-12-10T14:44:47.067788Z",
    "Duration": 0,
    "Action": {
        "TraceId": "xxxx",
        "HttpMethod": "GET",
        "ControllerName": "Identity",
        "ActionName": "/Account/Menu",
        "ViewPath": "/Account/Menu",
        "ActionParameters": {},
        "RequestBody": {},
        "ResponseBody": {
            "Type": "PageResult"
        },
        "UserName": "xxx@gmail.com",
        "RequestUrl": "https://localhost:5001/Identity/Account/Menu",
        "IpAddress": "::1",
        "ResponseStatusCode": 200
    }
}
 

Мой вопрос заключается в том, как я могу выбрать определенный параметр из вывода JSON, т.е. «Действие.Имя пользователя» вместо того, чтобы выводить весь вывод JSON, что он и делает в данный момент, а затем передавать его в представление. То, что я сделал до сих пор, — это представить вывод JSON в виде класса, а затем подключиться к базе данных, но это не работает

     public class Action
    {
        public string TraceId { get; set; }
        public string HttpMethod { get; set; }
        public string ControllerName { get; set; }
        public string ActionName { get; set; }
        public string ViewPath { get; set; }
        public string UserName { get; set; }
        public string RequestUrl { get; set; }
        public string IpAddress { get; set; }
        public int ResponseStatusCode { get; set; }
    }

    public class Audits
    {
        public List<Action> Actions { get; set; }
    }

         string connectionString = "Data Source=localhost;User ID=sa;Password=xxx;initial 
         catalog=xxx.db;integrated security=false;";

        public string UserName { get; set; }
        public string IpAddress { get; set; }
        public string HttpMethod { get; set; }

        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            string query = "SELECT JsonData FROM AuditTrail";
            using (SqlCommand command = new SqlCommand(query, connection))
            {
                connection.Open();
                List<AuditLog> auditLogs1 = new List<AuditLog>();
                var reader = command.ExecuteReader();
                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        AuditLog audit1 = new AuditLog();
                        audit1.User = reader["JsonData"].ToString();
                        auditLogs1.Add(audit1);
                    }
                    connection.Close();
                }
                var JsonResult = JsonConvert.SerializeObject(auditLogs1);
                var JsonResult1 = JsonConvert.DeserializeObject<Audits>(JsonResult);

                foreach (var x in JsonResult1.Actions)
                {
                    UserName = x.UserName;
                    HttpMethod = x.HttpMethod;
                    IpAddress = x.IpAddress;
                }
           }
 

Комментарии:

1. Какой результат вы получаете сейчас? Есть ли какие-либо ошибки, возникающие в вашей программе? Каков ожидаемый результат?

2. @MestreDosMagros Прямо сейчас он ничего не отображает, и никаких ошибок не появляется. Ожидаемый результат заключается в том, что UserName, HttpMethod и IPAddress должны отображать значения, которые в настоящее время отображаются в выводе JSON.

3. Важный вопрос: какая ВЕРСИЯ Sql Server? Более новые версии MSSQL имеют встроенные функции JSON, которые будут запрашивать у MSSQL JSON для вас, и поэтому вы получаете обратно нужную строку, а не вытаскиваете все jsonData

4. @McAden Я запускаю SQL Server 2019

Ответ №1:

В Sql Server 2016 и новее вы можете упростить это, обновив свой запрос:

 SELECT
    JSON_VALUE(JsonData, '$.Action.UserName') as UserName
   ,JSON_VALUE(JsonData, '$.Action.HttpMethod') as HttpMethod
   ,JSON_VALUE(JsonData, '$.Action.IpAddress') as IpAddress
FROM
    [dbo].[AuditTrail]
 

Адаптируя это в свой код, вы получаете:

 List<AuditLog> logs = new List<AuditLog>();
using (SqlConnection connection = new SqlConnection(connectionString))
{
    string query = @"SELECT
        JSON_VALUE(JsonData, '$.Action.UserName') as UserName
       ,JSON_VALUE(JsonData, '$.Action.HttpMethod') as HttpMethod
       ,JSON_VALUE(JsonData, '$.Action.IpAddress') as IpAddress
      FROM
        [dbo].[AuditTrail]";

    using (SqlCommand command = new SqlCommand(query, connection))
    {
        connection.Open();
        var reader = command.ExecuteReader();
        if (reader.HasRows)
        {
            while (reader.Read())
            {
                logs.Add(new AuditLog
                {
                    UserName = reader["UserName"].ToString(),
                    HttpMethod = reader["HttpMethod"].ToString(),
                    IpAddress = reader["IpAddress"].ToString()
                });
            }
        }
    }
}
 

Комментарии:

1. Большое спасибо, я все еще новичок в SQL.

2. Поздравления сезона. Есть ли способ сделать это в SQL server 2014? Спасибо

3. Не этот подход, вам нужно будет извлечь его в виде строки и проанализировать.

Ответ №2:

Итак, вы можете получить только ключ «Action» из вашего JSON таким образом:

 
            using (SqlCommand command = new SqlCommand(query, connection))
            {
                connection.Open();
                List<AuditLog> auditLogs1 = new List<AuditLog>();
                var reader = command.ExecuteReader();
                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        AuditLog audit1 = new AuditLog();
                        audit1.User = reader["JsonData"].ToString();
                        auditLogs1.Add(audit1);
                    }
                    connection.Close();
                }

                var root = JObject.Parse(auditLogs1);
                var audit = new Audits() { Actions = new List<Action>() };
                var action = root["Action"].ToObject<Action>();
                
                audit.Actions.Add(action);

                foreach (var x in audit.Actions)
                {
                    UserName = x.UserName;
                    HttpMethod = x.HttpMethod;
                    IpAddress = x.IpAddress;
                }
           }
 

С помощью этого вы можете выяснить, что вы могли бы делать