-4

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" })

}
Bert
  • 35
  • 1
  • 1
  • 9
  • 1
    I don't see any JavaScript `in` operator in this code; are you sure the error is occurring in what you posted? – Jacob Oct 16 '19 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 Oct 16 '19 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 Oct 16 '19 at 18:39
  • Jacob - I was told the error is in reference to the $.each somehow... – Bert Oct 16 '19 at 18:41
  • 1
    The SQL Injection is, as an aside, a very real problem here as well. Consider if `selectedOption` is equal to `1'; ; '`. – Travis J Oct 16 '19 at 18:42
  • Patrick - I understand that "theory", my question is where in that code is the wrong argument? Or which function needs changed so that those are the correct arguments.... But thanks. – Bert Oct 16 '19 at 18:47
  • 2
    @Bert `string.Format()` is not parameterizing your queries. You need to use `SqlParameter`, there is a great SO question [here](https://stackoverflow.com/questions/7505808/why-do-we-always-prefer-using-parameters-in-sql-statements) – maccettura Oct 16 '19 at 20:25
  • @All - SQL injection is not a concern here to have access to this site every user must FIRST have both SQL and Domain Admin privilages, as such SQL parameters would be a MISTAKE not an improvement and most definitely does NOT fix the issue or have anything to do with the topic. Thanks... – Bert Oct 17 '19 at 11:56

2 Answers2

4

The 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).

Travis J
  • 81,153
  • 41
  • 202
  • 273
  • SyntaxError: JSON.parse: unexpected character at line 4 column 1 of the JSON data – Bert Oct 16 '19 at 18:57
  • 1
    @Bert - Perhaps try logging out your `attValues` response. It is possible that there was a null value entered, or an empty value. `[1,2,,3]` is invalid JSON and results in a very similar error. – Travis J Oct 16 '19 at 21:12
  • not a bad idea, how would you suggest I do so? Although it seems odd that regardless which of the 3 options I pick I get the same error(s)... Sometimes I think the java code isn't even successfully calling the actionresult with the $.post - Thanks again for your help. – Bert Oct 17 '19 at 00:25
  • Added simple alert(attValues); before the var result = JSON.parse(attValues)... – Bert Oct 17 '19 at 17:25
  • 1
    @Bert - Glad that helped get you to where you needed to be. In the future, using `console.log(attValues)` will provide more information than the alert will (it will show up in your browser's console, generally found by pressing F12 on the keyboard). – Travis J Oct 17 '19 at 18:29
  • thanks I'll try that next time. Appreciate all the help. I'm still very new to this and the company won't pay for any training... Just expect me to convert a bunch of customizations done via window forms into web browser friendly MVC html forms while working 60+ hrs a week all with no training since COBOL on an AIX UNIX box days... Thanks Again :) – Bert Oct 17 '19 at 23:40
1

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));
                });
            });
        });
Bert
  • 35
  • 1
  • 1
  • 9