【问题标题】:How to display two partialviews in the same view in MVC?如何在 MVC 中的同一视图中显示两个局部视图?
【发布时间】:2015-11-21 17:23:09
【问题描述】:

如何在同一个视图中显示两个局部视图?在我的控制器中,我有两种方法都返回局部视图。我希望将这些方法放在一个视图中。

在我的控制器中我有这个:

   public ActionResult CountCars()
    {           
        var result = this.Data.Cars.All()                    
            .Select(t => new CarsViewModel
            {
                CategoryName = t.Name,
                CategoryCount = t.Category.Count()
            });
        return PartialView("_ChooseCarsPartialViewLayout", result.ToList());
    }

    public ActionResult ChooseCity()
    {
        var view = this.Data.Cities.All()
            .Select(x => new CityViewModel
            {
                CityName = x.Name,
                CountCities = x.City.Count()
            });

        return PartialView("_ChooseCarsPartialViewLayout", view.ToList());                   
    }      

_ChooseCarsPartialViewLayout

@model IEnumerable<Project.ViewModels.City.CityViewModel> <div class="container">
<div class="well">

    <div class="row">

        <div class="col-md-12">

            <div class="form-group">
                <h4>?</h4>
                <div class="checkbox checkbox-primary">
                    @for (int i = 0; i < Model.Count(); i++)
                    {
                        var cars = Model.ElementAt(i);

                        <label>@cars.CategoryName <span class="badge">@cars.CategoryCount</span></label>
                        @Html.RadioButton(cars.CategoryName,
                                 cars.CategoryId,
                            new
                            {
                                id = "radio",
                                type = "checkbox"

                            })

                    }
                </div>
            </div>



            <div class="form-group">
                <h4>Hvor vil du jobbe?</h4>
                <div class="checkbox checkbox-primary">
                    @for (int i = 0; i < Model.Count(); i++)
                    {
                        var city = Model.ElementAt(i);

                        <label>@city.CityName <span class="badge">@city.CountCities</span></label>
                        @Html.RadioButton(city.CityName,
                            city.CityId,
                            new
                            {
                                id = "radio",
                                type = "checkbox"

                            })

                    }
                </div>
            </div>
        </div>
    </div>
</div>

当我运行解决方案时,它只会显示一条错误消息。

值不能为空或空。 参数名称:名称

第 18 行:@Html.RadioButton(cars.CategoryName,

但如果我有两个不同的局部视图,那么效果很好,但我想在同一个局部视图中使用它。

我在 _Layout 中也有这个 Html.Action 来渲染部分视图

 @Html.Action("ChooseCity", "Home")

有什么建议吗?

【问题讨论】:

标签: asp.net asp.net-mvc


【解决方案1】:

问题在于强类型为IEnumerable&lt;Project.ViewModels.City.CityViewModel&gt; 的部分视图模型不包含CategoryName 的声明。因此,您应该创建一个复合模型,它将 CarsCitis 返回到局部视图。

public class CompositeModel
{
   public IEnumerable<Project.ViewModels.City.CityViewModel> Cars { get; set; }
   public IEnumerable<Project.ViewModels.City.CarsViewModel> Cities { get; set; }
}

现在改变你的看法

@model CompositeModel
<div class="container">
<div class="well">

    <div class="row">

        <div class="col-md-12">

            <div class="form-group">
                <h4>?</h4>
                <div class="checkbox checkbox-primary">
                    @for (int i = 0; i < Model.Cars.Count(); i++)
                    {
                        var cars = Model.Cars.ElementAt(i);

                        <label>@cars.CategoryName <span class="badge">@cars.CategoryCount</span></label>
                        @Html.RadioButton(cars.CategoryName,
                                 cars.CategoryId,
                            new
                            {
                                id = "radio",
                                type = "checkbox"

                            })

                    }
                </div>
            </div>



            <div class="form-group">
                <h4>Hvor vil du jobbe?</h4>
                <div class="checkbox checkbox-primary">
                    @for (int i = 0; i < Model.Cities.Count(); i++)
                    {
                        var city = Model.Cities.ElementAt(i);

                        <label>@city.CityName <span class="badge">@city.CountCities</span></label>
                        @Html.RadioButton(city.CityName,
                            city.CityId,
                            new
                            {
                                id = "radio",
                                type = "checkbox"

                            })

                    }
                </div>
            </div>
        </div>
    </div>
</div>

【讨论】:

  • 每个人必须更改实现。如果您看到他的代码,他会为两个操作返回相同的局部视图,但局部视图是 CitiViewModel 的类型。因为,cshtml 不会编译(除非由构建属性设置),所以当进程第一次尝试编译视图时,会在运行时抛出异常。
  • @user1672994 非常感谢您的回答。我已经按照您的代码进行了操作,但在调试它时又遇到了一些问题。 "值不能为空。参数名称:源"
  • 你在哪一行遇到了问题?
  • @user1672994 第 13 行:for (int i = 0; i
  • Cities 对象是否为空?基本上,只有当 Model 或其属性不为空时,您才应该生成输入按钮。如果您仍然有两个操作,那么您将只返回模型中的一个属性(城市或汽车),因此您应该进行空检查。另一点 - 您只能执行将聚合模型返回到部分视图的操作。
【解决方案2】:

由于您有一个名为 CityViewModel 的 ViewModel(尽管我将其命名为 RadiosVM,我将创建一些 EditorFor 模板。

使用复合模型作为user1672994 mentioned in his answer,尽管它可以变得更通用和可重用。 ViewModel 应该封装所有(有例外)呈现视图所需的数据。

public class RadiosVM
{
  public string Name { get; set; }
  public IEnumerable<RadioVM> Radios { get; set; }
}

public class RadioVM
{
  public string Name { get; set; }
  public int Count { get; set; }
}

public class SomePageVM // whatever
{
  public RadiosVM CarRadios { get; set; }
  public RadiosVM CityRadios { get; set; }

  // ... other properties
}

不要仅仅为了显示模型而启动另一个控制器(这是低效的),除非控制器正在执行与当前控制器完全无关的事情和/或您计划缓存该视图。

public class SomeController
{

  public ActionResult SomePage()
  {
    var model = new SomePageVM();
    model.CarRadios = GetCarRadios;
    model.CityRadios = GetCityRadios;
    return View(model);
  }

  private RadiosVM GetCarRadios()
  {           
    var result = new RadiosVM()
    {
      Name = "Cars",
      Radios = this.Data.Cars.All()                    
        .Select(t => new RadioVM
        {
          CategoryName = t.Name,
          CategoryCount = t.Category.Count()
        })
        .ToList();
    }
      return result;
  }

  public RadiosVM ChooseCity()
  {
    var result = new RadiosVM ()
    {
      Name = "Cars",
      Radios = this.Data.Cities.All()                    
        .Select(t => new RadioVM
        {
          CategoryName = t.Name,
          CategoryCount = t.Category.Count()
        })
        .ToList();
    }
      return result;
} 

观看次数:

SomePage.cshtml

@Model SomePageVM  

<div class="well">

  <div class="row">

    <div class="col-md-12">
      @Html.EditorFor(m => m.CarRadios)
    <div/>

    <div class="col-md-12">
      @Html.EditorFor(m => m.CityRadios)
    <div/>

// ...

/Views/Shared/EditorTemplates/RadiosVM.cshtml 要么 /Views/SomeController/EditorTemplates/RadiosVM.cshtml

@Model RadiosVM

<div class="form-group">
  <h4>@Html.DisplayFor(m => m.Name)</h4>

  <div class="checkbox checkbox-primary">

  @Html.DisplayFor(m => m.Radios)

</div>

/Views/Shared/EditorTemplates/RadioVM.cshtml 要么 /Views/SomeController/EditorTemplates/RadioVM.cshtml

@Model RadioVM

<label>@Html.DisplayFor(m => m.Name)
  <span class="badge">@Html.DisplayFor(m => m.Count)</span>
</label>
@Html.RadioButton(model.Name, 
  model.Id,  // You have no code that references this, I don't know...
  new
  {
    id = "radio",  // so **ALL** radios are named 'id'??  not valid
    type = "checkbox"
  })

【讨论】:

  • 非常感谢您的回答!但是为什么我需要 EditorFor 模板呢?
  • 非常感谢!!我已按照您的代码进行操作,它似乎工作得很好! :) 谢谢@user1672994
猜你喜欢
  • 1970-01-01
  • 2014-07-28
  • 2019-04-21
  • 2016-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多