Nieprawidłowy wynik parsowania jsona

0

Witam. W kontrolerze mam Model:

public class MachineDetailTableRowModel
    {
        public string MachineName { get; set; }
        
        public string ConcentrationValue { get; set; }
        public string ConcentrationColor { get; set; }
        public MachineReport.eLevelState PhLevelState { get; set; }
        public string PhValue { get; set; }
        public string PhColor { get; set; }
        public MachineReport.eLevelState TrampOilLevelState { get; set; }
        public string TrampOilValue { get; set; }
        public string TrampOilColor { get; set; }
        public string CleanOutDate { get; set; }
        public bool OnlySummaryData { get; set; } = false;
        public MachineComment[] LastReportComments { get; set; }
    }
public class MachineComment
    {
        public string Date { get; set; }
        public string Comment { get; set; }
        public string CircleColor { get; set; }
    }

i akcję kontrolera zwracającą widok częściowy:

        [Authorize]
        [Route("GenerateMachineDetailTableRow")]
        public IActionResult GenerateMachineDetailTableRow(MachineDetailTableRowModel Model)
        {
            _logger.LogInformation(JsonConvert.SerializeObject(Model));
            return PartialView("ReportGenerator/_MachineDetailTableRow", Model);
        }

Skrypt js generuje następujące dane:

var data = {
                MachineName: machineData.machineName,
                ConcentrationValue: machineData.concentrationValue,
                ConcentrationColor: machineData.concentrationColor,
                PhValue: machineData.phValue,
                PhColor: machineData.phColor,
                TrampOilValue: machineData.trampOilValue,
                TrampOilColor: machineData.trampOilColor,
                CleanOutDate: machineData.cleanOutDate,
                LastReportComments: machineData.commentsFromLastReport.map(function(value, label){
                    return {
                        CircleColor: value.circleColor,
                        Comment: value.Comment,
                        Date: value.date
                    }
                }),
                OnlySummaryData: onlySummaryData,
            };
        console.log(data);
        var htmlData = $.ajax({
            url: '/ReportGenerator/GenerateMachineDetailTableRow',
            data: data,
            ...

Pole w skrypcie o nazwie poniżej jest wypełnione poprawnie, jednak po przekazaniu do modelu otrzymuję pustą tablicę. Próbowałem wyrzucić obiekt MachineComment i wstawić tablicę typu string[], z tym samym skutkiem. Gdzie może leżeć błąd? Dodam, że problem jest tylko i wyłącznie z LastReportComments

LastReportComments
1

Od strony Javascriptu musisz zamienić zmienną data przed wysłaniem w JSON i uzupełnić pole type / dataType.

const htmlData = $.ajax({
  type: 'post',
  url: '/ReportGenerator/GenerateMachineDetailTableRow',
  data: JSON.stringify(data),
  dataType: 'json',
  // ...
});
0

Zmieniłem dataType: 'json', ale bez wstawiania data: JSON.stringify(data),, ponieważ wtedy już żadna z właściwości nie pobiera wartości. problem mam tylko z niepoprawnym konwertowaniem tablicy (pierwszy raz coś takiego mi się zdarza).

0

Cały obiekt jest prawidłowo widoczny. Mam go w kontrolerze. Jedyne co to ta jedna właściwość. Wszystkie nazwy się zgadzają. Wygląda jakby sama tablica nie zostawała rozpoznana. To jest impossible

0

@_13th_Dragon: à propos tej stronki to może źle powiedziałem troszkę. Nie dysponuję jako tako jsonem. Mam obiekty tutaj, które widzę w przeglądarce w podglądzie, że są utworzone prawidłowo

LastReportComments: machineData.commentsFromLastReport.map(function(value, label){
  return {
    CircleColor: value.circleColor,
    Comment: value.Comment,
    Date: value.date
  }
}),

Po sprawdzeniu w przeglądarce mają poprawne wartości. Przy przesłaniu do kontrolera debugger pokazuje mi pustą tablicę. Co lepsze, jak spróbuje wysłać to do kontrolera jako tekst i zdeserializuję JsonConvert.Deserializeobject() to wszystkie wartości są poprawne, ale to nieeleganckie :( tak więc argumenty wysyłane do kontrolera są w 100% poprawne

2

A masz w Program.cs wpis żeby używać Newtonsoft.Json?

builder.Services.AddControllers().AddNewtonsoftJson();

Domyślny System.Text.Json już nie raz miał problemy z prostymi zadaniami.

0
AdamWox napisał(a):

A masz w Program.cs wpis żeby używać Newtonsoft.Json?

builder.Services.AddControllers().AddNewtonsoftJson();

Domyślny System.Text.Json już nie raz miał problemy z prostymi zadaniami.

jakis przyklad :)?
wystarczy uzywac jak w dokumentacji

nawet jesli, to nie od razu rzym zbudowano (ewentualnie spalono) :D, jest problem, to sie zglasza issue
az mi sie przypomina jak entity framework core nie mial lazy loading bodajze =D

uzaleznianie czezsto modeli bazodanowych od zewnetrznych bibliotek (newtonsoft.json) to porazka, dlatego powinno sie przechodzic na system.text.json
nigdy nie mialem problemu z ta juz standardowo libka

1
heyyou napisał(a):

uzaleznianie czezsto modeli bazodanowych od zewnetrznych bibliotek (newtonsoft.json) to porazka, dlatego powinno sie przechodzic na system.text.json
nigdy nie mialem problemu z ta juz standardowo libka

Ktoś coś pisał o bazach danych? I w czym ta przewaga System.Text.Json się przejawia? Bo na pewno Newtonsoft jest rozwiązaniem dojrzalszym, bardziej sprawdzonym, bardziej elastycznym (wygodne budowanie i modyfikacja JSON), ludzie go znają i są zadowoleni (jak widać powyżej). Lepsze jest wrogiem dobrego.

0

tym ze czesto widuje atrybuty serializacji w encjach bazodanowych z zewnetrznej biblioteki (tu newtonsfot.json)
uzaleznienie czegokolwiek (viewmodeli, dto) od zewnetrznej libki tez jest słabe imho

btw. newtonsoftjson w performance jest o wiele slabszy z tego co kojarze ;)

za komuny tez niektorym bylo dobrze, takze ten...

0
heyyou napisał(a):

uzaleznianie czezsto modeli bazodanowych od zewnetrznych bibliotek (newtonsoft.json) to porazka, dlatego powinno sie przechodzic na system.text.json

Z punktu widzenia modelu (jakiegokolwiek), to System.Text.Json jest równie obcy jak Newtonsoft.Json. Jeśli MS przyznaje, że ich wersja nie wspiera wszystkiego tego, co Newtonsoft, to migracja jest ryzykowna, no chyba że liczymy na farta, że nigdy nie będziemy potrzebowali nic spoza tego kawałka, który przypadkiem zaimplementowali.

0
somekind napisał(a):

Jeśli MS przyznaje, że ich wersja nie wspiera wszystkiego tego, co Newtonsoft, to migracja jest ryzykowna, no chyba że liczymy na farta, że nigdy nie będziemy potrzebowali nic spoza tego kawałka, który przypadkiem zaimplementowali.

Implementacja System.Text.Json w najnowszym .necie ma już wszystko czego potrzeba i jest znacznie szybsza; jeśli czegoś nie zaimplementowano to zazwyczaj dlatego że ten feature wykraczał poza granice przyzwoitości i nie powinien istnieć - można znaleźć dużo dyskusji na githubie i dokładnych tłumaczeń czemu czegoś nie przenieśli. Jeśli polegałeś na tych "kawałkach" to zazwyczaj oznacza że gryzłeś problem od d**y strony i pora się naprostować. Jasne że deserializator może przy okazji deserializacji ugotować zupę, zrobić audyt bezpieczeństwa i przetłumaczyć tekst na japoński, ale czy to najlepsze miejsce w kodzie żeby to zrobić?

4
obscurity napisał(a):

Implementacja System.Text.Json w najnowszym .necie ma już wszystko czego potrzeba i jest znacznie szybsza;

Ale skąd wiesz, czego mi potrzeba?

jeśli czegoś nie zaimplementowano to zazwyczaj dlatego że ten feature wykraczał poza granice przyzwoitości i nie powinien istnieć - można znaleźć dużo dyskusji na githubie i dokładnych tłumaczeń czemu czegoś nie przenieśli. Jeśli polegałeś na tych "kawałkach" to zazwyczaj oznacza że gryzłeś problem od d**y strony i pora się naprostować.

Tak, oczywiście. Jeśli soft czegoś nie wspiera, to jest to wina użytkownika.
Pracujesz na Maku? ;)

