wtorek, 4 stycznia 2011

Element 'DropDownList' ma wartość SelectedValue, która jest nieprawidłowa, ponieważ nie istnieje na liście elementów... [PL]

Jakiś czas temu był na tym blogu wpis dotyczący GridView i TemplateField, czyli sposobu wygodniejszą wizualizację i edycję danych tabelarycznych. W ten sposób łatwo można zamienić skomplikowane numeryczne identyfikatory (pochodzące z kluczy obcych) na dropdown-listy przedstawiające dane z innych tabel. Jednak co się stanie, gdy nasza kolumna z identyfikatorami dopuszcza wartości puste (NULL)? Otóż pojawi się wtedy „błąd serwera w aplikacji ....”. Zobaczmy jak sobie można z tym poradzić.
Załóżmy, że pierwotnie kreator dodał nam następującą kolumnę w GridView:
<asp:BoundField DataField="ID_PODKATEGORII" HeaderText="ID_PODKATEGORII" SortExpression="ID_PODKATEGORII" />
Oczywiście, korzystając z wcześniej opisanej metody, zamieniamy to, na coś podobnego do:
            <asp:TemplateField HeaderText="Podkategoria" SortExpression="ID_PODKATEGORII">
                <ItemTemplate>
                    <asp:DropDownList ID="DropDownList_subcategory_disp" runat="server" DataSourceID="ObjectDataSource_subcategories"
                        DataTextField="NAZWA" DataValueField="ID" SelectedValue='<%# Bind("ID_PODKATEGORII") %>'
                        Enabled="false" >
                    </asp:DropDownList>
                </ItemTemplate>
                <EditItemTemplate>
                    <asp:DropDownList ID="DropDownList_subcategory_edit" runat="server" DataSourceID="ObjectDataSource_subcategories"
                        DataTextField="NAZWA" DataValueField="ID" SelectedValue='<%# Bind("ID_PODKATEGORII") %>' >
                    </asp:DropDownList>
                </EditItemTemplate>
            </asp:TemplateField>
I w efekcie możemy otrzymać (pisownia oryginalna :) ):

Błąd serwera w aplikacji '/'.


Element 'DropDownList_subcategory_disp' ma wartość SelectedValue, ktra jest nieprawidłowa, ponieważ nie istnieje na liście elementw.
Nazwa parametru: value

Opis: Podczas wykonywania bieżącego żądania sieci Web wystąpił nieobsługiwany wyjątek. Aby uzyskać dodatkowe informacje o błędzie i miejscu jego występowania w kodzie, przejrzyj ślad stosu.

Szczegły wyjątku: System.ArgumentOutOfRangeException: Element 'DropDownList_subcategory_disp' ma wartość SelectedValue, ktra jest nieprawidłowa, ponieważ nie istnieje na liście elementw.
Nazwa parametru: value

Błąd źrdła:

Podczas wykonywania bieżącego żądania sieci Web został wygenerowany nieobsługiwany wyjątek. Informacje dotyczące pochodzenia i lokalizacji wyjątku można zidentyfikować przy użyciu poniższego śladu stosu wyjątku.



Dlaczego tak się dzieje, otóż w moim przypadku kolumna ID_PODKATEGORII dopuszczała wartości puste (NULL), a takiej nie było wśród ID z tabeli opisującej podkategorie.
Rozwiązanie problemu okazuje się bardzo proste, wystarczy dodać element do dropdown-listy o wartości pustej (np. <asp:ListItem Text="Not set." Value="" ></asp:ListItem>) oraz we właściwościach dropdown-lity ustawić możliwość uzupełnienia listy o wartości dopisane (AppendDataBoundItems = "true"). W efekcie otrzymamy coś podobnego do:
            <asp:TemplateField HeaderText="Podkategoria" SortExpression="ID_PODKATEGORII">
                <ItemTemplate>
                    <asp:DropDownList ID="DropDownList_subcategory_disp" runat="server" DataSourceID="ObjectDataSource_subcategories"
                        DataTextField="NAZWA" DataValueField="ID" SelectedValue='<%# Bind("ID_PODKATEGORII") %>'
                        Enabled="false" AppendDataBoundItems = "true">
                        <asp:ListItem Text="Not set." Value=""></asp:ListItem>
                    </asp:DropDownList>
                </ItemTemplate>
                <EditItemTemplate>
                    <asp:DropDownList ID="DropDownList_subcategory_edit" runat="server" DataSourceID="ObjectDataSource_subcategories"
                        DataTextField="NAZWA" DataValueField="ID" SelectedValue='<%# Bind("ID_PODKATEGORII") %>' AppendDataBoundItems = "true">
                        <asp:ListItem Text="Not set." Value="" ></asp:ListItem>
                    </asp:DropDownList>
                </EditItemTemplate>
            </asp:TemplateField>
Co da nam:

Proste prawda? A może ktoś zna alternatywne rozwiązanie?
Promuj

1 komentarz:

  1. Ten sposób rozwiązuje tylko część problemu (brak wartości), natomiast często błąd wyskakuje przy hierarchicznych listach, kiedy zmieniamy pozycje listy nadrzędnej wyskakuje błąd, bo indeks z listy podrzędnej nie występuje jako dozwolona wartość na nowej wartości nadrzędnej. Masz może jakieś rozwiązanie wyłapujące wszystkie nieprawidłowe wartości nie tylko brak wartości?

    OdpowiedzUsuń

Posty powiązane / Related posts