ASP.NET MVC在View

时间:2015-07-30 02:12:05

标签: c# asp.net-mvc inheritance

我对c#和OOP以及MVC都很陌生,并且正在努力从MVC View中的继承类中获取数据。我可能做错了。

我有例如:

public class TasksViewModel
{
    public Tasks tasks;
        public TaskViewModel()
        {
            this.tasks = new Tasks();
        }
    }
}

然后我(简化):

public class BaseTask    
{
    public int id { get; set; }
    public String Description { get; set; }
}

public class WorkTasks : BaseTask
{
    public String Company { get; set; }
}

public class HomeTasks : BaseTask
{
    public String UserName{ get; set; }
}

public class Tasks
{

    public List<BaseTask> taskslist { get; set; }
    public Tasks()
    {
         taskslist = getAllTasks();
    }

    public List<BaseTask> getAllTasks()
    {


           //get data
        List<BaseTask> tempTasks = new List<BaseTask>();
        if (taskType == "Work")
        {
            WorkTask work = new WorkTask();
            work.id = id;
            work.Description = description;
            work.Company = company;
            tempTasks.Add(work)
        }
        else
        {
            HomeTask home = new HomeTask();
            home.id = id;
            home.Description = description;
            home.UserName = name;
            tempTasks.Add(home)
        }
...
        return tempTasks;

}

我将模型设置为任务,在我的视图中,我只是遍历它们

@foreach(var item in Model.tasks.taskslist)
{
    <p>@item.Description</p>
}

这很好用,我可以获得描述和Id,但我无法从BaseTask继承的任务中获取Company或UserName。我从item获得的数据是:

>id
>Description
>Namespace.WorkTasks

但是我无法访问WorkTasks或HomeTasks。

我可以通过

检查该项是WorkTask还是HomeTask
if (item.GetType().Name.Equals("WorkTasks"))
{
}

我试过

item.WorkTasks.Company

但这只是一个错误:任务不包含WorkTasks的定义......

我确信我犯了一个愚蠢的菜鸟错误。有人可以帮忙吗?

如果我这样做完全错了,那就说吧。这是我第一次尝试这个。

2 个答案:

答案 0 :(得分:2)

这似乎过于复杂,并且缺乏使用MVC的一些非常好的优点(授予我没有真正的整个帖子)。所以这里有一些示例代码基于你的大多数模型:

更简单的模型:

public class TasksViewModel
{
  public IEnumerable<TaskBase> Tasks {get; set; }
}

// Removed (s), it's best practice to only use s on collections
public class WorkTask : BaseTask
{
  public String Company { get; set; }
}

// Removed (s), it's best practice to only use s on collections
public class HomeTask : BaseTask
{
  public String UserName{ get; set; }
}

Controller填充模型:

public MyController
{
  public ActionResult MyTasksAction()
  {
    var model = new TasksViewmodel()
    model.Tasks = db.GetTasks();
    return View(model);  // Looks for MyTasksAction.cshtml
  }
}

查看(MyTasksAction.cshtml):

@model TasksViewModel

<div>
  @Html.DisplayFor(m => m.Tasks)
</div>

繁荣完成......(sorta kidding, but not really, if you're into that sorta thing

默认情况下,DisplayFor会完成它的工作(thats a story for another time),但它找不到与该类型匹配的显示模板,因此它使用它自己的内部对象显示模板,该模板足够智能循环所有项目自动神奇。当它遍历项目时,它会在每个项目上调用DisplayFor(),只要你有:

  

/Views/MyController/DisplayTemplates/WorkTask.cshtml

     

/Views/MyController/DisplayTemplates/HomeTask.cshtml

  

/Views/Shared/DisplayTemplates/WorkTask.cshtml

     

/Views/Shared/DisplayTemplates/HomeTask.cshtml

使用循环中的当前模型调用这些模板...因为显示模板基于类型(IE string的显示模板将是string.cshtml; worktask会是worktask.cshtml等。这些模板可能如下所示:

WorkTask.cshtml

@model WorkTask     
<div>
  @Html.DisplayFor(m => m.Description)</br>
  @Html.DisplayFor(m => m.Company)</br>
</div>

HomeTask.cshtml

@model HomeTask     
<div>
  @Html.DisplayFor(m => m.Description)</br>
  @Html.DisplayFor(m => m.UserName)</br>
</div>

答案 1 :(得分:0)

我将直接回答这个问题,从而获得学习经验。虽然,我可能会将其分成两个单独的列表,如其他人所建议的那样。一般的经验法则是每个模型的一个视图(.cshtml事物),虽然在工作中我们构建了一个ViewEngine来渲染List'TBase'所以大声笑。

namespace SOAnswer0729.Controllers
{
public class HomeController : Controller
{
    public RedirectToRouteResult Index()
    {
        return RedirectToAction("Tasks");
    }
    public ActionResult Tasks()
    {
        var tasks = new Tasks();
        var model = tasks.getAllTasks();
        return View(model);
    }
}

public class Tasks
{

    public List<BaseTask> taskslist { get; set; }
    public Tasks()
    {
        taskslist = getAllTasks();
    }

    public List<BaseTask> getAllTasks()
    {
        //get data
        List<BaseTask> tempTasks = new List<BaseTask>();

        tempTasks.AddRange(DataRepository.WorkSeedData);            
        tempTasks.AddRange(DataRepository.HomeSeedData);

        return tempTasks;
    }

    public enum TaskType
    {
        Undefined = 0,
        WorkTask = 1,
        HomeTask = 2
    }

}

public static class DataRepository
{

    public static List<WorkTask> WorkSeedData = new List<WorkTask>() { 
        new WorkTask() { id = 1, Company = "MSFT", Description = "Write Code" },
        new WorkTask() { id = 2, Company = "ATT", Description = "Sell Service" },
        new WorkTask() { id = 3, Company = "XFTY", Description = "Retain Customers" }
    };

    public static List<HomeTask> HomeSeedData = new List<HomeTask>() {
        new HomeTask() { id = 11, UserName = "Jim", Description = "Make Keys" },
        new HomeTask() { id = 12, UserName = "Bob", Description = "Find Keys" },
        new HomeTask() { id = 13, UserName = "Alice", Description = "Intecept Keys" }
    };
}

public class BaseTask
{
    public int id { get; set; }
    public String Description { get; set; }
}

public class WorkTask : BaseTask
{
    public String Company { get; set; }
}

public class HomeTask : BaseTask
{
    public String UserName { get; set; }
}

}

查看

@using SOAnswer0729.Controllers;
@model IEnumerable<BaseTask>
<table class="table">
<tr>
    <th>Company / Name </th>
    <th>
        @Html.DisplayNameFor(model => model.Description)
    </th>
</tr>

@foreach (var item in Model) {
<tr>
    <td>
        @Html.DisplayFor(modelItem => item.Description)
    </td>
    <td>
        @{ if (item is WorkTask)
            {
              <text>@(((WorkTask)item).Company)</text>
            }
            else if (item is HomeTask)
            {
                <text>@(((HomeTask)item).UserName).</text>
            }
        }
    </td>
</tr>
}
</table>