为什么 Ignite UI Hierarchical Grid 在我添加布局时会抛出 NullReferenceException?

Why does Ignite UI Hierarchical Grid throw a NullReferenceException when I add a layout?

每当我在不添加布局的情况下加载网格时,父网格加载得很好。但是,每当我添加布局时,将数据绑定到父级时都会抛出 NullReferenceException。

public ActionResult Index()
    {
        GridModel grid = GridLoadOnDemandModel();
        grid.ID = "Services";
        grid.LoadOnDemand = true;
        grid.DataSourceUrl = this.Url.Action("BindParent");
        grid.ColumnLayouts[0].DataSourceUrl = this.Url.Action("BindChild");
        return View(grid);
    }

    private GridModel GridLoadOnDemandModel()
    {
        GridModel grid = new GridModel();
        grid.AutoGenerateLayouts = false;
        grid.AutoGenerateColumns = true;
        grid.PrimaryKey = "ID";
        grid.Width = "100%";
        grid.Columns.Add(new GridColumn() { HeaderText = "Service ID", Key = "ID", DataType = "number" });
        grid.Columns.Add(new GridColumn() { HeaderText = "Client ID", Key = "ClientID", DataType = "number" });
        grid.Columns.Add(new GridColumn() { HeaderText = "Package ID", Key = "PackageID", DataType = "number" });

        GridColumnLayoutModel layout = new GridColumnLayoutModel();
        layout.Key = "ServiceHistory";
        layout.ForeignKey = "ID";
        layout.PrimaryKey = "ID";
        layout.AutoGenerateColumns = false;
        layout.Columns.Add(new GridColumn() { HeaderText = "Log ID", Key = "LogID", DataType = "number", Hidden = true });
        layout.Columns.Add(new GridColumn() { HeaderText = "Service ID", Key = "ID", DataType = "number", Hidden = true});
        layout.Columns.Add(new GridColumn() { HeaderText = "Client ID", Key = "ClientID", DataType = "number" });
        layout.Columns.Add(new GridColumn() { HeaderText = "Package ID", Key = "PackageID", DataType = "number" });

        layout.Width = "100%";
        grid.ColumnLayouts.Add(layout);

        return grid;
    }

错误是在 GetData 方法的 BindParent 方法中抛出的。

    public JsonResult BindParent()
    {
        GridModel model = GridLoadOnDemandModel();
        model.DataSource = GetService().AsQueryable();
        return model.GetData();
    }

    public JsonResult BindChild(string path, string layout)
    {
        GridModel model = GridLoadOnDemandModel();
        model.DataSource = GetServiceLogs().AsQueryable();
        return model.GetData(path, layout);
    }

    private IEnumerable<Service> GetService()
    {
        var services = new List<Service>();

        for (int i = 0; i < 10; i++)
        {
            var service = new Service
            {
                ID = i,
                ClientID = 1,
                PackageID = 1
            };

            services.Add(service);
        }

        return services;
    }

    private IEnumerable<ServiceLog> GetServiceLogs()
    {
        var serviceLogs = new List<ServiceLog>();

        for (int i = 0; i < 10; i++)
        {
            var serviceLog = new ServiceLog
            {
                LogID = i,
                ID = 1,
                ClientID = i,
                PackageID = i
            };

            serviceLogs.Add(serviceLog);
        }

        return serviceLogs;
    } 
public class Service
{
    public int ID { get; set; }
    public int ClientID { get; set; }
    public int PackageID { get; set; }
}

public class ServiceLog
{
    public int LogID { get; set; }
    public int ID { get; set; }
    public int ClientID { get; set; }
    public int PackageID { get; set; }
}

public class Service
{
    public int ID { get; set; }
    public int ClientID { get; set; }
    public int PackageID { get; set; }
}

public class ServiceLog
{
    public int LogID { get; set; }
    public int ID { get; set; }
    public int ClientID { get; set; }
    public int PackageID { get; set; }
}

这是堆栈跟踪:

at Infragistics.Web.Mvc.GridModel.RenderHierarchicalQueryableRecursive(IQueryable 可查询,WrappedGridResponse 响应,GridModel baseLayout) 在 Infragistics.Web.Mvc.GridModel.RenderHierarchicalQueryable(IQueryable 可查询) 在 Infragistics.Web.Mvc.GridModel.DataBind() 在 Infragistics.Web.Mvc.GridModel.GetData() 在 IgniteUIHTMLEditorExample.Controllers.ServiceHistoryController.BindParent() 中 c:\Users\kyle.wingate\Documents\Visual Studio 2013\Projects\IgniteUIHTMLEditorExample\IgniteUIHTMLEditorExample\Controllers\ServiceHistoryController.cs:第 53 行 在 lambda_method(闭包,ControllerBase,对象[]) 在 System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase 控制器,Object[] 参数) 在 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext,IDictionary2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 个参数) 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.ActionInvocation.InvokeSynchronousActionMethod() 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.b__39(IAsyncResult asyncResult,ActionInvocation innerInvokeState) 在 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult2.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase1.End() 在 System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult,对象标记) 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult 异步结果) 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.b__3d() 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.b__3f()

Service class/model 中,您应该有一个以 GridColumnLayoutModel.Key 值命名的 属性。 Service class 应该是这样的:

public class Service
{
    public int ID { get; set; }
    public int ClientID { get; set; }
    public int PackageID { get; set; }
    public IEnumerable<ServiceLog>  ServiceHistory { get; set; }
}

此更改将解决 NullReferenceException,但您还需要进行一些更改,以便您的示例按预期运行。

您还应该正确配置 GridColumnLayoutModel.PrimaryKeyGridColumnLayoutModel.ForeignKey,因为 GridModel.GetData 依赖于它们来 extract/filter 正确的子记录。 我想在你的情况下 ServiceHistory 布局的配置应该是这样的:

//… code omitted
layout.ForeignKey = "ID";
layout.PrimaryKey = "LogID";
// … code omitted

通过此更改,GridModel.GetData 方法将通过 ServiceLog class.

中的 ID 属性 过滤数据

您可能需要更改 GetServiceLogs 方法以生成不同的 ID,因为现在它将 return 数据仅用于 ServiceID = 1