Bound Dropdown List not populating into sql table on save

huangapple go评论57阅读模式
英文:

Bound Dropdown List not populating into sql table on save

问题

I have two dropdownlists that are bound to two columns in a sql table1. When I select an item within the dropdownlists and click my save button, the text in the dropdownlist does not appear in the sql table2.

The textbox data as well as the other dropdownlists that are not bound to a sql table, are saving into my sql table2.

I am using a stored procedure in sql to save the data from my webform to sql.

Stored Procedure:

USE [OnCallWeb]
GO
/****** Object: StoredProcedure [dbo].[DispatchRolesCreateOrUpdate] Script Date: 6/8/2023 10:10:04 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROC [dbo].[DispatchRolesCreateOrUpdate]
@ID int,
@Name nvarchar(max),
@Position nvarchar(max),
@Roles nvarchar(max),
@Status nvarchar(max),
@DispatcherCovering nvarchar(max)
AS
BEGIN
IF(@ID=0)
BEGIN
INSERT INTO Dispatcher_Roles(Name,Position,Roles,Status,DispatcherCovering)
VALUES(@Name,@Position,@Roles,@Status,@DispatcherCovering)
END
ELSE
BEGIN
UPDATE Dispatcher_Roles
SET
Name = @Name,
Position = @Position,
Roles = @Roles,
Status = @Status,
DispatcherCovering = @DispatcherCovering
Where ID= @ID
END
END

My CS code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Configuration;
using System.Data.SqlClient;

namespace OnCallWeb.Dispatch_Policies
{
public partial class WorkstationRoles : System.Web.UI.Page
{
SqlConnection sqlcon = new SqlConnection(@"Data Source=UCPDAPPS2;Initial Catalog=OnCallWeb;Integrated Security=true;");
protected void Page_Load(object sender, EventArgs e)
{
string mainconn = ConfigurationManager.ConnectionStrings["Reporting_SystemConnectionString"].ConnectionString;
SqlConnection sqlconn = new SqlConnection(mainconn);
string sqlquery = "select [ID],[Emp_ID] + ' ' + [Emp_Name] as FullName from [dbo].[Personnel] where [JurisdictionID] = 99";
SqlCommand sqlcomm = new SqlCommand(sqlquery, sqlconn);
sqlconn.Open();
DataSet ds = new DataSet();
SqlDataAdapter sda = new SqlDataAdapter(sqlcomm);
sda.Fill(ds);
DropDownList1.DataSource = ds;
DropDownList1.DataTextField = "FullName";
DropDownList1.DataValueField = "ID";
DropDownList1.DataBind();
DropDownList1.Items.Insert(0, new ListItem("", "0"));
DropDownList4.DataSource = ds;
DropDownList4.DataTextField = "FullName";
DropDownList4.DataValueField = "ID";
DropDownList4.DataBind();
DropDownList4.Items.Insert(0, new ListItem("", "0"));
sqlconn.Close();


if (!IsPostBack)
{
btnDelete.Enabled = false;
}
}

protected void btnClear_Click(object sender, EventArgs e)
{
Clear();
}

public void Clear()
{
ID.Value = "";
DropDownList1.Items.Clear();
DropDownList2.Items Clear();
TextBox1.Text = "";
DropDownList3.Items.Clear();
DropDownList4.Items.Clear();
lblSuccessMessage.Text = lblErrorMessage.Text = "";
btnSave.Text = "Save";
btnDelete.Enabled = false;
}

protected void btnSave_Click(object sender, EventArgs e)
{
if (sqlcon.State == ConnectionState.Closed)
sqlcon.Open();
SqlCommand sqlCmd = new SqlCommand("DispatchRolesCreateOrUpdate",sqlcon);
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.Parameters.AddWithValue("@ID",(ID.Value==""?0:Convert.ToInt32(ID.Value)));
sqlCmd.Parameters.AddWithValue("@Name",DropDownList1.SelectedItem.Text);
sqlCmd.Parameters.AddWithValue("@Position",DropDownList2.Text.Trim());
sqlCmd.Parameters.AddWithValue("@Roles",TextBox1.Text.Trim());
sqlCmd.Parameters.AddWithValue("@Status",DropDownList3.Text.Trim());
sqlCmd.Parameters.AddWithValue("@DispatcherCovering",DropDownList4.SelectedItem.Text);
sqlCmd.ExecuteNonQuery();
sqlcon.Close();
Clear();
if (ID.Value == "")
lblSuccessMessage.Text = "Saved Successfully";
else
lblSuccessMessage.Text = "Updated Successfully";
}
}
}

I have tried changing the addwithvalues SelectedItem.Text to SelectedItem.Value which did not resolve the issue.

英文:

I have two dropdownlists that are bound to two columns in a sql table1. When I select an item within the dropdownlists and click my save button, the text in the dropdownlist does not appear in the sql table2.

The textbox data as well as the other dropdownlists that are not bound to a sql table, are saving into my sql table2.

I am using a stored procedure in sql to save the data from my webform to sql.

Stored Procedure:

USE [OnCallWeb]
GO
/****** Object:  StoredProcedure [dbo].[DispatchRolesCreateOrUpdate]    Script Date: 6/8/2023 10:10:04 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROC [dbo].[DispatchRolesCreateOrUpdate]
@ID int,
@Name nvarchar(max),
@Position nvarchar(max),
@Roles nvarchar(max),
@Status nvarchar(max),
@DispatcherCovering nvarchar(max)
AS
BEGIN
IF(@ID=0)
BEGIN
INSERT INTO Dispatcher_Roles(Name,Position,Roles,Status,DispatcherCovering)
VALUES(@Name,@Position,@Roles,@Status,@DispatcherCovering)
END
ELSE
BEGIN
UPDATE Dispatcher_Roles
SET
Name = @Name,
Position = @Position,
Roles = @Roles,
Status = @Status,
DispatcherCovering = @DispatcherCovering
Where ID= @ID
END
END

My CS code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
namespace OnCallWeb.Dispatch_Policies
{
public partial class WorkstationRoles : System.Web.UI.Page
{
SqlConnection sqlcon = new SqlConnection(@"Data Source=UCPDAPPS2;Initial Catalog=OnCallWeb;Integrated Security=true;");
protected void Page_Load(object sender, EventArgs e)
{
string mainconn = ConfigurationManager.ConnectionStrings["Reporting_SystemConnectionString"].ConnectionString;
SqlConnection sqlconn = new SqlConnection(mainconn);
string sqlquery = "select [ID],[Emp_ID] + '  ' + [Emp_Name] as FullName from [dbo].[Personnel] where [JurisdictionID] = 99";
SqlCommand sqlcomm = new SqlCommand(sqlquery, sqlconn);
sqlconn.Open();
DataSet ds = new DataSet();
SqlDataAdapter sda = new SqlDataAdapter(sqlcomm);
sda.Fill(ds);
DropDownList1.DataSource = ds;
DropDownList1.DataTextField = "FullName";
DropDownList1.DataValueField = "ID";
DropDownList1.DataBind();
DropDownList1.Items.Insert(0, new ListItem("", "0"));
DropDownList4.DataSource = ds;
DropDownList4.DataTextField = "FullName";
DropDownList4.DataValueField = "ID";
DropDownList4.DataBind();
DropDownList4.Items.Insert(0, new ListItem("", "0"));
sqlconn.Close();
if (!IsPostBack)
{
btnDelete.Enabled = false;
}
}
protected void btnClear_Click(object sender, EventArgs e)
{
Clear();
}
public void Clear()
{
ID.Value = "";
DropDownList1.Items.Clear();
DropDownList2.Items.Clear();
TextBox1.Text = "";
DropDownList3.Items.Clear();
DropDownList4.Items.Clear();
lblSuccessMessage.Text = lblErrorMessage.Text = "";
btnSave.Text = "Save";
btnDelete.Enabled = false;
}
protected void btnSave_Click(object sender, EventArgs e)
{
if (sqlcon.State == ConnectionState.Closed)
sqlcon.Open();
SqlCommand sqlCmd = new SqlCommand("DispatchRolesCreateOrUpdate",sqlcon);
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.Parameters.AddWithValue("@ID",(ID.Value==""?0:Convert.ToInt32(ID.Value)));
sqlCmd.Parameters.AddWithValue("@Name",DropDownList1.SelectedItem.Text);
sqlCmd.Parameters.AddWithValue("@Position",DropDownList2.Text.Trim());
sqlCmd.Parameters.AddWithValue("@Roles",TextBox1.Text.Trim());
sqlCmd.Parameters.AddWithValue("@Status",DropDownList3.Text.Trim());
sqlCmd.Parameters.AddWithValue("@DispatcherCovering",DropDownList4.SelectedItem.Text);
sqlCmd.ExecuteNonQuery();
sqlcon.Close();
Clear();
if (ID.Value == "")
lblSuccessMessage.Text = "Saved Successfully";
else
lblSuccessMessage.Text = "Updated Successfully";
}
}
}

I have tried changing the addwithvalues SelectedItem.Text to SelectedItem.Value which did not resolve the issue.

答案1

得分: 0

以下是翻译好的内容:

简单的答案?

你必须将首次页面加载的代码放置在!IsPostBack内,该代码用于加载和设置下拉列表。

请记住,在任何按钮点击或启用autopostback=true的控件上,都会发生页面回发。

因此,在你的情况下,页面加载运行,下拉列表被加载。

当用户点击按钮时,页面加载将再次触发,然后运行你的按钮存根代码。

然而,由于在页面加载时,你重新加载了下拉控件,所以用户的选择将丢失。

因此,请将你的下拉列表的“加载”代码放在真正的第一次页面加载中(在!IsPostBack代码存根内),因为这样下拉列表就不会在每次页面回发时重新加载。

这样,用户的选择和值在每次点击按钮时都不会被覆盖。

你还应该进入项目->设置,并使用向导创建你的连接字符串。

例如在这里:

Bound Dropdown List not populating into sql table on save

所以,有了上面的知识,并且我建议将连接字符串的内容移出代码(因为在代码中更改所有硬编码的连接字符串可能会相当困难),然后我建议使用以下代码:

而我有一个全局(静态)类,其中包含我的辅助函数,它们如下:

public static DataTable MyRstP(SqlCommand cmdSQL)
{
    DataTable rstData = new DataTable();
    using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
    {
        using (cmdSQL)
        {
            cmdSQL.Connection = conn;
            conn.Open();
            rstData.Load(cmdSQL.ExecuteReader());
        }
    }
    return rstData;
}

public static void MyRstE(SqlCommand cmdSQL)
{
    using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
    {
        using (cmdSQL)
        {
            cmdSQL.Connection = conn;
            conn.Open();
            cmdSQL.ExecuteNonQuery();
        }
    }
}

因此,我在一个地方存放了连接甚至使用了SQL命令对象。(这不仅在编码时很方便,而且意味着你可以在部署时轻松更改连接字符串)。

因此,现在你的代码变成了这样:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        LoadData();
        btnDelete.Enabled = false;
    }
}

void LoadData()
{
    string sqlquery 
        = @"select [ID],[Emp_ID] + ' ' + [Emp_Name] as FullName from 
           [dbo].[Personnel] where [JurisdictionID] = 99";

    SqlCommand cmdSQL = new SqlCommand(sqlquery);
    DataTable dt = General.MyRstP(cmdSQL);
    DropDownList1.DataSource = dt;
    DropDownList1.DataTextField = "FullName";
    DropDownList1.DataValueField = "ID";
    DropDownList1.DataBind();
    DropDownList1.Items.Insert(0, new ListItem("", "0"));

    DropDownList4.DataSource = dt;
    DropDownList4.DataTextField = "FullName";
    DropDownList4.DataValueField = "ID";
    DropDownList4.DataBind();
    DropDownList4.Items.Insert(0, new ListItem("", "0"));
}

protected void btnSave_Click(object sender, EventArgs e)
{
    SqlCommand sqlCmd = new SqlCommand("DispatchRolesCreateOrUpdate");
    sqlCmd.CommandType = CommandType.StoredProcedure;

    sqlCmd.Parameters.Add("@ID", SqlDbType.Int).Value = (ID.Value == "" ? 0 : Convert.ToInt32(ID.Value));
    sqlCmd.Parameters.Add("@Name", SqlDbType.NVarChar).Value =  DropDownList1.SelectedItem.Text;
    sqlCmd.Parameters.Add("@Position", SqlDbType.NVarChar).Value =  DropDownList2.Text.Trim();
    sqlCmd.Parameters.Add("@Roles", SqlDbType.NVarChar).Value = TextBox1.Text;  
    sqlCmd.Parameters.Add("@Status", SqlDbType.NVarChar).Value =  DropDownList3.Text;
    sqlCmd.Parameters.Add("@DispatcherCovering", SqlDbType.NVarChar).Value =  DropDownList4.SelectedItem.Text);
    General.MyRstE(sqlCmd);

    if (ID.Value == "")
        lblSuccessMessage.Text = "Saved Successfully";
    else
        lblSuccessMessage.Text = "Updated Successfully";
}

所以,请检查!IsPostBack。你只能在首次页面加载和首次页面加载时加载下拉控件。如果像你一样每次重新加载下拉控件,那么用户的选择将在每次回发时丢失。

编辑:需要不同的连接字符串。

由于你需要处理不止一个连接字符串,那么我建议为这两个辅助函数使用以下代码:

public static DataTable MyRstP(SqlCommand cmdSQL, string sCon = "")
{
    DataTable rstData = new DataTable();
    if (sCon == "")
        sCon = Properties.Settings.Default.TEST4;

    using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
    {
        using (cmdSQL)
        {
            cmdSQL.Connection = conn;
            conn.Open();
            rstData.Load(cmdSQL.ExecuteReader());
        }
    }
    return rstData;
}

public static void MyRstE(SqlCommand cmdSQL, string sCon = "")
{
    if (sCon == "")
        sCon = Properties.Settings.Default.TEST4;

    using (SqlConnection conn = new SqlConnection(sCon))
    {
        using (cmdSQL)
        {
            cmdSQL.Connection = conn;
            conn.Open();
            cmdSQL.ExecuteNonQuery();
        }
    }
}

因此,现在对于你代码的99%来说,你可以使用主数据库的连接。

然而,现在,对于需要使用不同连接的情况,你可以使用以下方式:

MyRstE(cmdSQL, Properties.Settings.Default.MyOtherDB)
英文:

The simple answer?

You have to place your FIRST time page load code, the code that loads + set's up the dropdown lists inside of the !IsPostBack.

Remember, on any button click, or even controls with autopostback = true, then a page post back occurs.

So, in your case, page load runs, dropdowns are loaded up.

When a user clicks a button, page load will fire again, and then your button stub code runs.

However, since on page load, you re-load the dropdown controls again, then the user's choice will be lost.

So place your down down list "loading" code inside of the REAL first page load (inside of the !IsPostBack code stub, since then the dropdown lists will not be re-loaded each page post-back).

Thus, the user choices and values will not be over-write each time a button is clicked.

You should also go project->settings, and use the wizards to create your connection string.

Eg here:

Bound Dropdown List not populating into sql table on save

So, with above knowledge in mind, and my suggesting to remove the connection string stuff out of code (since it will be rather difficult to change all those hard coded connection strings in code), then I suggest this code:

And I have a global (static) class with my helper routines, they are this:

    public static DataTable MyRstP(SqlCommand cmdSQL)
{
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (cmdSQL)
{
cmdSQL.Connection = conn;
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
public static void MyRstE(SqlCommand cmdSQL)
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (cmdSQL)
{
cmdSQL.Connection = conn;
conn.Open();
cmdSQL.ExecuteNonQuery();
}
}
}

So, I have ONE location for the connection and even the use of the SQL command object. (not only is this nice and and handy while coding, it also means you can easy change the connection string at deployment time).

So, now your code becomes this:

    protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
LoadData();
btnDelete.Enabled = false;
}
}
void LoadData()
{
string sqlquery 
= @"select [ID],[Emp_ID] + '  ' + [Emp_Name] as FullName from 
[dbo].[Personnel] where [JurisdictionID] = 99";
SqlCommand cmdSQL = new SqlCommand(sqlquery);
DataTable dt = General.MyRstP(cmdSQL);
DropDownList1.DataSource = dt;
DropDownList1.DataTextField = "FullName";
DropDownList1.DataValueField = "ID";
DropDownList1.DataBind();
DropDownList1.Items.Insert(0, new ListItem("", "0"));
DropDownList4.DataSource = dt;
DropDownList4.DataTextField = "FullName";
DropDownList4.DataValueField = "ID";
DropDownList4.DataBind();
DropDownList4.Items.Insert(0, new ListItem("", "0"));
}
protected void btnSave_Click(object sender, EventArgs e)
{
SqlCommand sqlCmd = new SqlCommand("DispatchRolesCreateOrUpdate");
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.Parameters.Add("@ID", SqlDbType.Int).Value = (ID.Value == "" ? 0 : Convert.ToInt32(ID.Value));
sqlCmd.Parameters.Add("@Name", SqlDbType.NVarChar).Value =  DropDownList1.SelectedItem.Text;
sqlCmd.Parameters.Add("@Position", SqlDbType.NVarChar).Value =  DropDownList2.Text.Trim();
sqlCmd.Parameters.Add("@Roles", SqlDbType.NVarChar).Value = TextBox1.Text;  
sqlCmd.Parameters.Add("@Status", SqlDbType.NVarChar).Value =  DropDownList3.Text;
sqlCmd.Parameters.Add("@DispatcherCovering",SqlDbType.NVarChar).Value =  DropDownList4.SelectedItem.Text);
General.MyRstE(sqlCmd);
if (ID.Value == "")
lblSuccessMessage.Text = "Saved Successfully";
else
lblSuccessMessage.Text = "Updated Successfully";
}

So, check the !IsPostBack. You can only load ONE time and on FIRST page load the dropdown controls. If you re-load dropdown's each time as you have, then the user's selections will be lost on each post-back.

Edit: Different connection strings are required.

Since you have to deal with MORE then one connection string, then I suggest this code for the 2 helper routines:

    public static DataTable MyRstP(SqlCommand cmdSQL, string sCon = "")
{
DataTable rstData = new DataTable();
if (sCon == "")
sCon = Properties.Settings.Default.TEST4;
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (cmdSQL)
{
cmdSQL.Connection = conn;
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
public static void MyRstE(SqlCommand cmdSQL, string sCon = "")
{
if (sCon == "")
sCon = Properties.Settings.Default.TEST4;
using (SqlConnection conn = new SqlConnection(sCon))
{
using (cmdSQL)
{
cmdSQL.Connection = conn;
conn.Open();
cmdSQL.ExecuteNonQuery();
}
}
}

So, now, for 99% of your code, then you can/have/use/enjoy the main overall connection for the given database.

HOWEVER, now, for cases in which you want to use a different connection, then you can go

  MyRstE(cmdSQL,Properties.Settings.Default.MyOtherDB)

huangapple
  • 本文由 发表于 2023年6月9日 00:09:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76433820.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定