【问题标题】:C# - How can I print out viewdata?C# - 如何打印出视图数据?
【发布时间】:2015-12-29 20:23:34
【问题描述】:

我想知道如何打印视图上的视图数据。

这是我传递视图数据的方式

 public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            User user = db.user.Find(id);

            if (user == null)
            {
                return HttpNotFound();
            }
            ViewData["competenties"] = from usercomp in dbE.UserComp
                                       join comp in dbE.Competenties on usercomp.fk_Comp_id equals comp.comp_id
                                       where usercomp.fk_user_id == id
                                       select new { compname = comp.competentie };

            ViewData["locations"] = from userloc in dbE.UserLoc
                                    join loc in dbE.Locations on userloc.fk_location_id equals loc.loc_id
                                    where userloc.fk_user_id == id
                                    select new { locname = loc.loc_name };
            return View(user);
        }

例如,如何在视图上为用户打印所有位置的“locname”?我尝试了很多东西,但到目前为止似乎没有任何效果。

【问题讨论】:

  • 创建视图模型并将其传递给视图,而不是执行 ViewData 不是更容易吗?

标签: c# asp.net asp.net-mvc view


【解决方案1】:

例如,我如何打印所有位置的“locname” 视图中的用户?

哦,再努力一点。 C# 中的匿名类型仅适用于当前方法。因此,就像在每个 ASP.NET MVC 应用程序中一样,请首先定义一些视图模型模型来描述您将在视图中使用的数据:

public class MyModel
{
    public string LocationName { get; set; }
}

您将把 LINQ 查询投射到:

 ViewData["locations"] = 
     from userloc in dbE.UserLoc
     join loc in dbE.Locations on userloc.fk_location_id equals loc.loc_id
     where userloc.fk_user_id == id
     select new MyViewModel { LocationName = loc.loc_name };

好的,既然你知道你的投影是什么,你可以在你的视图中使用这种类型:

@foreach (var model in (IEnumerable<MyViewModel>)ViewData["locations"])
{
    <div>@model.LocationName</div>
}

到目前为止,我展示的代码当然只是在您的情况下可以完成的第一步改进。这只是初学者。显然,永远不应该编写这样的代码,因为这是反人类罪。正确的做法是使用真实的视图模型进行投影:

public class Location
{
    public string Name { get; set; }
}

public class Competence
{
    public string Name { get; set; }
}

public class MyViewModel
{
    public User User { get; set; }
    public IEnumerable<Location> Locations { get; set; }
    public IEnumerable<Competence> Competences { get; set; }
}

然后在你的控制器动作项目中针对这个模型:

public ActionResult Details(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }

    User user = db.user.Find(id);

    if (user == null)
    {
        return HttpNotFound();
    }

    var competences = 
        from usercomp in dbE.UserComp
        join comp in dbE.Competenties on usercomp.fk_Comp_id equals comp.comp_id
        where usercomp.fk_user_id == id
        select new Competence { Name = comp.competentie };

    var locations = 
        from userloc in dbE.UserLoc
        join loc in dbE.Locations on userloc.fk_location_id equals loc.loc_id
        where userloc.fk_user_id == id
        select new Location { Name = loc.loc_name };

    var model = new MyViewModel
    {
        User = user,
        Locations = locations.ToList(), // eagerly fetch the data that will be needed in the view
        Competences = competences.ToList(), // eagerly fetch the data that will be needed in the view
    }

    return View(model);
}

很明显,最后一步是将您的视图强类型化为我们刚刚定义的视图模型:

@model MyViewModel

好的,现在访问您需要的任何信息都非常容易

@foreach (var location in Model.Locations)
{
    <div>@location.Name</div>
}

或其他:

@foreach (var competence in Model.Competences)
{
    <div>@competence.Name</div>
}

或者如果你想问候你的用户或其他什么:

<div>
    Hello @Model.User.FirstName and welcome back to my super duper website
</div>

当您在 ASP.NET MVC 视图中使用强类型视图模型时,您甚至会发现 Visual Studio 有一些相当不错的 IntelliSense,因此您不应该依赖一些动态转换和类似滴答声的东西- 在运行时等待在您(或您的用户)脸上爆炸的炸弹机制。

所以这篇文章的结论是你永远不应该在 ASP.NET MVC 应用程序中使用ViewDataViewBag。这两件事就像应该根除的癌症。在您的 ASP.NET MVC 解决方案中搜索这些关键字(Ctrl+Shift+F),如果出现,则对其进行操作。

【讨论】:

  • 感谢您的回复,非常有帮助
  • 嗨,我听从了你的建议,我开始理解结构,但是我有错误“实体或复杂类型 'P104.Models.Locations' 不能在LINQ to Entities 查询”,有什么建议吗?我几乎遵循了您的代码。
【解决方案2】:

如果出于某种原因您不想使用 ViewModel,您可以执行以下操作:

在 View 的开头声明一些对象;

@{
    Layout = null;
    var myObject = ViewData["locations"];
    var properties = myObject.GetType().GetProperties();
}

要显示属性的数据,请执行以下操作:

<label>@myObject.GetType().GetProperties().FirstOrDefault(x => x.Name == "locname").GetValue(myObject)</label>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-23
    • 1970-01-01
    • 2013-11-14
    相关资源
    最近更新 更多