简体   繁体   English

ASP.NET MVC在View中获取继承的类数据

[英]ASP.NET MVC Get inherited class data in View

I am very new to c# and OOP and MVC and am struggling with getting the data from an inherited class in MVC View. 我对C#和OOP和MVC还是很陌生,并且正在努力从MVC View中的继承类获取数据。 I am probably doing this all wrong. 我可能做错了所有。

I have for example: 我有例如:

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

I then have (simplified): 然后,我有(简体):

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;

}

I set the model as Tasks and in my view I just iterate through them 我将模型设置为Tasks,在我看来,我只是遍历它们

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

this works just fine and I can get the description and Id, but I can't get the Company or UserName from the tasks inherited from BaseTask. 这工作正常,我可以获取描述和ID,但无法从BaseTask继承的任务中获取Company或UserName。 The data I get from item is: 我从item获得的数据是:

>id
>Description
>Namespace.WorkTasks

however I can't access WorkTasks or HomeTasks. 但是我无法访问WorkTasks或HomeTasks。

I can check that the item is a WorkTask or a HomeTask with 我可以使用以下命令检查该项目是WorkTask还是HomeTask

if (item.GetType().Name.Equals("WorkTasks"))
{
}

and I tried 我尝试了

item.WorkTasks.Company

but this just gives an error: Tasks does not contain a definition for WorkTasks... 但这只是一个错误:任务不包含WorkTasks的定义...

I am sure I am making a stupid rookie mistake. 我确定我是在犯一个愚蠢的菜鸟错误。 Can anyone help? 有人可以帮忙吗?

And if I am doing this totally wrong then just say. 如果我这样做完全错误,那就说。 This is my very first attempt at this. 这是我的第一次尝试。

This seems overly complicated and lacks using some of the awesome advantages of MVC (granted I didn't real the entire post). 这似乎过于复杂,并且缺乏使用MVC的某些令人赞叹的优势(当然,我并没有了解整个文章)。 So here is some example code based losely off most of your models: 因此,这是一些基于示例的大多数模型的示例代码:

Simplier model: 简单模型:

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 populates model: 控制器填充模型:

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

View (MyTasksAction.cshtml): 查看(MyTasksAction.cshtml):

@model TasksViewModel

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

Boom done... ( sorta kidding, but not really, if you're into that sorta thing ) 繁荣完成了...( 有点开玩笑,但如果您真的喜欢那种事情,那不是真的

By default the DisplayFor will do it's work ( thats a story for another time ) but it won't find a display template matching that type, so it uses it's own internal Object display template which is smart enough to loop through all the items auto-magically. 默认情况下,DisplayFor会完成它的工作( 这是另一个故事 ),但找不到与该类型匹配的显示模板,因此它使用自己的内部Object显示模板,该模板足够聪明,可以自动遍历所有项。神奇地。 As it loops through the items it calls DisplayFor() on each item so as long as you have: 只要遍历所有项目,只要您有以下条件,它就会在每个项目上调用DisplayFor()

/Views/MyController/DisplayTemplates/WorkTask.cshtml /Views/MyController/DisplayTemplates/WorkTask.cshtml

/Views/MyController/DisplayTemplates/HomeTask.cshtml /Views/MyController/DisplayTemplates/HomeTask.cshtml

OR 要么

/Views/Shared/DisplayTemplates/WorkTask.cshtml /Views/Shared/DisplayTemplates/WorkTask.cshtml

/Views/Shared/DisplayTemplates/HomeTask.cshtml /Views/Shared/DisplayTemplates/HomeTask.cshtml

those templates are called with the current model in the loop... because Display templates are based on the type (IE a display template for string would be string.cshtml ; worktask would be worktask.cshtml , etc). 这些模板在循环中与当前模型一起调用...,因为显示模板基于类型(即, string的显示模板为string.cshtmlworktaskworktask.cshtml等)。 Those templates might look like: 这些模板可能看起来像:

WorkTask.cshtml WorkTask.cshtml

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

HomeTask.cshtml HomeTask.cshtml

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

I'm going to answer the question directly cause its a learning experience. 我要回答这个问题,直接导致其学习经验。 Although, I would probably split it into two separate lists as suggested by other people. 虽然,我可能会按照其他人的建议将其分为两个单独的列表。 The general rule of thumb is one view (.cshtml thing) per one model, although at work we built a ViewEngine to render List'TBase' so lol. 一般的经验法则是每个模型一个视图(.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; }
}

} }

VIEW 视图

@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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM