我有一些不会渲染的MVC3网站的剃刀代码。我出于某种原因得到Cannot perform runtime binding on a null reference
运行时错误。以下是我的观点:
@{
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
<table>
@for (var i = 0; i < ViewBag.taskList.Count; i++)
{
<tr>
@for (var j = 0; j < 9; j++)
{
<td>@ViewBag.taskList.get(i).attr.get(j);</td>
}
</tr>
}
</table>
这是我的模特:
public class parentTask
{
int id { get; set; }//task ID
int pId { get; set; }//parent task ID
String name { get; set; }//task name
String dDate { get; set; }//due date
String cDate { get; set; }//completion date
String description { get; set; }//Description of task
String assignedTo { get; set; }//assigned to
String tags { get; set; }//tags
public List<object> attr;//list for rendering attributes
public parentTask(int i, int p, String n, String d, String c, String de, String a, String t)//constructor
{
id = i;
pId = p;
name = n;
dDate = d;
cDate = c;
description = de;
assignedTo = a;
tags = t;
attr= new List<object>();
attr.Add(id);
attr.Add(pId);
attr.Add(name);
attr.Add(dDate);
attr.Add(cDate);
attr.Add(description);
attr.Add(assignedTo);
attr.Add(tags);
}
}
这是我的控制器:
public class TaskController : Controller
{
String[] values = new fileReader().values;
public List<parentTask> taskList = new List<parentTask>();
public ViewResult index(){
String tId=values[0];
String tPId=values[1];
String tName=values[2];
String tD=values[3];
String tC=values[4];
String tDe=values[5];
String tA=values[6];
String tT=values[7];
for(int i=8; i< values.Length; i+=8){
taskList.Add(new parentTask(Convert.ToInt32(values[i]), Convert.ToInt32(values[i + 1]), values[i + 2], values[i + 3], values[i + 4], values[i + 5], values[i + 6], values[i + 7]));
}
ViewBag.taskList = taskList;
return View();
}
#region Status Codes
private static string ErrorCodeToString(MembershipCreateStatus createStatus)
{
// See http://go.microsoft.com/fwlink/?LinkID=177550 for
// a full list of status codes.
switch (createStatus)
{
case MembershipCreateStatus.DuplicateUserName:
return "User name already exists. Please enter a different user name.";
case MembershipCreateStatus.DuplicateEmail:
return "A user name for that e-mail address already exists. Please enter a different e-mail address.";
case MembershipCreateStatus.InvalidPassword:
return "The password provided is invalid. Please enter a valid password value.";
case MembershipCreateStatus.InvalidEmail:
return "The e-mail address provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidAnswer:
return "The password retrieval answer provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidQuestion:
return "The password retrieval question provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidUserName:
return "The user name provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.ProviderError:
return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
case MembershipCreateStatus.UserRejected:
return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
default:
return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
}
}
#endregion
}
当我运行程序时,它会在发现错误时将我带到视图中,但是我不确定问题出在哪里所以我想我会包含其他代码来帮助,如果有人可以帮助我,非常感谢。
答案 0 :(得分:1)
不使用Viewbag包含父任务列表,而是返回包含列表本身的视图。
在您的控制器中:
return View(taskList)
现在在你看来:
@model List<parentTask>
<h2>@ViewBag.Message</h2>
<table>
@for (var i = 0; i < Model.Count; i++)
{
<tr>
@for (var j = 0; j < 9; j++)
{
<td>@Model[i].attr[j];</td>
}
</tr>
}
假设您的类和其他方法没有错误。
答案 1 :(得分:1)
代码存在许多问题,因此最容易提供完整的示例。我已经采用了行业标准的属性,变量和参数命名约定。
始终旨在使视图尽可能简单,因为它们是MVC中最不易读的部分。使用强类型模型优先于ViewBag变量。
由于数据包含在列表中,请使用foreach
,而不是将它们编入索引(在这种情况下,包括任务和属性)。
@model IEnumerable<TaskManager.Models.ParentTask>
@{
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
<table>
@foreach (var parentTask in Model)
{
<tr>
@foreach (var attr in parentTask.Attr)
{
<td>@attr</td>
}
</tr>
}
</table>
始终在短名称之前使用可读的变量/属性/参数名称。使用大小写允许您以有意义的方式重用名称作为属性和匹配参数。
public class ParentTask
{
int TaskId { get; set; }
int ParentTaskId { get; set; }
String TaskName { get; set; }
String DueDate { get; set; }
String CompletionDate { get; set; }
String Description { get; set; }
String AssignedTo { get; set; }
String Tags { get; set; }
public List<object> Attr;
public ParentTask(int taskId, int parentTaskId, String taskName, String dueDate, String completionDate, String description, String assignedTo, String tags)//constructor
{
TaskId = taskId;
ParentTaskId = parentTaskId;
TaskName = taskName;
DueDate = dueDate;
CompletionDate = completionDate;
Description = description;
AssignedTo = assignedTo;
Tags = tags;
Attr = new List<object>();
Attr.Add(TaskId);
Attr.Add(ParentTaskId);
Attr.Add(TaskName);
Attr.Add(DueDate);
Attr.Add(CompletionDate);
Attr.Add(Description);
Attr.Add(AssignedTo);
Attr.Add(Tags);
}
}
您无法保证每个页面都会调用控制器的构造函数,因为它们被重用,因此您需要每次都清除任务列表。
public class TaskController : Controller
{
String[] values = new fileReader().values;
public List<ParentTask> TaskList = new List<ParentTask>();
public ViewResult Index()
{
// These were not used
//string tId = values[0];
//string tPId = values[1];
//string tName = values[2];
//string tD = values[3];
//string tC = values[4];
//string tDe = values[5];
//string tA = values[6];
//string tT = values[7];
// The constructor may not be called on each page load, so clear the list
TaskList.Clear();
for (int i = 8; i < values.Length; i += 8)
{
TaskList.Add(new ParentTask(Convert.ToInt32(values[i]), Convert.ToInt32(values[i + 1]), values[i + 2], values[i + 3], values[i + 4], values[i + 5], values[i + 6], values[i + 7]));
}
// Return a strongly typed view with our list of tasks as the ViewModel
return View(TaskList);
}