NullReferenceException w pętli foreach

0

Problem nie występuje u mnie lokalnie, natomiast występuje na jednym serwerze (a na drugim nie). Niestety mam ograniczony dostęp do tego serwera, więc rady w stylu: "Porównaj konfigurację" możemy od razu odłożyć na bok ;)

Jest to API w .NET Core 3.1. Publikacja na serwer to wgranie plików z folderu publish. Publish jest z następującymi ustawieniami:

Configuration: Release - Any CPU
Target Framework: netcoreapp3.1
Deployment Mode: Self-Contained
Target Runtime: win-x64

Z tego co wiem o serwerze to jest to serwer IIS na Windowsie.

Dobra, tyle tytułem wstępu, zanim zaczniecie się zastanawiać, po co ustawienia publikacji podaję, skoro już z tytułu wątku wiadomo, że na pewno obiekt, po którym próbuję iterować, jest nullem ;) Oto kod, który rzuca NullReferenceException:

private List<Link> AdjustItems(string text, List<Link> items)
{
	int x = -1;
	try
	{
		x = items.Count;
		foreach (var item in items) //-------TUTAJ rzuca NullReferenceException
		{
			///
		}

		return items;
	}
	catch (Exception e)
	{
		throw new MyException("items.Count: " + x, e);
	}            
}

Ponieważ NullReferenceException jest rzucany w linii z pętelką, moją pierwszą myślą było, że pewnie items jakimś cudem jest puste. Prześledziłam jednak możliwe ścieżki i nijak mi to nie pasowało. Przede wszystkim - z analizy wynikało mi, że jeśli items byłoby puste, to funkcja wołająca AdjustItems powinna już rzucić wyjątkiem. Dodałam więc sczytywanie items.Count i teraz widzę już wprost, że dzieje się magia - w logach w treści wyjątku wyświetla się:

items.Count: 3

Czyli items nie jest puste, nie jest nullem. Tymbardziej, że po dodaniu linijki x = items.Count wyjątek wciąż rzucany jest dopiero na linijce z pętlą.

Teraz już powinno być jasne, czemu podaję konfigurację publikacji... Czy zdarzyło się wam, żeby NullReference poszedł z powodu braku deklaracji foreach? :D Czy też sama nie wiem czego. Moje dalsze strzały, to że brakuje czegoś, co jest deklarowane w tej klasie (ale inne metody tej klasy wyjątków nie rzucały...).

Sama teraz zamierzam przepisać pętlę na while, spróbować iterować po innych obiektach, posprawdzam sobie stan atrybutów klasy... Jednak ponieważ problem występuje na serwerze, do którego mam ograniczony dostęp, samo wgrywanie zmian chwilę zajmie... Dlatego piszę z nadzieją, że komuś zdarzyło się coś podobnego ;)

2
  1. Jesteś pewna, że binarki na serwer wgrywają się prawidłowo i linijka z logów jest tą samą, którą widzisz w kodzie źródłowym?
  2. A żaden item nie jest nullem? Co się dzieje w tej pętli?
0

Ad. 1. Mogę tylko potwierdzić, że gdy zmieniam kod, to linijki w logach sensownie się przesuwają (a ten exception idzie 3 poziomy wyżej, zanim trafi do logów, i wszystkie StackTrace'y trafiają OK). Niestety nie mam wpływu na proces wgrywania (nad czym mocno ubolewam).

Ad. 2. A nawet gdyby item był nullem, to co...? Mogłabym to sprawdzić na przykład tak:

bool CzyJakisItemJestNullem(List<item> items)
{
    foreach (var item in items)
    {
        if (item == null) return true;
    }
    return false;
}

Prawda....? ;)

Tak czy siak, nie sądzę, by item był nullem, bo gdy debuguję lokalnie, to dostaję normalną listę 3 obiektów. Uwzględnię jednak sprawdzenie i tym co za chwilę będę pisać.

Cała pętla:

foreach (var link in links)
{
    var textBefore = text.Substring(0, link.Index);
    var moveIndex = CountCharactersOfTagInText(textBefore.Replace(supEnd, ""), supStart, textBefore.Length);
    moveIndex += CountCharactersOfTagInText(textBefore.Replace(supStart, ""), supEnd, textBefore.Length);

    var linkText = text.Substring(link.Index - moveIndex);
    var moveEnd = CountCharactersOfTagInText(linkText.Replace(supEnd, ""), supStart, link.Length);
    moveEnd += CountCharactersOfTagInText(linkText.Replace(supStart, ""), supEnd, link.Length);

    link.Index -= moveIndex;
    link.Length += moveEnd;
}

Wcześniejsze items tutaj to oczywiście links. supEnd i supStart to consty, które tak naprawdę są zadeklarowane na samym początku funkcji AdjustItems (nie uwzględniałam wcześniej, żeby nie zaciemniać kodu).

2

foreach woła GetEnumerator() oraz MoveNext(). Sprawdź dokładnie, co masz w całym stack trace wyjątku i idź tym tropem. BTW na pewno masz tam List<T>, a nie IEnumerable<T>?

5
aurel napisał(a):

Prawda....? ;)

Prawda, i myślę, że warto to zrobić.
Podobnie jak logować całą kolekcję, a nie tylko Count.
Bo mnie się wydaje, że w release może zachodzić jakieś inlinowanie albo coś w tym stylu, i zwyczajnie jest jakiś problem z operacjami na tym itemie.
Albo może to text jest nullem?

1

@somekind masz rację, okazało się, że każdy item jest == null. To oczywiście wciąż problem, ale przenosi moje debugowanie w zupełnie inne miejsce ;) Dzięki!

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