Веб-API ASP.Net. Почему мои JSON полны странных данных и не форматируются?

У меня есть класс Company, который выглядит так.

public class Company
    {
        [JsonPropertyName("companyID")]
        public string CompanyID { get; set; }
        [JsonPropertyName("vehicleIDs")]
        public List<string> VehicleIDs { get; set; }
        [JsonPropertyName("email")]
        public string Email { get; set; }
        [JsonPropertyName("companyName")]
        public string CompanyName { get; set; }
    }

Я впервые делаю API, а также впервые работаю с C#. Я создаю список и пытаюсь вернуть его как Json из моего метода GET. Тем не менее, в любом случае, то, что я пытался сделать, похоже, привело к тонне информации, я понятия не имею, откуда она взялась. Я также пробовал форматировать так, чтобы он выглядел с отступом, и это тоже не работает.

В настоящее время мой метод GET просто возвращает список, а в моем методе регистрации WebApiConfig.cs у меня есть

var json = config.Formatters.JsonFormatter;
            json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
            config.Formatters.Remove(config.Formatters.XmlFormatter);

Это работает до некоторой степени, и я, по крайней мере, могу использовать и получать доступ к своему списку объектов, которые я получаю, но Json выглядит так

[{"$id":"1","CompanyID":"28","VehicleIDs":["1900","2121","1802","2125","1701","1703","1702"],"Email":"ElizabethHarper","CompanyName":"Allegany Paratransit","Configuration":null,"ControllerContext":{"$id":"2","Configuration":null,"ControllerDescriptor":null,"Controller":null,"Request":null,"RequestContext":{"$id":"3","Request":null,"ClientCertificate":null,"Configuration":null,"IncludeErrorDetail":false,"IsLocal":false,"RouteData":null,"Url":null,"VirtualPathRoot":null,"Principal":{"$id":"4","m_identity":{"$id":"5","System.Security.ClaimsIdentity.version":"1.0","System.Security.ClaimsIdentity.nameClaimType":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name","System.Security.ClaimsIdentity.roleClaimType":"http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid","System.Security.ClaimsIdentity.claims":"AAEAAAD/////AQAAAAAAAAAEAQAAAI4BU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuTGlzdGAxW1tTeXN0ZW0uU2VjdXJpdHkuQ2xhaW1zLkNsYWltLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQMAAAAGX2l0ZW1zBV9zaXplCF92ZXJzaW9uAwAAHlN5c3RlbS5TZWN1cml0eS5DbGFpbXMuQ2xhaW1bXQgICQIAAAAAAAAAAAAAAAcCAAAAAAEAAAAAAAAAAxxTeXN0ZW0uU2VjdXJpdHkuQ2xhaW1zLkNsYWltCw= = ","m_userToken":{"$id":"6","value":0}},"m_roles":null,"m_rolesTable":null,"m_rolesLoaded":false,"m_version":"1.0","m_serializedClaimsIdentities":"AAEAAAD/////AQAAAAAAAAAEAQAAAH9TeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYy5MaXN0YDFbW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dAwAAAAZfaXRlbXMFX3NpemUIX3ZlcnNpb24GAAAICAkCAAAAAgAAAAIAAAARAgAAAAQAAAAGAwAAAAEwBgQAAACMCEFBRUFBQUQvLy8vL0FRQUFBQUFBQUFBRUFRQUFBQ1ZUZVhOMFpXMHVVMlZqZFhKcGRIa3VRMnhoYVcxekxrTnNZV2x0YzBsa1pXNTBhWFI1Q0FBQUFBbHRYM1psY25OcGIyNEhiVjloWTNSdmNoUnRYMkYxZEdobGJuUnBZMkYwYVc5dVZIbHdaUkp0WDJKdmIzUnpkSEpoY0VOdmJuUmxlSFFIYlY5c1lXSmxiQlJ0WDNObGNtbGhiR2w2WldST1lXMWxWSGx3WlJSdFgzTmxjbWxoYkdsNlpXUlNiMnhsVkhsd1pSSnRYM05sY21saGJHbDZaV1JEYkdGcGJYTUJBd0VDQVFFQkFTVlRlWE4wWlcwdVUyVmpkWEpwZEhrdVEyeGhhVzF6TGtOc1lXbHRjMGxrWlc1MGFYUjVCZ0lBQUFBRE1TNHdDZ29LQ2dZREFBQUFPbWgwZEhBNkx5OXpZMmhsYldGekxuaHRiSE52WVhBdWIzSm5MM2R6THpJd01EVXZNRFV2YVdSbGJuUnBkSGt2WTJ4aGFXMXpMMjVoYldVR0JBQUFBRUJvZEhSd09pOHZjMk5vWlcxaGN5NXRhV055YjNOdlpuUXVZMjl0TDNkekx6SXdNRGd2TURZdmFXUmxiblJwZEhrdlkyeGhhVzF6TDJkeWIzVndjMmxrQmdVQUFBQ0FBMEZCUlVGQlFVUXZMeTh2TDBGUlFVRkJRVUZCUVVGQlJVRlJRVUZCU1RSQ1ZUTnNlbVJIVm5STWEwNTJZa2Q0YkZrelVuQmlNalY2VEd0a2JHSnRWbmxoVjAxMVZFZHNlbVJIUVhoWE1YUlVaVmhPTUZwWE1IVlZNbFpxWkZoS2NHUklhM1ZSTW5ob1lWY3hla3hyVG5OWlYyeDBURU5DZEdNeVRuWmpiWGh3V1dsM1oxWnRWbmxqTW14Mlltb3dNRXhxUVhWTlF6UjNURU5DUkdSWGVEQmtXRXBzVUZjMWJHUllVbmxaVjNkelNVWkNNVmx0ZUhCWk1IUnNaVlpTZG1FeVZuVlFWMGt6VGpKRk1WbDZWVEpOVkd0NlRrZFZkMDlFYkdSWVVVMUJRVUZCUjFneWJEQmFWekY2UWxZNWVtRlljR3hEUmpreVdsaEtlbUZYT1hWQmQwRkJTR3hPTldNelVteGlVelZVV2xkT01XTnRiREJsVXpWRVlrZEdjR0pZVFhWUk1uaG9ZVmN4WWxoUlowbERVVWxCUVVGQlFVRkJRVUZCUVVGQlFVRmpRMEZCUVVGQlFVVkJRVUZCUVVGQlFVRkJlSGhVWlZoT01GcFhNSFZWTWxacVpGaEtjR1JJYTNWUk1uaG9ZVmN4ZWt4clRuTlpWMngwUTNjOVBRcz0NAgs = "}},"RouteData":null},"ActionContext":{"$id":"7","ControllerContext":{"$ref":"2"},"ActionDescriptor":null,"ModelState":{},"ActionArguments":{},"Response":null,"Request":null,"RequestContext":{"$ref":"3"}},"ModelState":{},"Request":null,"RequestContext":{"$ref":"3"},"Url":null,"User":{"$ref":"4"}},{"$id":"8","CompanyID":"27","VehicleIDs":["312","311","2105"],"Email":"[email protected]","CompanyName":"Allegany Fixed Bus","Configuration":null,"ControllerContext":{"$id":"9","Configuration":null,"ControllerDescriptor":null,"Controller":null,"Request":null,"RequestContext":{"$id":"10","Request":null,"ClientCertificate":null,"Configuration":null,"IncludeErrorDetail":false,"IsLocal":false,"RouteData":null,"Url":null,"VirtualPathRoot":null,"Principal":{"$ref":"4"}},"RouteData":null},"ActionContext":{"$id":"11","ControllerContext":{"$ref":"9"},"ActionDescriptor":null,"ModelState":{},"ActionArguments":{},"Response":null,"Request":null,"RequestContext":{"$ref":"10"}},"ModelState":{},"Request":null,"RequestContext":{"$ref":"10"},"Url":null,"User":{"$ref":"4"}}]

Я понятия не имею, откуда и для чего берется этот лишний текст. Я попытался вернуть его в виде строки Json, используя как Newtonsoft.Json, так и System.Text.Json, оба они дают одинаковые результаты.

Кто-нибудь может объяснить?

«В настоящее время мой метод GET просто возвращает список». Можете ли вы опубликовать свой метод получения, пожалуйста?

Serge 05.04.2023 21:45

Это довольно долго, в основном я вызываю другие методы для запроса базы данных и оценки данных. Я возвращаю List<Company>.

Dave 05.04.2023 21:52

Покажите хотя бы заголовок действия и несколько последних строк. И было бы неплохо увидеть код, который вы используете, чтобы получить этот json из ответа

Serge 05.04.2023 21:53

Вы сказали This is my first time making an API, also first time working with C#, если это ваш первый раз, вы не должны спешить со сложными вещами. напишите простой метод return List<Company> даже с фиктивными данными, посмотрите результат, если он вам не нужен. разместить свой вопрос. Постепенно добавляйте больше кодов, чтобы приблизиться к сложному методу, если все идет хорошо или вы обнаружите проблему.

RezaNoei 05.04.2023 22:06

@RezaNoei Я совсем не новичок в программировании, и это для моих собственных знаний. Я уже сделал именно то, что вы описываете. Я начал с возврата List<string[]>, когда начал это. Мне тогда не понравилось, как это работало на другом конце, и я перешел на класс Company, и вот я здесь.

Dave 05.04.2023 22:09

@Serge Простите мое невежество, какой заголовок действия?

Dave 05.04.2023 22:11

Заголовок вашего API с вводом и выводом

Serge 05.04.2023 22:13

Атрибут [JsonPropertyName] предназначен для сериализатора System.Text.Json, а SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects — для сериализатора Json.NET. Если вы на самом деле используете Json.NET, то [JsonPropertyName("companyID")] не будет иметь никакого эффекта, и вы должны использовать [Newtonsoft.Json.JsonPropertyAttribute("companyID")]. См. Почему JsonConvert.DeserializeObject игнорирует атрибуты JsonPropertyName?. Можете ли вы подтвердить, какой сериализатор вы используете?

dbc 05.04.2023 22:36

Есть ли шанс, что ваш public class Company на самом деле является public partial class Company и что некоторые дополнительные поля и свойства определены в каком-то другом public partial коде?

dbc 05.04.2023 22:51
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
10
68
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

вы можете попытаться указать возвращаемый тип как json Например, у нас есть actionresult Task, просто удалите и создайте метод для возврата Json. как публичный jsonresult

Похоже, что он возвращает какой-то http-ответ в каждом объекте Company. Я не знаю, как вам это удалось; Я не видел ничего подобного раньше. Я заметил, что атрибуты, кажется, не имеют никакого эффекта - имена свойств в возвращаемом json имеют регистр Pascal, а не регистр, который вы указали в JsonPropertyName.

У меня есть другой подход, который всегда работал для меня, когда будут преобразованы атрибутированные имена свойств json.

Если вы хотите использовать Newtonsoft.Json, атрибутируйте свойства в вашей сущности Company с помощью JsonProperty Newtonsoft вместо JsonPropertyName, и вы можете преобразовать каждый объект Company в JObject и добавить их все в JArray, прежде чем возвращать их в ответ. Что-то вроде этого в вашем контроллере:

JArray ja = new JArray();
foreach (Company company in context.Companies.ToArray())
{
    JObject jo = JObject.FromObject(company);
    ja.Add(jo);
}
JsonSerializerSettings jsonSettings = new JsonSerializerSettings
{
    Formatting = Formatting.None,
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
return new JsonResult(ja, jsonSettings);

Я думаю, вы правы в отношении http-ответа внутри каждой сущности. Я понятия не имею, как это происходит, я довольно много исследовал. Я только что попробовал ваш метод, и почему-то проблема усугубляется. Там так много текста завернуто.

Dave 05.04.2023 22:45

Понижение определенно исходило не от меня. Я исправил проблему, я написал ответ выше.

Dave 06.04.2023 17:08
Ответ принят как подходящий

Я обнаружил проблему. Я не совсем уверен, когда это произошло, возможно, это было результатом intellisense, я не знаю.

Этот:

public class Company
{
    [JsonPropertyName("companyID")]
    public string CompanyID { get; set; }
    [JsonPropertyName("vehicleIDs")]
    public List<string> VehicleIDs { get; set; }
    [JsonPropertyName("email")]
    public string Email { get; set; }
    [JsonPropertyName("companyName")]
    public string CompanyName { get; set; }
}

Стал:

public class Company : ApiController
{
    [JsonPropertyName("companyID")]
    public string CompanyID { get; set; }
    [JsonPropertyName("vehicleIDs")]
    public List<string> VehicleIDs { get; set; }
    [JsonPropertyName("email")]
    public string Email { get; set; }
    [JsonPropertyName("companyName")]
    public string CompanyName { get; set; }
}

Удаление: ApiController решил проблему.

Другие вопросы по теме