级联下拉列表与mvc和jQuery无法正常工作

时间:2010-12-06 21:07:16

标签: asp.net linq asp.net-mvc-2 drop-down-menu

我正在尝试使用级联下拉列表的解决方案(在一个下拉列表中选择确定第二个中的选项)在此处找到:

http://www.pieterg.com/post/2010/04/12/Cascading-DropDownList-with-ASPNET-MVC-and-JQuery.aspx

<script src="../../Scripts/jquery-1.4.1.js" type="text/javascript"></script>
    <script src="../../Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(function () {
            //Hook onto the MakeID list's onchange event
            $("#CustomerId").change(function () {
                //build the request url
                var url = "Timesheet/Tasks";
                //fire off the request, passing it the id which is the MakeID's selected item value
                $.getJSON(url, { id: $("#CustomerId").val() }, function (data) {
                    //Clear the Model list
                    $("#TaskId").empty();
                    //Foreach Model in the list, add a model option from the data returned
                    $.each(data, function (index, optionData) {
                        $("#TaskId").append("<option value='" + optionData.ID + "'>" + optionData.Description + "</option>");
                    });
                });
            }).change();
        });
    </script>
    <h2>
        Index</h2>
    <fieldset>
        <legend>Fields</legend>
        <div>
            <label for="Customers">
                Kund:</label>
            <%:Html.DropDownListFor(m => m.Customers, new SelectList(Model.Customers,"Id", "Name"), new {@id="CustomerId"}) %>
            <%--<%:Html.DropDownListFor(m => m.CustomerId, new SelectList(Model.Customers,"Id", "Name")) %>--%>
            &nbsp;&nbsp;
            <label for="Tasks">
                Aktiviteter:</label>
            <%:Html.DropDownListFor(m => m.Tasks, new SelectList(Model.Tasks,"Id", "Name"), new {@id="TaskId"}) %>
            <%--<%:Html.DropDownListFor(m => m.TaskId, new SelectList(Model.Tasks,"Id", "Name")) %>--%>
<%--            <select id="TaskId" name="TaskId">
            </select>--%>
        </div>
    </fieldset>

这是获取任务的Action方法:

    public JsonResult Tasks(string id)
    {
        var result = new JsonResult();
        //var tasks = from t in _model.Tasks
        //            where t.CustomerId.ToString() == id
        //            select t;
        List<Task> tasklist = new List<Task>();
        foreach (var task in _model.Tasks)
        {
            if(task.CustomerId.ToString() == id)
                tasklist.Add(task);
        }

        //result.Data = tasks.ToList();
        result.Data = tasklist;

        result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
        return result;
    }

