我是ASP.NET新手,
我正在制作国家/地区下拉列表。
例如:对于特定国家/地区,我将从缓存文件中读取该国家/地区的状态。
当用户第一次访问时, LOGIC: ,此时缓存将为空,因此将从XMLFile
获取相应的状态并将其状态插入缓存,下次当用户访问同一个国家/地区时,应该从缓存而不是XMLFile
获取状态。
我无法在下拉列表中获取所需国家/地区的状态...
这是我的代码段,
protected void DropDownListCountry_SelectedIndexChanged(object sender, EventArgs e)
{
string SelectedCountry = DropDownListCountry.SelectedItem.Text;
XDocument doc = XDocument.Load(Server.MapPath("XMLFile.xml"));
var query = from country in doc.Descendants("country")
where country.Attribute("name").Value == SelectedCountry
select new
{
states = from state in country.Elements("state")
select new{
Name = state.Attribute("name").Value
}
};
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("Name"));
if (Cache["key"]==null)
{
foreach (var st in query)
{
foreach (var StateName in st.states)
{
DataRow dr = dt.NewRow();
dr["Name"] = StateName.Name;
dt.Rows.Add(dr);
Cache.Insert("key", dr);
}
}
DropDownListState.DataSource = dt;
DropDownListState.DataTextField = "Name";
DropDownListState.DataBind();
}
else
{
object obj = Cache["key"];
dt.Rows.Add(obj);
DropDownListState.DataSource = dt;
DropDownListState.DataTextField = "Name";
DropDownListState.DataBind();
}
}
提前致谢!!
答案 0 :(得分:2)
此代码存在一些问题,例如处理数据和UI的方式,使用缓存以及错误,每个对象的缓存键应该是唯一的。
因此,让我们重构一下代码并创建一个方法,该方法返回带有国家/地区名称的状态的DataTable。如果状态已经在缓存中,则将返回缓存中的DataTable。
private static DataTable GetStates(string countryName)
{
DataTable dt = HttpContext.Current.Cache[countryName] as DataTable;
if (dt != null)
return dt;
// the datatable is not in cache, let's create it then and add it to cache, next call will pick it from cache and won't read and parse the xml again
var doc = XDocument.Load(HttpContext.Current.Server.MapPath("XMLFile.xml"));
var query = from country in doc.Descendants("country")
where country.Attribute("name").Value == countryName
select new
{
states = from state in country.Elements("state")
select new
{
Name = state.Attribute("name").Value
}
};
dt = new DataTable();
dt.Columns.Add(new DataColumn("Name"));
foreach (var st in query)
{
foreach (var StateName in st.states)
{
DataRow dr = dt.NewRow();
dr["Name"] = StateName.Name;
dt.Rows.Add(dr);
}
}
// add the data table in the cache (not a row and don't use the same key)
HttpContext.Current.Cache.Insert(countryName, dt);
// return this table
return dt;
}
现在是事件处理程序
protected void DropDownListCountry_SelectedIndexChanged(object sender, EventArgs e)
{
var countryName = DropDownListCountry.SelectedItem.Text;
var dt = GetStates(countryName);
DropDownListState.DataSource = dt;
DropDownListState.DataTextField = "Name"; // you can set it in markup also
DropDownListState.DataBind();
}
所有用户都共享缓存,因此如果您打算这样做,则可以使用它。
答案 1 :(得分:0)
这样的事情可能有所帮助:
private DataTable PopulateCountryList()
{
DataTable dt = (DataTable)Cache["countries"];
if (dt == null)
{
dt.Columns.Add(new DataColumn("Name"));
XDocument doc = XDocument.Load(Server.MapPath("XMLFile.xml"));
var query = from country in doc.Descendants("country")
where country.Attribute("name").Value == SelectedCountry
select new
{
states = from state in country.Elements("state")
select new {
Name = state.Attribute("name").Value
}
};
foreach (var st in query)
{
foreach (var StateName in st.states)
{
DataRow dr = dt.NewRow();
dr["Name"] = StateName.Name;
dt.Rows.Add(dr);
}
}
Cache.Insert("countries", dt, null, DateTime.Today.AddDays(1), TimeSpan.Zero);
}
return = dt;
}
如果你想填充Dropdown:
DropDownListState.DataSource = PopulateCountryList();
DropDownListState.DataTextField = "Name";
DropDownListState.DataBind();