Jasne że deserializator może przy okazji deserializacji ugotować zupę, zrobić audyt bezpieczeństwa i przetłumaczyć tekst na japoński, ale czy to najlepsze miejsce w kodzie żeby to zrobić?

Jakoś nie widzę gotowania zupy na tej liście, w ogóle nie widzę rzeczy z serializacją niezwiązanych:
screenshot-20221109114003.png
źródło

Nie mówię, że System.Text.Json jest zły, żeby go nie używać, czy żeby nie migrować. Po prostu trzeba to robić z głową, będąc pewnym, że albo wspiera czego potrzebujemy OOB, albo że mamy czas na dorobienie sobie brakujących nam ficzerów.

1
somekind napisał(a):

źródło

A teraz kliknij sobie na "Not supported" i przy każdym masz wyjaśnienie. Trzy środkowe tyczą się nieprawidłowego JSONa niezgodnego ze standardem który Newtonsoft ignorował.
Ostatnie tyczy się tego że ludzie chcą przesyłać teksty dłuższe niż 125MB i tablice większe niż kilka milionów elementów. Może... ale tylko może - JSON nie jest najlepszym formatem do serializowania całej bazy danych i przesyłania plików binarnych? Rozumiem że ktoś może tego potrzebować bo tak jest łatwiej, ale raczej imo json powinien zawierać tylko linki lub id plików niż ich całą treść.

Jedyne z listy czego naprawdę brakuje to obsługa JsonPath, ale tę można sobie chwilowo załatwić za pomocą 3rd party paczek nugetowych, tak samo można zrobić z "Support for System.Runtime.Serialization attributes" czego już nie dodadzą bo zepsuło by to kompatybilność wsteczną. Reszta to nie tyle niewspierane funkcje co intencjonalna zmiana zachowania względem newtonsoftu.

Może to nie jest najlepsza pora na migrację, jeszcze dużo będzie zrobione w .NET 8 https://github.com/dotnet/runtime/issues/77020 ale nie ma moim zdaniem żadnych powodów żeby rekomendować używanie newtona w nowych projektach

1 użytkowników online, w tym zalogowanych: 0, gości: 1