为什么 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, IDictionary
2 个参数)
在 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.WrappedAsyncResultBase
1.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.PrimaryKey
和 GridColumnLayoutModel.ForeignKey
,因为 GridModel.GetData
依赖于它们来 extract/filter 正确的子记录。
我想在你的情况下 ServiceHistory
布局的配置应该是这样的:
//… code omitted
layout.ForeignKey = "ID";
layout.PrimaryKey = "LogID";
// … code omitted
通过此更改,GridModel.GetData
方法将通过 ServiceLog
class.
中的 ID
属性 过滤数据
您可能需要更改 GetServiceLogs
方法以生成不同的 ID
,因为现在它将 return 数据仅用于 Service
和 ID = 1
每当我在不添加布局的情况下加载网格时,父网格加载得很好。但是,每当我添加布局时,将数据绑定到父级时都会抛出 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, IDictionary
2 个参数)
在 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.WrappedAsyncResultBase
1.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.PrimaryKey
和 GridColumnLayoutModel.ForeignKey
,因为 GridModel.GetData
依赖于它们来 extract/filter 正确的子记录。
我想在你的情况下 ServiceHistory
布局的配置应该是这样的:
//… code omitted
layout.ForeignKey = "ID";
layout.PrimaryKey = "LogID";
// … code omitted
通过此更改,GridModel.GetData
方法将通过 ServiceLog
class.
ID
属性 过滤数据
您可能需要更改 GetServiceLogs
方法以生成不同的 ID
,因为现在它将 return 数据仅用于 Service
和 ID = 1