我有两个问题:

  1. 第二个下拉列表根本不会改变,具体取决于第一个下拉列表。我尝试了各种变体(正如您从注释掉的下拉列表中看到的那样)。我在Firebug中收到错误消息,但我无法解释它(见下文)。
  2. Action方法中的linq表达式由于某种原因似乎不起作用,这真的很奇怪,因为我之前一直在使用这种表达式而没有任何问题。也许我累了,错过了什么,但我看不到它。表达式返回所有任务,而不仅仅是与当前客户具有相同ID的任务。 foreach工作得很好,这让它更奇怪......这与第一个问题完全无关,因为foreach工作正常,只选择了三个任务(这是正确的)。但仍然是第二个下拉列表显示所有任务......
  3. 任何帮助表示赞赏!

    Firebug错误日志:

    <html>
        <head>
            <title>A circular reference was detected while serializing an object of type 'Tidrapportering.Models.Task'.</title>
            <style>
             body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;} 
             p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px}
             b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}
             H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }
             H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }
             pre {font-family:"Lucida Console";font-size: .9em}
             .marker {font-weight: bold; color: black;text-decoration: none;}
             .version {color: gray;}
             .error {margin-bottom: 10px;}
             .expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }
            </style>
        </head>
    
        <body bgcolor="white">
    
                <span><H1>Server Error in '/' Application.<hr width=100% size=1 color=silver></H1>
    
                <h2> <i>A circular reference was detected while serializing an object of type 'Tidrapportering.Models.Task'.</i> </h2></span>
    
                <font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">
    
                <b> Description: </b>An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
    
                <br><br>
    
                <b> Exception Details: </b>System.InvalidOperationException: A circular reference was detected while serializing an object of type 'Tidrapportering.Models.Task'.<br><br>
    
                <b>Source Error:</b> <br><br>
    
                <table width=100% bgcolor="#ffffcc">
                   <tr>
                      <td>
                          <code>
    
    An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.</code>
    
                      </td>
                   </tr>
                </table>
    
                <br>
    
                <b>Stack Trace:</b> <br><br>
    
                <table width=100% bgcolor="#ffffcc">
                   <tr>
                      <td>
                          <code><pre>
    
    [InvalidOperationException: A circular reference was detected while serializing an object of type &#39;Tidrapportering.Models.Task&#39;.]
       System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1478
       System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
       System.Web.Script.Serialization.JavaScriptSerializer.SerializeEnumerable(IEnumerable enumerable, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +126
       System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1311
       System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
       System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +502
       System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1355
       System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
       System.Web.Script.Serialization.JavaScriptSerializer.SerializeCustomObject(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +502
       System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1355
       System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
       System.Web.Script.Serialization.JavaScriptSerializer.SerializeEnumerable(IEnumerable enumerable, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +126
       System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +1311
       System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat) +194
       System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, StringBuilder output, SerializationFormat serializationFormat) +26
       System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, SerializationFormat serializationFormat) +74
       System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj) +6
       System.Web.Mvc.JsonResult.ExecuteResult(ControllerContext context) +458
       System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +39
       System.Web.Mvc.&lt;&gt;c__DisplayClass14.&lt;InvokeActionResultWithFilters&gt;b__11() +60
       System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +391
       System.Web.Mvc.&lt;&gt;c__DisplayClass16.&lt;InvokeActionResultWithFilters&gt;b__13() +61
       System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +285
       System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +830
       System.Web.Mvc.Controller.ExecuteCore() +136
       System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +111
       System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +39
       System.Web.Mvc.&lt;&gt;c__DisplayClass8.&lt;BeginProcessRequest&gt;b__4() +65
       System.Web.Mvc.Async.&lt;&gt;c__DisplayClass1.&lt;MakeVoidDelegate&gt;b__0() +44
       System.Web.Mvc.Async.&lt;&gt;c__DisplayClass8`1.&lt;BeginSynchronous&gt;b__7(IAsyncResult _) +42
    
       System.Web.Mvc.Async.WrappedAsyncResult`1.End() +141
       System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +54
       System.Web.Mvc.Async.AsyncResultWrapper.End(IAsyncResult asyncResult, Object tag) +40
       System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +52
       System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +38
       System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8841105
    
       System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously) +184
    </pre></code>
    
                      </td>
                   </tr>
                </table>
    
                <br>
    
                <hr width=100% size=1 color=silver>
    
                <b>Version Information:</b>&nbsp;Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1
    
                </font>
    
        </body>
    </html>
    

    更新:

    我现在将其更新为以下内容:

    获取与所选客户关联的任务的操作方法:

        public JsonResult Tasks(string id)
        {
            var result = new JsonResult();
            var tasks =
                _model.Tasks.Where(task => task.CustomerId.ToString() == id).Select(
                    task => new {ID = task.Id, Name = task.Name});
            result.Data = tasks;
    
            result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
            return result;
        }
    

    在视图中:

        <div>
            <label for="Customers">
                Kund:</label>
            <%:Html.DropDownListFor(m => m.Customers, new SelectList(Model.Customers,"Id", "Name"), new {@id="CustomerId"}) %>
            &nbsp;&nbsp;
            <label for="Tasks">
                Aktiviteter:</label>
            <%:Html.DropDownListFor(m => m.Tasks, new SelectList(Model.Tasks,"Id", "Name"), new {@id="TaskId"}) %>
        </div>
    

    现在我在第二个下拉列表中以某种方式过滤和选择结果,选择不同客户时选项的数量是正确的。但是,任务下拉列表中的值对于所有这些值都是“未定义的”...

    更新2:

    我发现了问题:

    在jQuery中,我忘了修复任务对象的属性名称。这是工作版本:

        $(document).ready(function () {
            //Hook onto the MakeID list's onchange event
            $("#CustomerId").change(function () {
                //build the request url
                var url = "Timesheet/Tasks";
                //fire off the request, passing it the id which is the MakeID's selected item value
                $.getJSON(url, { id: $("#CustomerId").val() }, function (data) {
                    //Clear the Model list
                    $("#TaskId").empty();
                    //Foreach Model in the list, add a model option from the data returned
                    $.each(data, function (index, optionData) {
                        $("#TaskId").append("<option value='" + optionData.Id + "'>" + optionData.Name + "</option>");
                    });
                });
            }).change();
        });
    

    但我想知道如何获取下拉列表的默认值。否则,当您第一次访问该页面时,客户下拉列表将具有值,但任务列表不会...

1 个答案:

答案 0 :(得分:2)

JsonResult使用JavascriptSerializer生成JSON数据,JavascriptSerializer不支持循环引用。 也许以下帖子可以帮助您解决问题:Json and Circular Reference Exception

<强>更新

不要使用循环引用,只需返回另一个对象的List,只需要两个字段:ID和Description。它看起来像这样:

var tasklist = _model.Tasks.Where(x => x.CustomerId.ToString() == id)
                           .Select(x => new { ID = task.ID, Description = task.Description });