Исправить ‘Выбранное значение, которое является недопустимым, поскольку оно не существует в списке элементов’ без изменения SQL

#c# #asp.net

#c# #asp.net

Вопрос:

 <asp:SqlDataSource ID="dsUsers" runat="server" 
     ConnectionString="<%$ ConnectionStrings:csDB1 %>" 
     SelectCommand="SELECT UserID, UserName, RoleID
                    FROM [Database1].[dbo].[Users]
                    ORDER BY UserName">
</asp:SqlDataSource>

<asp:SqlDataSource ID="dsRoles" runat="server" 
     ConnectionString="<%$ ConnectionStrings:csDB2 %>" 
     SelectCommand="SELECT RoleID, RoleName
                    FROM [Database2].[dbo].[Roles]
                    WHERE RoleActive = 1">
</asp:SqlDataSource>

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="UserID" OnRowDataBound="GridView1_RowDataBound" DataSourceID="dsUsers">
  <Columns>
    <asp:BoundField DataField="UserName" HeaderText="User Name" SortExpression="UserName" />
    <asp:TemplateField HeaderText="Role" ItemStyle-HorizontalAlign="Center">
      <ItemTemplate>
        <asp:DropDownList ID="ddRole" runat="server" SelectedValue='<%# Bind("RoleID") %>' DataSourceID="dsRoles" DataTextField="RoleName" DataValueField="RoleID"  AppendDataBoundItems="true">
          <asp:ListItem Text="-Select-" Value="" />
        </asp:DropDownList>
      </ItemTemplate>
    </asp:TemplateField>
  </Columns>
</asp:GridView>
  

Users Таблица и Roles table находятся в разных базах данных, используя отдельные строки подключения, я не могу это изменить. Мне сказали не выполнять никаких соединений между этими таблицами / базами данных.

Этот код выдает следующую ошибку:

‘ddRole’ имеет выбранное значение, которое недопустимо, поскольку оно не существует в списке элементов.

Я знаю, почему возникает ошибка. Есть пользователь, у которого есть RoleId, и роль была отключена в таблице ролей (RoleActive равно 0). Это случается не часто, но иногда случается. Я могу исправить это с помощью сценария SQL, чтобы либо изменить роль, либо изменить идентификатор роли пользователя на действительную роль. Однако я ищу решение, которое не приведет к появлению ошибки на веб-странице. В идеале я хотел бы видеть, что если значение не существует в записи dsRoles, то в выпадающем списке должен отображаться элемент «-Select =», который был добавлен. Однако я не был уверен, как это сделать.

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

1. Почему бы вам просто не сделать -Select- значение 0?

2. Вы могли бы попробовать сделать это в GridView RowDataBound и проверить столбец RoleId в rowdata на соответствие таблице Roles — выполнив запрос к нему (признаю, не очень эффективный!), И если RoleId не найден, установите для него значение ‘0’. Вы могли бы удалить свое Bind там и назначить его вручную в RowDataBound. Это может сработать. Или вариант — отключить те, которые не активны, чтобы они не могли быть выбраны пользователем, для чего также может потребоваться элемент управления javascript.

Ответ №1:

В вашем коде, когда вы привязываете выпадающий список, оберните вызов selectedvalue в try catch, таким образом, вы можете явно задать выбранное значение в случае возникновения ошибки. например

  dropdown.DataSource = dsUsers;
 dropdown.DataBind();

 try
 {
     dropdown.SelectedValue = yourvalue;
 }
 catch()
 {
    // set it to blank (-select one-) which is valid as its appended from databounditems
    dropdown.SelectedValue = "";
 }