I am trying to save array of data in database how to achieve it.
I have a form where three inputs PRODUCT_ID, TDC_NO, REVISION are there along with array list of values generated dynamically (sizeMin, sizeMax, tolMin, tolMax). I want to store those dynamically generated values in Prop_detail whose structure I have mentioned at below and PRODUCT_ID, TDC_NO, REVISION values in tdcProduct1 table whose structure I designed below.how to pass those array list of values from server side to database .and how to store further in database.
.aspx
<script type="text/javascript">
$(document).on("click", "[id*=btnFrmSubmit]", function () {
var user = {};
user.PRODUCT_ID = 1;
user.TDC_NO = $("[id*=Tdc_No]").val();
user.REVISION = $("#Revision").text();
/* Creating Array object as WireDimDetails to add in user object*/
var WireDimDetails = new Array();
$("#WireDimTbl tbody tr").each(function () {
var row = $(this);
/* Declare and sets the WireDimDetail object with the property which will add in WireDimDetails array object*/
var WireDimDetail = {};
var sizeMin = row.find("[id^=SizeMin]").val();
/* Checking if control exist or not else assign empty value in sizeMax*/
var sizeMax = row.find("[id^=SizeMax]") != "undefined" ? row.find("[id^=SizeMax]").val() : "";
var tolMin = row.find("[id^=TolMin]").val();
var tolMax = row.find("[id^=TolMax]").val();
/*Sets the Values of controls */
WireDimDetail.SizeMin = sizeMin;
WireDimDetail.SizeMax = sizeMax;
WireDimDetail.TolMin = tolMin;
WireDimDetail.TolMax = tolMax;
/*Add WireDimDetail object in WireDimDetails Array object*/
WireDimDetails.push(WireDimDetail);
})
/*Add WireDimDetails array of object to user object*/
user.WireDimDetails = WireDimDetails;
$.ajax({
type: "POST",
url: "TDC.aspx/SaveFrmDetails",
data: JSON.stringify({ user: user, }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert("Data has been added successfully.");
window.location.reload();
},
error: function (response) { alert(response.responseText); }
});
</script>
Server side
[WebMethod]
public static void SaveFrmDetails(User user)
{
string connectionString = ConfigurationManager.ConnectionStrings["conndbprodnew"].ConnectionString;
using (OracleConnection con = new OracleConnection(connectionString))
{
using (OracleCommand cmd = new OracleCommand("INSERT INTO TDC_PRODUCT1(PRODUCT_ID,TDC_NO, REVISION) VALUES (:PRODUCT_ID,:TDC_NO,:REVISION )",con))
{
cmd.CommandType = CommandType.Text;
List<WireDimDetail> wireDimDetails = user.WireDimDetails;
for (int i = 0; i < wireDimDetails.Count; i++)
{
WireDimDetail wireDimDetail = wireDimDetails[i];
string sizeMin = wireDimDetail.SizeMin;
string sizeMax = !string.IsNullOrEmpty(wireDimDetail.SizeMax) ? wireDimDetail.SizeMax : "0"; // set default value
string tolMin = wireDimDetail.TolMin;
string tolMax = wireDimDetail.TolMax;
}
cmd.Parameters.AddWithValue(":PRODUCT_ID",user.PRODUCT_ID);
cmd.Parameters.AddWithValue(":TDC_NO", user.TDC_NO);
cmd.Parameters.AddWithValue(":REVISION", user.REVISION);
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
}
Table structure for saving data and array list of data, tdcProduct1 table consist of three columns:
Productid | Tdc_no | Revision
And second table Prop_detail:
Tdc_no | Tdc_property
My concern is how to store an array of data in Prop_detail table at the same time while storing data in tdcProduct1 using SaveFrmDetails. Any ideas would be appreciated.
I think you want to save multiple WireDimDetail to Prop_detail per user
so a simple way is loop through the wireDimDetails and get string of wireDimDetail for inserting in Tdc_property.
After inserting row in TDC_PRODUCT1, for inserting details the code would be like:
[WebMethod]
public static void SaveFrmDetails(User user)
{
string connectionString = ConfigurationManager.ConnectionStrings["conndbprodnew"].ConnectionString;
using (OracleConnection con = new OracleConnection(connectionString))
{
using (OracleCommand cmd = new OracleCommand("INSERT INTO TDC_PRODUCT1(PRODUCT_ID,TDC_NO, REVISION) VALUES (:PRODUCT_ID,:TDC_NO,:REVISION )", con))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue(":PRODUCT_ID", user.PRODUCT_ID);
cmd.Parameters.AddWithValue(":TDC_NO", user.TDC_NO);
cmd.Parameters.AddWithValue(":REVISION", user.REVISION);
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
cmd.CommandText = "insert into Prop_detail(Tdc_no,Tdc_property) values(#tdN,#tdProp)";
foreach (WireDimDetail wireDimDetail in user.WireDimDetails)
{
cmd.Parameters.Clear();
var stringwriter = new System.IO.StringWriter();
var serializer = new System.Xml.Serialization.XmlSerializer(wireDimDetail.GetType());
serializer.Serialize(stringwriter, wireDimDetail);
cmd.Parameters.AddWithValue("#tdN", user.TDC_NO);
cmd.Parameters.AddWithValue("#tdProp", stringwriter.ToString());
cmd.ExecuteNonQuery();
}
con.Close();
}
}
}
the stringwriter is string of each WireDimDetail.
but if you want to new record for sizeMin,sizeMax,tolMin and tolMax change foreach loop to:
foreach (WireDimDetail wireDimDetail in user.WireDimDetails)
{
cmd.Parameters.Clear();
string[] strNumbers = new string[4]
{
wireDimDetail.SizeMin,
!string.IsNullOrEmpty(wireDimDetail.SizeMax) ? wireDimDetail.SizeMax : "0",
wireDimDetail.TolMin,
wireDimDetail.TolMax
};
foreach (string number in strNumbers)
{
cmd.Parameters.AddWithValue("#tdN", user.TDC_NO);
cmd.Parameters.AddWithValue("#tdProp", number);
cmd.ExecuteNonQuery();
}
}
EDIT:
The final try would be like :
[WebMethod]
public static void SaveFrmDetails(User user)
{
string connectionString = ConfigurationManager.ConnectionStrings["conndbprodnew"].ConnectionString;
using (OracleConnection con = new OracleConnection(connectionString))
{
using (OracleCommand cmd = new OracleCommand("INSERT INTO TDC_PRODUCT1(PRODUCT_ID,TDC_NO, REVISION) VALUES (:PRODUCT_ID,:TDC_NO,:REVISION )", con))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue(":PRODUCT_ID", user.PRODUCT_ID);
cmd.Parameters.AddWithValue(":TDC_NO", user.TDC_NO);
cmd.Parameters.AddWithValue(":REVISION", user.REVISION);
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
cmd.CommandText = "insert into Prop_detail(Tdc_no,Rowno,Prop_Name,Tdc_property) values(#tdN,#rowNo,#propN,#tdProp)";
int rowNum = 1;// You can get rowNum from DB and initiate it to last rowNum
foreach (WireDimDetail wireDimDetail in user.WireDimDetails)
{
cmd.Parameters.Clear();
Dictionary<string, string> strNumbers = new Dictionary<string, int>()
{
{"sizMin", wireDimDetail.SizeMin },
{"sizeMax" , !string.IsNullOrEmpty(wireDimDetail.SizeMax) ? wireDimDetail.SizeMax.ToString() : "0" },
{"tolMin", wireDimDetail.TolMin.ToString() },
{"tolMax", wireDimDetail.TolMax.ToString() }
};
cmd.Parameters.Clear();
foreach (KeyValuePair<string, string> kvp in strNumbers)
{
cmd.Parameters.AddWithValue("#tdN", user.TDC_NO);
cmd.Parameters.AddWithValue("#rowNo", rowNum);
cmd.Parameters.AddWithValue("#propN", kvp.Key);
cmd.Parameters.AddWithValue("#tdProp", kvp.Value);
cmd.ExecuteNonQuery();
}
rowNum++;
}
con.Close();
}
}
}
NOTES:
1- rowNum can be retrieved from DB and then increase (can be initiated by select max(rowNo) from Prop_detail).
2- I used dictionary to hold the name of variable such as sizeMax and etc, there are many ways to do this
Related
I am doing a small project with asp.net. Part of the assignment is me retrieving information from an SQL Server Database. So far, I just needed single records, so I used the follow code:
public string getTwitterSearchHistory(string userId)
{
if (userId != null)
{
List<string> history = new List<string>();
string result = "";
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
conn.Open();
SqlCommand command = new SqlCommand("SELECT searchedTerm FROM dbo.TwitterSearchHistoryModels WHERE userId = #userId", conn);
command.Parameters.AddWithValue("#userId", userId);
using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.Read())
{
result = String.Format("{0}", reader["searchedTerm"]);
}
}
conn.Close();
return result;
}
return "";
}
Now, this code works perfect when I would want retrieve a property from one record. However, now I need to retrieve a property from multiple properties. Meaning, lets say I have the following:
ID | UserId | searchedTerm
--------------------------------
1 | 1 | hello
2 | 1 | anothersearchedterm
3 | 1 | this is a term
How can I retrieve all searchedTerms for userId 1 and store them in some kind of array?
Thanks!
**EDIT:
I am sending an Ajax request to a method inside my controller, as such.
function loadHistory() {
var detailsForGet = {
userId: sessionStorage.getItem("userName")
}
$.ajax({
type: "GET",
url: "https://localhost:44326/User/getTwitterSearchHistory",
data: detailsForGet,
success: function (data) {
console.log(data)
}
});
}
Now, in the controller I have this method which executes a select query from a local DB:
public List<string> getTwitterSearchHistory(string userId)
{
if (userId != null)
{
List<string> history = new List<string>();
string result = "";
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
conn.Open();
SqlCommand command = new SqlCommand("SELECT searchedTerm FROM dbo.TwitterSearchHistoryModels WHERE userId = #userId", conn);
command.Parameters.AddWithValue("#userId", userId);
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
history.Add(String.Format("{0}", reader["searchedTerm"]));
}
}
conn.Close();
return history;
}
return null;
}
Now, while debugging, I can see that the variable history holds the values good, however, in my success in thew ajax call, when I try to print the data, I get the following: System.Collections.Generic.List`1[System.String]..
What am I doing wrong please? Thanks
i would like to create an id generator based on their department selected from the dropdownlist. lets say my ddl has 3 departments (A,B,C) and when generating an id it will be A20181001 and then A20181002 upon submission but when i pick B from the ddl after sending A20181001 to the database, it will be B20181001.
so far i have created the code for the increment for the id without the departments. here is the code i did so far. (I used the date for today so the 20181001 is just an example):
void getMRF_No()
{
string year = DateTime.Now.Date.ToString("yyyyMMdd");
int mrf = 0;
int i;
string a;
//string x = Request.QueryString["BUnit"];
string mrfNo = "";
database db = new database();
string conn = dbe.BU();
SqlConnection connUser = new SqlConnection(conn);
SqlCommand cmd = connUser.CreateCommand();
SqlDataReader sdr = null;
string query = "SELECT TOP 1 MRF_NO FROM incMRF ORDER BY MRF_NO DESC";
connUser.Open();
cmd.CommandText = query;
sdr = cmd.ExecuteReader();
while (sdr.Read())
{
mrfNo = sdr.GetInt32(0).ToString();
}
if (mrfNo == "")
{
mrfNo = Convert.ToString(year) + "" + 00;
}
mrf += 0;
i = Convert.ToInt32(mrfNo) + 1;
a = i.ToString();
txtMRFNo.Text = a;
connUser.Close();
}
any help to improve this code will be helpful. thank you :)
EDIT:
here is the dropdown list code:
void SelectBU()
{
string database = dbe.BU ();
using (SqlConnection con = new SqlConnection(database))
{
con.Open();
string query = "select BUnit from BusinessUnit";
using (SqlDataAdapter sda = new SqlDataAdapter(query, con))
{
DataSet ds = new DataSet();
sda.Fill(ds, "BUnit");
ddlBu.DataSource = ds;
ddlBu.DataTextField = "BUnit";
ddlBu.DataValueField = "BUnit";
ddlBu.DataBind();
selectOption(ddlBu, "Select Dept");
}
con.Close();
}
}
EDIT2: I will state what im searching for here incase some doesnt know or understand. What i want is upon selecting a department from a dropdownlist, for example i picked A. the textbox show show A2018102201. if i select B it should show B2018102201 and if its C then c2018102201. and it will change its number once i submit it to a database and a new form loads. So if A2018102201 is already in the database, then the text shown in the text box will be A2018102202. BUT if i select B then the textbox will show B2018102201 since it does not exist in the database yet.
First you should get max ID, then increase the numeric part of your Id, and If this is a multi-user application, you have to lock your table, because it might create many ID duplication, Therefore I'm not recommend to create ID like this on c#, it is better to create a Sequence on SQL server. but I wrote this sample for you, just call it with proper value.
static string getMRF_No(string prefixCharFromDropDownList)
{
string year = DateTime.Now.Date.ToString("yyyyMMdd");
string mrfNo = "";
SqlConnection connUser = new SqlConnection("Server=130.185.76.162;Database=StackOverflow;UID=sa;PWD=$1#mssqlICW;connect timeout=10000");
SqlCommand cmd = new SqlCommand(
$"SELECT MAX(MRF_NO) as MaxID FROM incMRF where MRF_NO like '{prefixCharFromDropDownList}%'"
,connUser
);
connUser.Open();
SqlDataReader sdr = cmd.ExecuteReader();
while (sdr.Read())
{
mrfNo = sdr["MaxID"].ToString();
}
if (mrfNo == "")
{
mrfNo = prefixCharFromDropDownList + year + "000";
}
else
{
mrfNo = prefixCharFromDropDownList + (long.Parse(mrfNo.Substring(1)) + 1).ToString().PadLeft(2);
}
sdr.Close();
cmd = new SqlCommand($"INSERT INTO incMRF (MRF_NO) values ('{mrfNo}')",connUser);
cmd.ExecuteNonQuery();
connUser.Close();
//txtMRFNo.Text = prefixCharFromDropDownList + i.ToString();
return mrfNo;
}
I call this method on a console application as test.
static void Main(string[] args)
{
// send dropdown (selected char) as prefix to method
var newAId = getMRF_No("A");
var newAnotherAId = getMRF_No("A");
var newBId = getMRF_No("B");
var newAnotherAId2 = getMRF_No("A");
Console.ReadKey();
}
I have a string array which consists of identifiers. I want to get some values from SQL using these identifiers . Is there a way of adding them with a string value to SqlCommand parameters?
I want to create a query like:
select CaseList from MasterReportData where Id = 1 OR Id = 2 OR Id = 3
This is my C# code:
public static List<string> GetCaseList(string[] masterIdList)
{
try
{
string query = " select CaseList from MasterReportData where #masterId";
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.AddWithValue("masterId", ***);
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
list.Add(reader[0].ToString());
}
}
conn.Close();
}
catch (Exception e)
{
var err= 0;
}
return list;
}
There are many different ways you can go about doing this but I prefer to create a temp table of possible values. That way you can do something like
select CaseList from MasterReportData where Id IN(select Id from tempTable)
The best approach (with sql optimization) would be:
Create your Type:
CREATE TYPE dbo.IntTTV AS TABLE
( Id int )
Your Ids:
var ids = new List<int>
{
1,
2,
3,
}
Create a schema:
var tableSchema = new List<SqlMetaData>(1)
{
new SqlMetaData("Id", SqlDbType.Int) // I think it's Int
}.ToArray();
Create the table in C#
var table = ids
.Select(i =>
{
var row = new SqlDataRecord(tableSchema);
row.SetInt32(0, i);
return row;
})
.ToList();
Create the SQL Parameter
var parameter = new SqlParameter();
parameter.SqlDbType = SqlDbType.Structured;
parameter.ParameterName = "#Ids";
parameter.Value = table;
parameter.TypeName = "dbo.IntTTV";
var parameters = new SqlParameter[1]
{
parameter
};
Slightly change your query (this is just an example:)
string query = "select mrd.CaseList from MasterReportData mrd"
+ " inner join #ids i on mrd.Id = i.id";
public static List<string> GetCaseList(string[] masterIdList)
{
List<string> list = new List<string>();
try
{
string query = "select CaseList from MasterReportData where ";
using (SqlConnection conn = new SqlConnection(connString))
{
int i = 0;
SqlCommand cmd = new SqlCommand(query, conn);
for(i = 0; i < masterIdList.Length; i++)
{
var parm = "#ID" + i;
cmd.Parameters.Add(new SqlParameter(parm, masterIdList[i]));
query += (i > 0 ? " OR " : "") + " Id = " + parm;
}
cmd.CommandText = query;
//cmd.Parameters.AddWithValue("masterId", ***);
conn.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
list.Add(reader[0].ToString());
}
}
}
}
catch (Exception e)
{
e.ToString();
}
return list;
}
I want to build a custom interface (a separate aspx page) to manage the data that is put into the webforms for marketeers (WFFM) database, and that for just one form. It must be possible to edit the data and select records with particular sortings and pagings. The database is configured to be SQLite.
Is this possible and recommended, or is it just plain xml that is saved into the WFFM database? And how should I go about it?
This is completely doable, though the select query to get data out of WFFM is a bit funky because everything is stored loose in one huge table called "field" with only a trail of GUIDs to tie the stored values back to what form they came from and what field.
Provided below is part of an Export to Excel utility I wrote for WFFM data. It builds a DataTable object from submitted form results. You could adapt it to some other structure without much work though.
public string connectionStringWFFM = "user id=sitecore_admin;password=xxx;Data Source=SitecoreDBServer.com;Database=Sitecore_WebForms";
protected DataTable BuildDataTable(Item formItem)
{
List<FormResult> formResults = FormResults(formItem.ID.Guid);
List<Field> distinctFields = DistinctFields(formItem.ID.Guid);
var dt = new DataTable();
dt.Columns.Add("Submission_DateTime", typeof (string));
foreach (Field field in distinctFields)
{
var dataColumn = new DataColumn("_" + field.id.ToString("N"), typeof (string));
dataColumn.Caption = field.name.Replace(" ", "_");
dt.Columns.Add(dataColumn);
}
foreach (FormResult formResult in formResults)
{
var connection = new SqlConnection();
connection.ConnectionString = connectionStringWFFM;
var command = new SqlCommand();
command.Connection = connection;
command.CommandText = "select fieldid, value from field where formid=#formid order by fieldid";
command.Parameters.Add("#formid", SqlDbType.UniqueIdentifier).Value = formResult.id;
connection.Open();
SqlDataReader reader = command.ExecuteReader();
DataRow dataRow = dt.NewRow();
dataRow["Submission_DateTime"] = formResult.timestamp.ToString("MM/dd/yyyy HH:mm:ss");
while (reader.Read())
{
dataRow["_" + reader.GetGuid(0).ToString("N")] = reader.GetValue(1).ToString().Replace("<item>", "").Replace("</item>", "");
}
dt.Rows.Add(dataRow);
reader.Close();
connection.Close();
}
return dt;
}
public List<Field> DistinctFields(Guid formitemid)
{
var connection = new SqlConnection();
connection.ConnectionString = connectionStringWFFM;
var command = new SqlCommand();
command.Connection = connection;
command.CommandText = "select distinct fieldid from field where formid in (select id from form where formitemid=#formitemid) order by fieldid";
command.Parameters.Add("#formitemid", SqlDbType.UniqueIdentifier).Value = formitemid;
connection.Open();
SqlDataReader reader = command.ExecuteReader();
var results = new List<Field>();
int count = 0;
while (reader.Read())
{
var field = new Field();
field.id = reader.GetGuid(0);
Database database = Factory.GetDatabase("master");
Item i = database.GetItem(new ID(field.id));
if (i != null && i.DisplayName != null)
{
field.name = i.DisplayName;
}
else
{
field.name = "Field" + count;
}
results.Add(field);
count += 1;
}
reader.Close();
connection.Close();
return results;
}
public List<FormResult> FormResults(Guid formitemid)
{
var connection = new SqlConnection();
connection.ConnectionString = connectionStringWFFM;
var command = new SqlCommand();
command.Connection = connection;
command.CommandText = "select id, timestamp from form where formitemid=#formitemid";
command.Parameters.Add("#formitemid", SqlDbType.UniqueIdentifier).Value = formitemid;
connection.Open();
SqlDataReader reader = command.ExecuteReader();
var results = new List<FormResult>();
while (reader.Read())
{
var result = new FormResult();
result.id = reader.GetGuid(0);
result.timestamp = reader.GetDateTime(1);
results.Add(result);
}
reader.Close();
connection.Close();
return results;
}
public class FormResult
{
public Guid id { get; set; }
public DateTime timestamp { get; set; }
}
public class Field
{
public Guid id { get; set; }
public string name { get; set; }
}
Here I have two dropdownlists. First one to display the list of countries and the second to list the states value for selected country from first. The list of values are populated from
properly but in the dropdownlist, the values are not populated.
jQuery:
$(document).ready(function () {
$("#Country").change(function () {
var Id = $('#Country option:selected').attr('value');
$("#Region").empty();
$.getJSON("/ControllerName/GetRegionList",{ ID: Id },
function (data) {
jQuery.each(data, function (key) {
$("#Region").append($("<option></option>").val(ID).html(Name));
});
});
});
});
View :
#Html.DropDownList("Country", new SelectList(Model.CountryList, "Value", "Text", Model.CountryList.SelectedValue))
#Html.DropDownList("Region", new SelectList(Model.RegionList, "Value", "Text", Model.RegionList.SelectedValue))
Controller:
public List<Region> GetRegionList(int ID)
{
int countryid = ID;
AddressModel objmodel = new AddressModel();
List<Region> objRegionList = new List<Region>();
objRegionList.Add(new Region { ID = "0", Name = " " });
if (countryid != 0)
{
countryid = Convert.ToInt32(ID);
SqlCommand cmd = new SqlCommand("USP_ProcedureName", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Id", countryid);
cmd.Parameters.AddWithValue("#Mode", "Region");
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
if (dr["RegionId"].ToString() != "")
{
objRegionList.Add(new Region { ID = dr["RegionId"].ToString(), Name = dr["Name"].ToString() });
}
}
dr.Close();
con.Close();
}
return objRegionList;
}
What is the mistake in my code.? Any Suggestions.
EDIT : Added the snapshot
In ASP.NET MVC controller actions must return ActionResults. In your case you could return JSON:
public ActionResult GetRegionList(int id)
{
var objRegionList = new List<Region>();
objRegionList.Add(new Region { ID = "0", Name = " " });
if (countryid != 0)
{
int countryid = ID;
using (var conn = new SqlConnection("YOUR CONNECTION STRING COMES HERE"))
using (var cmd = conn.CreateCommand())
{
con.Open();
cmd.CommandText = "USP_ProcedureName";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Id", countryid);
cmd.Parameters.AddWithValue("#Mode", "Region");
using (var dr = cmd.ExecuteReader())
{
while (dr.Read())
{
if (dr["RegionId"].ToString() != "")
{
objRegionList.Add(new Region
{
ID = dr["RegionId"].ToString(),
Name = dr["Name"].ToString()
});
}
}
}
}
}
return Json(objRegionList, JsonRequestBehavior.AllowGet);
}
Notice that I have also cleared your code from unused variables and unnecessary Convert.ToInt32 calls and most importantly wrapped IDisaposable resources such as SQL connections, commands and data readers in using statements to avoid leaking resources.
Then include the url of the controller action as a data-* attribute on the first dropdown to avoid ugly hardcoding it in your javascript and breaking when you deploy your application in IIS in a virtual directory:
#Html.DropDownList(
"Country",
new SelectList(Model.CountryList, "Value", "Text", Model.CountryList.SelectedValue),
new { data_url = Url.Action("GetRegionList", "ControllerName") }
)
finally adapt (simplify) your javascript:
$('#Country').change(function () {
var regionDdl = $('#Region');
regionDdl.empty();
var id = $(this).val();
var url = $(this).data(url);
$.getJSON(url, { id: id }, function (data) {
$.each(data, function (index, region) {
regionDdl.append(
$('<option/>', {
value: region.ID,
html: region.Name
})
);
});
});
});