I have a table and one of the column is YesNo which is of type varchar(3). I have two radio buttons in my PDF file which is in an array:
pg1rb (radio group field)
--> c1 (radio button one (yes))
--> c2 (radio button two (no))
I set textboxes like this in my code:
formFieldMap["topmostSubform[0].Page1[0].f1_01_0_[0]"] = reader.GetValue(0).ToString();
How can I select YES or NO radio button based on the row value?
Can I do something like this:
formFieldMap["pg1rb"] = reader.GetBoolean(10); //10 is the 9th column which is Yes/No value
Or do I get the value and based on it select the radio button, something like this:
if (reader.GetValue(10).ToString() == "Yes") {
formFieldMap["pg1rb"][c1] = "1";
else {
formFieldMap["pg1rb"][c2] = "1";
}
My SQL table:
I am trying to follow this site: Website example
My function that actually does the conversion:
public void writeData(string k, string c)
{
Conn = new SqlConnection(cString);
Conn.Open();
//MessageBox.Show(k);
//MessageBox.Show(c);
var pdfPath = Path.Combine(Server.MapPath("~/PDFTemplates/forme.pdf"));
// Get the form fields for this PDF and fill them in!
var formFieldMap = PDFHelper.GetFormFieldNames(pdfPath);
//if more than multiple entries, verify by name and the last four ssn
sqlCode = "SELECT * FROM [DSPCONTENT01].[dbo].[TablePDFTest] WHERE [name] = '" + k + "' AND [ssn3] = " + c + "";
//sqlCode = "SELECT * FROM [DSPCONTENT01].[dbo].[TablePDFTest] WHERE [name] = #name2 AND [ssn3] = #ssnnum";
//MessageBox.Show("" + sqlCode.ToString());
using (SqlCommand command = new SqlCommand(sqlCode, Conn))
{
command.CommandType = CommandType.Text;
//command.Parameters.AddWithValue("name2", k);
//command.Parameters.AddWithValue("ssnnum", c);
using (reader = command.ExecuteReader())
{
if (reader.HasRows)
{
if (reader.Read())
{
//MessageBox.Show(reader.GetValue(0).ToString());
/*formFieldMap["topmostSubform[0].Page1[0].f1_01_0_[0]"] = reader.GetValue(0).ToString();
formFieldMap["topmostSubform[0].Page1[0].f1_02_0_[0]"] = reader.GetValue(1).ToString();
formFieldMap["topmostSubform[0].Page1[0].f1_04_0_[0]"] = reader.GetValue(2).ToString();
formFieldMap["topmostSubform[0].Page1[0].f1_05_0_[0]"] = reader.GetValue(3).ToString();
formFieldMap["topmostSubform[0].Page1[0].f1_07_0_[0]"] = reader.GetValue(4).ToString();
formFieldMap["topmostSubform[0].Page1[0].social[0].TextField1[0]"] = reader.GetValue(5).ToString();
formFieldMap["topmostSubform[0].Page1[0].social[0].TextField2[0]"] = reader.GetValue(6).ToString();
formFieldMap["topmostSubform[0].Page1[0].social[0].TextField2[1]"] = reader.GetValue(7).ToString();
formFieldMap["topmostSubform[0].Page1[0].social[0].TextField2[2]"] = reader.GetValue(8).ToString();
formFieldMap["topmostSubform[0].Page1[0].social[0].TextField2[3]"] = reader.GetValue(9).ToString();*/
if (reader.GetValue(10).ToString() == "Yes")
{
//MessageBox.Show("YES");
}
else if (reader.GetValue(10).ToString() == "No")
{
//MessageBox.Show("NO");
}
}
}
}
}
// Requester's name and address (hard-coded)
formFieldMap["topmostSubform[0].Page1[0].f1_06_0_[0]"] = "Medical Group\n12 Westchester Ave\nPurchase, NY 10121";
var pdfContents = PDFHelper.GeneratePDF(pdfPath, formFieldMap);
PDFHelper.ReturnPDF(pdfContents, "Completed-W9.pdf");
}
The PDFHelper class:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Web;
using System.IO;
using iTextSharp.text.pdf;
public class PDFHelper
{
public static Dictionary<string, string> GetFormFieldNames(string pdfPath)
{
var fields = new Dictionary<string, string>();
var reader = new PdfReader(pdfPath);
foreach (DictionaryEntry entry in reader.AcroFields.Fields)
fields.Add(entry.Key.ToString(), string.Empty);
reader.Close();
return fields;
}
public static byte[] GeneratePDF(string pdfPath, Dictionary<string, string> formFieldMap)
{
var output = new MemoryStream();
var reader = new PdfReader(pdfPath);
var stamper = new PdfStamper(reader, output);
var formFields = stamper.AcroFields;
foreach (var fieldName in formFieldMap.Keys)
formFields.SetField(fieldName, formFieldMap[fieldName]);
stamper.FormFlattening = false;
stamper.Close();
reader.Close();
return output.ToArray();
}
// See http://stackoverflow.com/questions/4491156/get-the-export-value-of-a-checkbox-using-itextsharp/
public static string GetExportValue(AcroFields.Item item)
{
var valueDict = item.GetValue(0);
var appearanceDict = valueDict.GetAsDict(PdfName.AP);
if (appearanceDict != null)
{
var normalAppearances = appearanceDict.GetAsDict(PdfName.N);
// /D is for the "down" appearances.
// if there are normal appearances, one key will be "Off", and the other
// will be the export value... there should only be two.
if (normalAppearances != null)
{
foreach (var curKey in normalAppearances.Keys)
if (!PdfName.OFF.Equals(curKey))
return curKey.ToString().Substring(1); // string will have a leading '/' character, so remove it!
}
}
// if that doesn't work, there might be an /AS key, whose value is a name with
// the export value, again with a leading '/', so remove it!
var curVal = valueDict.GetAsName(PdfName.AS);
if (curVal != null)
return curVal.ToString().Substring(1);
else
return string.Empty;
}
public static void ReturnPDF(byte[] contents)
{
ReturnPDF(contents, null);
}
public static void ReturnPDF(byte[] contents, string attachmentFilename)
{
var response = HttpContext.Current.Response;
if (!string.IsNullOrEmpty(attachmentFilename))
response.AddHeader("Content-Disposition", "attachment; filename=" + attachmentFilename);
response.ContentType = "application/pdf";
response.BinaryWrite(contents);
response.End();
}
}
Your question was confusing because it used a reader object that didn't refer to iTextSharp's PdfReader class and it used a formFieldMap object of which the type was unknown (it doesn't seem related to iTextSharp). Your edit was very welcome to understand the question.
The field names you mention look as if they are fields in an XFA form, but the article you refer to talks about filling out AcroForm documents, so let's assume that your form was indeed born as an XFA form, but later on converted to an AcroForm.
In this case, nobody will be able to tell you which values to pick to set the radio buttons without seeing the PDF. Please download chapter 6 of my book and read section 6.3.5, more specifically where it says Inspecting the form and its fields. On page 183, you can read that the possible values for a group of radio buttons is either "Off"–no radio button is selected— or a code that is defined in the form itself.
For instance: in the example from the book, the possible values for the category group were spec, toro, anim, etc...
This means that you can set a radio box in that group like this:
formFields.SetField("category", "spec");
or:
formFields..SetField("category", "toro");
or:
formFields.SetField("category", "anim");
and so on.
So, if you want to set a radio button in a radiogroup named pg1rb, you first need to know which are the possible values. You assume that the possible values are "Yes" and "No" in which case you could use:
formFields.SetField("pg1rb", "Yes");
or
formFields.SetField("pg1rb", "No");
But the possible values could also be "1" and "0", "On" and "Off", "true" and "false",... The possible values were chosen by the person who created the form.
You can get these values programmatically by using the code from page 182:
StringBuilder sb = new StringBuilder();
sb.Append("Possible values for pg1rb:");
sb.Append(Environment.NewLine);
states = form.GetAppearanceStates("pg1rb");
for (int i = 0; i < states.Length - 1; i++) {
sb.Append(states[i]);
sb.Append(", ");
}
sb.Append(states[states.Length - 1]);
Inspect what was written to the sb object and you have the values you are looking for.
Related
I have to make a select statement on a database and than compare the results with a text file using only C# in Visual Studio. If the text file has a bigger value than the record in the database, the program returns the value from the text file, and if the database record has a bigger value, the program returns the value from the database. The results are added to a list being a class WynikPorownania{}. The user types in the file an index of a product and the value(in this case the value is it's availability condition).
For example:
The textfile says this:
WYR_WR_CZ1=12
VIDIS_JIMU_BOX=3
REREK_KOTEK_T=5
In the database, theses indexes are connected to an availability condition like this
WYR_WR_CZ1=-1.0000
VIDIS_JIMU_BOX=-13.0000
REREK_KOTEK_T=0.0000
Now the program should return the bigger value in a list being the WynikPorownania{} class.
For now, I managed to do this much: I took every record from the select query and put it in to a list as a class. I have a function that checks the "standysp"(availability condition) for a specified index, and I asigned the text file value to a string. I think that it could be done maybe with this "zwr" function and maybe a loop but I don't really know where to go from now on. This is my code for now:
using System;
using FirebirdSql.Data.FirebirdClient;
using System.Collections.Generic;
using System.Linq;
using System.IO;
namespace dokselect
{
class indexstan
{
public string index;
public double standysp;
}
class WynikPorownania
{
public string Indeks;
public int Ilosc;
}
class Program
{
public static void Main()
{
///////CONNECTION
string conn = "database=C:/PCBiznes/BAZA/IXION2_LOGMAG.FB;user=SYSDBA;password=masterkey;DataSource=192.168.24.112;Port=3050";
FbConnection myConnection = new FbConnection(conn);
FbDataReader myReader = null;
string sql = "select KARTOTEKA.indeks,STANMAG.standysp FROM kartoteka JOIN stanmag using(ID_KARTOTEKA);";
FbCommand myCommand = new FbCommand(sql, myConnection);
myConnection.Open();
myReader = myCommand.ExecuteReader();
///////LIST lista1
List<indexstan> lista1 = new List<indexstan>();
double standysp;
string index;
while (myReader.Read())
{
index = myReader[0].ToString();
standysp = Convert.ToDouble(myReader[1]);
lista1.Add(new indexstan { index=index, standysp=standysp });
//Console.WriteLine(myReader[0].ToString());
}
myConnection.Close();
Console.WriteLine(lista1.Count);
//RETURN STANDYSP FUNCTION
double zwr(string myIndex)
{
var result = lista1.FirstOrDefault(lista1 => lista1.index == myIndex).standysp;
return result;
}
zwr("EMPIS_DESKA_FASOLKA");
//READ FROM TXT
string path = "C:/Users/Praktykant/Documents/textdocs/dok1.txt";
string plik = File.ReadAllText(path);
//Console.WriteLine(plik);
StreamReader objReader = new StreamReader(path);
myConnection.Close();
}
}
You mean something like this?
var list = File.ReadAllLines(path).Select(line =>
{
var tokens = line.Split("=");
var index = tokens[0];
var value = int.Parse(tokens[1]);
return new WynikPorownania
{
Indeks = index,
Ilosc = (int)Math.Max(value, zwr(index).standysp)
}
}).ToList();
(Depending on the size of the file, a StreamReader would be better than ReadAllLines)
You're almost there.
Extract text file line by line, and compute bigger value
StringReader r = new StringReader(plik);
string line;
while((line = r.ReadLine()) != null)
{
string index = line.Split('=')[0];
string textValue = line.Split('=')[1];
double biggerValue = Math.Max(
zwr(index),
double.Parse(textValue);
Console.WriteLine($"{index} > {biggerValue}");
}
I have a .csv file structured like so, first row is the header column, for each SomeID I need to add the NetCharges together(or substract if the code calls for it) and put each item into its own column by the SomeCode column.
Heres the file I receive;
SomeID,OrderNumber,Code,NetCharge,Total
23473,30388,LI 126.0000, 132.00
96021, 000111, LI, 130.00, 126.00
23473,30388,FU 6.0000, 132.00
4571A,10452,LI,4100.0000, 4325.0000
4571A,10452,FU,150.00,4325.0000
4571A,10452,DT,75.00,4325.0000
I need to insert the data to my sql table which is structured like this. This is what I'm aiming for:
ID OrderNumber LICode LICodeValue FUCode FUCodeValue DTCode, DTCodeValue, total
23473 30388n LI 126.000 FU 6.0000 NULL NULL 132.0000
4571A 10452 LI 4100.0000 FU 150.0000 DT 75.00 4325.0000
My SomeID will not always be grouped together like the 4571A id is.I basically need to iterate over this file and create one record for each SomeID. I cannot seem to find a way with csvHelper. I'm using C# and csvHelper. I have trid this so far but I cannot get back to the SomeId after passing on to the nexr one:
using (var reader = new StreamReader( "C:\testFiles\some.csv" ))
using (var csv = new CsvReader( reader, CultureInfo.InvariantCulture ))
{
var badRecords = new List<string>();
var isRecordBad = false;
csv.Configuration.HasHeaderRecord = true;
csv.Configuration.HeaderValidated = null;
csv.Configuration.IgnoreBlankLines = true;
csv.Configuration.Delimiter = ",";
csv.Configuration.BadDataFound = context =>
{
isRecordBad = true;
badRecords.Add( context.RawRecord );
};
csv.Configuration.MissingFieldFound = ( s, i, context ) =>
{
isRecordBad = true;
badRecords.Add( context.RawRecord );
};
List<DataFile> dataFile = csv.GetRecords<DataFile>().ToList();
//initialize variable
string lastSomeId = "";
if (!isRecordBad)
{
foreach (var item in dataFile)
{
// check if its same record
if (lastSomeId != item.SomeID)
{
MyClass someClass = new MyClass();
lastSomeId = item.SomeID;
//decimal? LI = 0;//was going to use these as vars for calculations not sure I need them???
//decimal? DSC = 0;
//decimal? FU = 0;
someClass.Id = lastSomeId;
someClass.OrdNum = item.OrderNumber;
if (item.Code == "LI")
{
someClass.LICode = item.Code;
someClass.LICodeValue = item.NetCharge;
}
if (item.Code == "DT")
{
someClass.DTCode = item.Code;
someClass.DTCodeValue = item.NetCharge
}
if (item.Code == "FU")
{
someClass.FUCode = item.Code;
someClass.FUCodeValue = item.NetCharge;
}
someClass.Total = (someClass.LICodeValue + someClass.FUCodeValue);
//check for other values to calculate
//insert record to DB
}
else
{
//Insert into db after maipulation of values
}
}
}
isRecordBad = false;
}//END Using
Any clues would be greatly appreciated. Thank you in advance.
I am using MySQLClient with a local database. I wrote a method which returns a list of data about the user, where I specify the columns I want the data from and it generates the query dynamically.
However, the reader is only returning the column names rather than the actual data and I don't know why, since the same method works previously in the program when the user is logging in.
I am using parameterised queries to protect from SQL injection.
Here is my code. I have removed parts which are unrelated to the problem, but i can give full code if needed.
namespace Library_application
{
class MainProgram
{
public static Int32 user_id;
static void Main()
{
MySqlConnection conn = LoginProgram.Start();
//this is the login process and works perfectly fine so i won't show its code
if (conn != null)
{
//this is where things start to break
NewUser(conn);
}
Console.ReadLine();
}
static void NewUser(MySqlConnection conn)
{
//three types of users, currently only using student
string query = "SELECT user_role FROM Users WHERE user_id=#user_id";
Dictionary<string, string> vars = new Dictionary<string, string>
{
["#user_id"] = user_id.ToString()
};
MySqlDataReader reader = SQLControler.SqlQuery(conn, query, vars, 0);
if (reader.Read())
{
string user_role = reader["user_role"].ToString();
reader.Close();
//this works fine and it correctly identifies the role and creates a student
Student user = new Student(conn, user_id);
//later i will add the logic to detect and create the other users but i just need this to work first
}
else
{
throw new Exception($"no user_role for user_id - {user_id}");
}
}
}
class SQLControler
{
public static MySqlDataReader SqlQuery(MySqlConnection conn, string query, Dictionary<string, string> vars, int type)
{
MySqlCommand cmd = new MySqlCommand(query, conn);
int count = vars.Count();
MySqlParameter[] param = new MySqlParameter[count];
//adds the parameters to the command
for (int i = 0; i < count; i++)
{
string key = vars.ElementAt(i).Key;
param[i] = new MySqlParameter(key, vars[key]);
cmd.Parameters.Add(param[i]);
}
//runs this one
if (type == 0)
{
Console.WriteLine("------------------------------------");
return cmd.ExecuteReader();
//returns the reader so i can get the data later and keep this reusable
}
else if (type == 1)
{
cmd.ExecuteNonQuery();
return null;
}
else
{
throw new Exception("incorrect type value");
}
}
}
class User
{
public List<string> GetValues(MySqlConnection conn, List<string> vals, int user_id)
{
Dictionary<string, string> vars = new Dictionary<string, string> { };
//------------------------------------------------------------------------------------
//this section is generating the query and parameters
//using parameters to protect against sql injection, i know that it ins't essential in this scenario
//but it will be later, so if i fix it by simply removing the parameterisation then im just kicking the problem down the road
string args = "";
for (int i = 0; i < vals.Count(); i++)
{
args = args + "#" + vals[i];
vars.Add("#" + vals[i], vals[i]);
if ((i + 1) != vals.Count())
{
args = args + ", ";
}
}
string query = "SELECT " + args + " FROM Users WHERE user_id = #user_id";
Console.WriteLine(query);
vars.Add("#user_id", user_id.ToString());
//-------------------------------------------------------------------------------------
//sends the connection, query, parameters, and query type (0 means i use a reader (select), 1 means i use non query (delete etc..))
MySqlDataReader reader = SQLControler.SqlQuery(conn, query, vars, 0);
List<string> return_vals = new List<string>();
if (reader.Read())
{
//loops through the reader and adds the value to list
for (int i = 0; i < vals.Count(); i++)
{
//vals is a list of column names in the ame order they will be returned
//i think this is where it's breaking but im not certain
return_vals.Add(reader[vals[i]].ToString());
}
reader.Close();
return return_vals;
}
else
{
throw new Exception("no data");
}
}
}
class Student : User
{
public Student(MySqlConnection conn, int user_id)
{
Console.WriteLine("student created");
//list of the data i want to retrieve from the db
//must be the column names
List<string> vals = new List<string> { "user_forename", "user_surname", "user_role", "user_status"};
//should return a list with the values in the specified columns from the user with the matching id
List<string> return_vals = base.GetValues(conn, vals, user_id);
//for some reason i am getting back the column names rather than the values in the fields
foreach(var v in return_vals)
{
Console.WriteLine(v);
}
}
}
What i have tried:
- Using getstring
- Using index rather than column names
- Specifying a specific column name
- Using while (reader.Read)
- Requesting different number of columns
I have used this method during the login section and it works perfectly there (code below). I can't figure out why it doesnt work here (code above) aswell.
static Boolean Login(MySqlConnection conn)
{
Console.Write("Username: ");
string username = Console.ReadLine();
Console.Write("Password: ");
string password = Console.ReadLine();
string query = "SELECT user_id, username, password FROM Users WHERE username=#username";
Dictionary<string, string> vars = new Dictionary<string, string>
{
["#username"] = username
};
MySqlDataReader reader = SQLControler.SqlQuery(conn, query, vars, 0);
Boolean valid_login = ValidLogin(reader, password);
return (valid_login);
}
static Boolean ValidLogin(MySqlDataReader reader, string password)
{
Boolean return_val;
if (reader.Read())
{
//currently just returns the password as is, I will implement the hashing later
password = PasswordHash(password);
if (password == reader["password"].ToString())
{
MainProgram.user_id = Convert.ToInt32(reader["user_id"]);
return_val = true;
}
else
{
return_val = false;
}
}
else
{
return_val = false;
}
reader.Close();
return return_val;
}
The problem is here:
string args = "";
for (int i = 0; i < vals.Count(); i++)
{
args = args + "#" + vals[i];
vars.Add("#" + vals[i], vals[i]);
// ...
}
string query = "SELECT " + args + " FROM Users WHERE user_id = #user_id";
This builds a query that looks like:
SELECT #user_forename, #user_surname, #user_role, #user_status FROM Users WHERE user_id = #user_id;
Meanwhile, vars.Add("#" + vals[i], vals[i]); ends up mapping #user_forename to "user_forename" in the MySqlParameterCollection for the query. Your query ends up selecting the (constant) value of those parameters for each row in the database.
The solution is:
Don't prepend # to the column names you're selecting.
Don't add the column names as variables to the query.
You can do this by replacing that whole loop with:
string args = string.Join(", ", vals);
I'm trying to change several button images according to what state I get in the database.
If I get any state "0" I should change the button image to a "busy" image, since the default image is a "free" one.
So my question is: How can i change a button through a variable name?
I have this code for now(i know its wrong):
private void checkSuites()
{
SqlCeCommand checkSuite = new SqlCeCommand("SELECT * FROM RentSessionLog WHERE State='0'", mainConnection);
SqlCeDataReader readSuite = checkSuite.ExecuteReader();
int suiteIndex;
string suitePath = "suite" + suiteIndex;
while (readSuite.Read())
{
suiteIndex = Convert.ToInt32(readSuite["SuiteNum"]);
suitePath.Image = NewSoftware.Properties.Resources.busySuiteImg;
}
}
It's as simple as:
while (readSuite.Read())
{
suiteIndex = Convert.ToInt32(readSuite["SuiteNum"]);
switch(suiteIndex)
{
case 0:
{
suitePath.Image = NewSoftware.Properties.Resources.busySuiteImg;
break;
}
default:
{
suitePath.Image = NewSoftware.Properties.Resources.freeSuiteImg;
}
}
}
Edit:
The reason I used a switch is in case you have other-states appearing in the future. You have "Busy" and "Free", but there could be "Reserved" as well and you may want to have further conditions that would just get obfuscated in a simple if else if sequence.
I believe you need to use this.Controls.Find(suitePath, true) to turn your string into a control. I am presuming that "suite" + suiteIndex is the .Name of each of your buttons.
string suitePath = "suite" + suiteIndex;
Button suiteButton = this.Controls.Find(suitePath, true);
suiteButton.Image = ...
See more details about Controls.Find
Alternatively for quicker access, you may want to keep a Dictionary<int, Control> with each of your buttons in it.
I DID IT! Using a dictionary as Thymine said:
public void checkSuites()
{
Dictionary<int, Control> btnList = new Dictionary<int, Control>();
btnList.Add(1, suite1);
btnList.Add(2, suite2);
btnList.Add(3, suite3);
btnList.Add(4, suite4);
btnList.Add(5, suite5);
SqlCeCommand checkSuite = new SqlCeCommand("SELECT * FROM RentSessionLog WHERE State='0'", mainConnection);
SqlCeDataReader readSuite = checkSuite.ExecuteReader();
while (readSuite.Read())
{
int suiteIndex = Convert.ToInt32(readSuite["SuiteNum"]);
string suitePath = "suite" + suiteIndex;
foreach (Button key in btnList.Values)
{
if (key.Name == suitePath)
{
key.Image = NewSoftware.Properties.Resources.busySuiteImg;
}
}
}
}
Thank you all who helped :D
I have the below code that gets added to a literal in my form. How in the code behind to I grab get/set the data from the select = name="populationSelect"....?
protected void PopulatePopulation()
{
StringBuilder sb = new StringBuilder();
StringBuilder sql = new StringBuilder();
// Define sql
sql.Append("SELECT pid, population ");
sql.Append("FROM populations ");
sql.Append("ORDER BY pid ASC ");
using (IDataReader reader = SqlHelper.GetDataReader(sql.ToString()))
{
sb.AppendLine("<div class=\"narrowRes\">Poulation</div><select name=\"populationSelect\" class=\"narrowResSelect\"><option value=\"0\">All populations</option>");
while (reader.Read())
{
int pid = reader.IsDBNull(0) ? -1 : reader.GetInt32(0);
string population = reader.IsDBNull(1) ? string.Empty : reader.GetString(1);
population = population.Trim();
sb.AppendLine(string.Format("<option value=\"{0}\">{1}</option>", pid, population));
}
}
sb.AppendLine("</select>");
ltrlExplorePopulation.Text = sb.ToString();
}
Not easily. Since you're using a literal instead of an asp.net control (like a drop down list), asp.net does not create a control for you to use in the code behind.
That being said you should be able to access the value through the Request parameters.
var value = Request["populationSelect"];
A better solution would be to create a dropdownlist control on the page and databind to it.
if (!IsPostBack)
{
List<ListItem> data = new List<ListItem>();
using (IDataReader reader = SqlHelper.GetDataReader(sql.ToString()))
{
//sb.AppendLine("<div class=\"narrowRes\">Poulation</div><select name=\"populationSelect\" class=\"narrowResSelect\"><option value=\"0\">All populations</option>");
while (reader.Read())
{
int pid = reader.IsDBNull(0) ? -1 : reader.GetInt32(0);
string population = reader.IsDBNull(1) ? string.Empty : reader.GetString(1);
population = population.Trim();
data.Add(new ListItem(population, pid.ToString()));
//sb.AppendLine(string.Format("<option value=\"{0}\">{1}</option>", pid, population));
}
}
DropDownList1.DataSource = data;
DropDownList1.DataBind();
}