我目前正在使用asp.net webform从mssql中的数据库中提取数据。我有三个表(tOptions,tModel,tOptions_Model),数据域是(OptionsID,Options,ModelID,Model)。表单的作用是,当您从下拉列表中选择其中一个模型时,它将发送一个sql查询以获取与该模型对应的所有选项。我遇到的错误是,当您从下拉列表中选择其中一个模型时,这是收到的错误:
System.Data.dll中出现'System.Data.SqlClient.SqlException'类型的异常,但未在用户代码中处理
附加信息:'3'附近的语法不正确(3表示在下拉列表中选择的模型,因此它将是ddl中的第三个项目)。我的问题是,这是根据所选模型获取所有选项的正确方法吗?
public partial class ModelsAndOptions : System.Web.UI.Page
{
private static System.Data.SqlClient.SqlConnection conn;
private static SqlDataSourceCommandEventArgs comm;
private static SqlDataReader reader;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
OpenConnection();
}
}
protected void ddlModel_SelectedIndexChanged(object sender, EventArgs e)
{
int optionsID;
string options;
ListItem optionsItem;
// clear the listbox just in case something is already inside it.
lbxOptions.Items.Clear();
string result = ("SELECT Options, OptionsID FROM tOptions WHERE ID = '('" + ddlModel.SelectedValue + "')'");
SqlCommand comm = new SqlCommand(result, conn);
try
{
reader.Close();
} catch (Exception ex)
{
}
//use reader obj to execute query
reader = comm.ExecuteReader();
// iterate through dataset by each line
while (reader.Read())
{
// stores primary key of options
optionsID = reader.GetInt32(0);
// stores name
options = reader.GetString(1);
// creates a list item with text of both the primary key and the name
optionsItem = new ListItem(options, optionsID.ToString());
// add items to the listbox
lbxOptions.Items.Add(optionsItem);
}
}
private void OpenConnection()
{
System.Configuration.ConnectionStringSettings strConn;
strConn = ReadConnectionString();
conn = new System.Data.SqlClient.SqlConnection(strConn.ConnectionString);
try
{
conn.Open();
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
}
private System.Configuration.ConnectionStringSettings ReadConnectionString()
{
//string to store the path
String strPath;
strPath = HttpContext.Current.Request.ApplicationPath + "/Web.config";
//object that points to web.config file
System.Configuration.Configuration rootWebConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(strPath);
System.Configuration.ConnectionStringSettings connString = null;
// if the connection string is working, then set the object to equal the connection string located inside the web.config file
if (rootWebConfig.ConnectionStrings.ConnectionStrings.Count > 0)
{
connString = rootWebConfig.ConnectionStrings.ConnectionStrings["kroegedlConnectionString"];
}
// return the connection string setting obj
return connString;
}
protected void btnAddOne_Click(object sender, EventArgs e)
{
lbxChosenOptions.Items.Add(lbxOptions.SelectedItem);
lbxOptions.Items.Remove(lbxOptions.SelectedItem);
}
}
答案 0 :(得分:2)
提交太多罪
// Extract method: do not cram everything into single IndexChanged
private void CoreAddOptions() {
// Do not open a global connection
// Wrap IDisposable into using
using (SqlConnection conn = new SqlConnection(ConnectionString)) {
conn.Open();
// Make Sql Readable
// Make Sql paramterized
string sql =
@"select Options,
OptionsID
from tOptions
where Id = @prm_Id";
// Wrap IDisposable into using
using (SqlCommand comm = new SqlCommand(sql, conn)) {
// Do not hardcode SQL but use parameters
comm.Parameters.AddWithValue("@prm_Id", ddlModel.SelectedValue);
// Wrap IDisposable into using
using (var reader = comm.ExecuteReader()) {
while (reader.Read()) {
// Use Convert instead of Get + ToString
var optionsItem = new ListItem(
Convert.ToString(reader[0]),
Convert.ToString(reader[1]));
lbxOptions.Items.Add(optionsItem);
}
}
}
}
}
然后
protected void ddlModel_SelectedIndexChanged(object sender, EventArgs e) {
CoreAddOptions();
}
答案 1 :(得分:0)
创建存储过程并将经过验证的参数传递给它。 这可以减少SQL注入,并允许您更轻松地测试代码。
将所有资源包含在using语句中以确保它们被处置掉。