Have a view with 2 drop-downs the 2nd one disabled by default. When selection is made in first drop-down, it is supposed to both call an action in my controller to retrieve list of values for 2nd drop-down, then use simple scripting to clear the 2nd drop-down, enable the 2nd drop-down and fill it with the results.
When I make a selection from the first drop-down, the 2nd drop-down is enabled but no values appear. Using Ctrl-shift-i I see the error TypeError: right-hand side of 'in' should be an object, got string.
But I'm using a List of values not a string variable...
I have verified in SQL manager that the SQL query works for all 3 different options available in first drop-down.
Added alert(attValues); into $.post. It is resulting in an entire HTML doc being shown in the alert that goes about really long way of saying 404 page not found.
The important line seeming to be:
<form method="post" action="../../../Error_404.aspx?selectedOption=SKU_SelectableAttribute_2" id="error404">
Controller
[HttpPost]
public ActionResult GetAttributeValues(string selectedOption)
{
JsonResult result = new JsonResult();
if (selectedOption != null)
{
string sql = "SELECT Title FROM BL_Attribute (NOLOCK) WHERE BL_Attribute.DeleteFlag = '0' AND AttributeGroupName = '" + selectedOption + "'";
using (SqlCommand selectAttValues = new SqlCommand(sql, P21SqlConnection))
{
using (SqlDataReader reader = selectAttValues.ExecuteReader())
{
List<string> attValues = new List<string>();
while (reader.Read())
{
attValues.Add(reader["Title"].ToString());
}
return Json(attValues, JsonRequestBehavior.AllowGet);
}
}
}
return Json(new { Success = "false" });
}
View
@using System.Data
@model Product
@{
ViewBag.Title = "Attributes";
Layout = "~/Views/Shared/_VisualRuleLayout.cshtml";
var listAttGroups = new List<SelectListItem>
{
new SelectListItem { Text = "SKU_Color", Value = "SKU_Color"},
new SelectListItem { Text = "SKU Select Att 1", Value = "SKU_SelectableAttribute_1"},
new SelectListItem { Text = "SKU Select Att 2", Value = "SKU_SelectableAttribute_2"}
};
}
@section scripts{
<script>
$(function () {
$("#ApplyGroup").change(function () {
var option = $(this).val();
$("#AttributeValue").empty();
$("#AttributeValue").prop('disabled', false);
var url = "KCDA_PrdGrp_Attributes/GetAttributeValues?selectedOption=" + option;
$.post(url, function (attValues) {
$.each(attValues, function (i, attValue) {
$("#AttributeValue").append($('<option></option>').val(attValue).html(attValue));
});
});
});
});
</script>
}
<center><h3>Edit Attributes</h3></center>
@using (Html.BeginForm("Return", "KCDA_PrdGrp_Attributes", FormMethod.Post, new { name = "Return" }))
{
@Html.DropDownList("ApplyGroup", listAttGroups, new { @id = "ApplyGroup", @class = "form-control" })
@Html.DropDownList("AttributeValue", new List<SelectListItem>(), new { @id = "AttributeValue", @class = "form-control", disabled = "disabled" })
}
Have a view with 2 drop-downs the 2nd one disabled by default. When selection is made in first drop-down, it is supposed to both call an action in my controller to retrieve list of values for 2nd drop-down, then use simple scripting to clear the 2nd drop-down, enable the 2nd drop-down and fill it with the results.
When I make a selection from the first drop-down, the 2nd drop-down is enabled but no values appear. Using Ctrl-shift-i I see the error TypeError: right-hand side of 'in' should be an object, got string.
But I'm using a List of values not a string variable...
I have verified in SQL manager that the SQL query works for all 3 different options available in first drop-down.
Added alert(attValues); into $.post. It is resulting in an entire HTML doc being shown in the alert that goes about really long way of saying 404 page not found.
The important line seeming to be:
<form method="post" action="../../../Error_404.aspx?selectedOption=SKU_SelectableAttribute_2" id="error404">
Controller
[HttpPost]
public ActionResult GetAttributeValues(string selectedOption)
{
JsonResult result = new JsonResult();
if (selectedOption != null)
{
string sql = "SELECT Title FROM BL_Attribute (NOLOCK) WHERE BL_Attribute.DeleteFlag = '0' AND AttributeGroupName = '" + selectedOption + "'";
using (SqlCommand selectAttValues = new SqlCommand(sql, P21SqlConnection))
{
using (SqlDataReader reader = selectAttValues.ExecuteReader())
{
List<string> attValues = new List<string>();
while (reader.Read())
{
attValues.Add(reader["Title"].ToString());
}
return Json(attValues, JsonRequestBehavior.AllowGet);
}
}
}
return Json(new { Success = "false" });
}
View
@using System.Data
@model Product
@{
ViewBag.Title = "Attributes";
Layout = "~/Views/Shared/_VisualRuleLayout.cshtml";
var listAttGroups = new List<SelectListItem>
{
new SelectListItem { Text = "SKU_Color", Value = "SKU_Color"},
new SelectListItem { Text = "SKU Select Att 1", Value = "SKU_SelectableAttribute_1"},
new SelectListItem { Text = "SKU Select Att 2", Value = "SKU_SelectableAttribute_2"}
};
}
@section scripts{
<script>
$(function () {
$("#ApplyGroup").change(function () {
var option = $(this).val();
$("#AttributeValue").empty();
$("#AttributeValue").prop('disabled', false);
var url = "KCDA_PrdGrp_Attributes/GetAttributeValues?selectedOption=" + option;
$.post(url, function (attValues) {
$.each(attValues, function (i, attValue) {
$("#AttributeValue").append($('<option></option>').val(attValue).html(attValue));
});
});
});
});
</script>
}
<center><h3>Edit Attributes</h3></center>
@using (Html.BeginForm("Return", "KCDA_PrdGrp_Attributes", FormMethod.Post, new { name = "Return" }))
{
@Html.DropDownList("ApplyGroup", listAttGroups, new { @id = "ApplyGroup", @class = "form-control" })
@Html.DropDownList("AttributeValue", new List<SelectListItem>(), new { @id = "AttributeValue", @class = "form-control", disabled = "disabled" })
}
Share
Improve this question
edited Oct 17, 2019 at 17:33
Bert
asked Oct 16, 2019 at 18:32
BertBert
451 gold badge1 silver badge9 bronze badges
8
-
1
I don't see any JavaScript
in
operator in this code; are you sure the error is occurring in what you posted? – Jacob Commented Oct 16, 2019 at 18:36 - 5 Do you know what a SQL Injection Attack is? Your code is extremely vulnerable to that type of attack. Use parameterized queries instead of concatenating strings – maccettura Commented Oct 16, 2019 at 18:36
-
If the error is being triggered from some library code, like jQuery, you probably passed the wrong argument to a function. E.g.
$.somejQueryFunction('somestring')
instead of$.somejQueryFunction({})
– Patrick Evans Commented Oct 16, 2019 at 18:39 -
1
The SQL Injection is, as an aside, a very real problem here as well. Consider if
selectedOption
is equal to1'; <insert devastating sql>; '
. – Travis J Commented Oct 16, 2019 at 18:42 -
2
@Bert
string.Format()
is not parameterizing your queries. You need to useSqlParameter
, there is a great SO question here – maccettura Commented Oct 16, 2019 at 20:25
2 Answers
Reset to default 4The error is the result of the returned JSON being a string. JSON is afterall, just a notation. When .each
attempts to iterate an array like variable, it instead finds a string and throws the error.
In order to convert the string into an iterable array, it needs to be parsed. Looking to see if your Success flag was false would help as well.
$.post(url, function (attValues) {
var result = JSON.parse(attValues);
if( result.Success && result.Success == "false" ) return;
$.each(result, function (i, attValue) {
$("#AttributeValue").append($('<option></option>').val(attValue).html(attValue));
});
});
As an aside, the SQL in the controller is problematic as it does not prevent malicious values from being inserted into a live query. It should be addressed by parametizing, encoding, or using a different sql paradigm (such as integrating LINQ or using a ORM).
So issue ended up simple over pathing, ajax.post() defaults to current directory already and I had included it in URL. Removing the "KCDA_PrdGrp_Attributes/" from beginning of URL fixed issue.
Also the JSON.parse() was incorrect. It failed using .parse with error of invalid character line 1 character 1 every time after fixing URL, but it does work perfectly without it.
Thanks again for help - Travis idea of logging (in my case adding simple alert()) to show variable value indeed helped me finish debugging.
$("#ApplyGroup").change(function () {
var option = $(this).val();
$("#AttributeValue").empty();
$("#AttributeValue").prop('disabled', false);
var url = "GetAttributeValues?selectedOption=" + option;
$.post(url, function (attValues) {
$.each(attValues, function (i, attValue) {
$("#AttributeValue").append($('<option></option>').val(attValue).html(attValue));
});
});
});
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744175332a4561726.html
评论列表(0条)