沿模型传递额外数据的最佳实践是什么?

时间:2017-08-02 15:11:47

标签: asp.net-mvc

有时您需要将一些额外的数据传递给视图。例如,添加新闻页面中的新闻组应该从数据库中检索。

我知道在视图中创建Db-context的实例并不是一个很好的做法。相反,我们可以向视图模型添加一些属性并将这些数据传递给视图或使用View-Bag并对其进行类型转换,但在这些情况下,您可能需要在HttpGet和HttpPost中编写一些代码,当您需要时在Get和Post方法中返回相同的视图。

进行此类操作的最佳做​​法是什么?有没有另一种方式写一次?

3 个答案:

答案 0 :(得分:1)

据我了解,您似乎可以处理您需要执行的操作,但不喜欢get和post操作之间的代码重复。为此,只需将公共代码分解为控制器上的受保护或私有方法,两个操作都可以调用。例如,假设您需要一个Foo项目的选择列表:

public class MyViewModel
{
    ...
    public IEnumerable<SelectListItem> FooOptions { get; set; }
}

然后:

public class MyController : Controller
{
    ...

    private void PopulateFooOptions(MyViewModel model)
    {
        var foos = db.Foos.ToList();
        model.FooOptions = foos.Select(f => new SelectListItem { Value = f.Id.ToString(), f.Name });
    }

    public ActionResult Create()
    {
        var model = new MyViewModel();
        PopulateFooOptions(model);
        return View(model);
    }

    [HttpPost]
    public ActionResult Create(MyViewModel model)
    {
        if (ModelState.IsValid)
        {
            // do stuff
        }

        PopulateFooOptions(model);
        return View(model);
    }
}

答案 1 :(得分:0)

要仅编写一次组件并在不同视图中重复使用它,请将组件打包到自己的操作中,并使用自己的ViewModelPartial View

如果无法从外部调用此操作,则将其归为[ChildActionOnly]。数据库访问应该在此子操作中发生,数据应使用ViewModel传递给View。

使用@Html.Action("{actionName}", "{controllerName}")在需要时呈现此操作生成的HTML。

例如:

NewsController包含子操作:

[ChildActionOnly]
public PartialViewResult ShowNewsGroups(long userId) {

    var data = // ... read from DB using userId parameter
    var vm = new ShowNewsGroupsViewModel {
           GroupInfos = data
    };

    return PartialView("_ShowNewsGroups", vm);
}

部分视图_ShowNewsGroups.cshtml呈现新闻组:

@model ShowNewsGroupsViewModel 
@for(var i = 0; i < Model.GroupInfos.Count(); i++) {
    @Html.DisplayFor(m => m.GroupInfos[i])
}

主视图调用子操作并传递所需参数:

@Html.Action("ShowNewsGroups", "News", new { userId = Model.UserId }))

答案 2 :(得分:0)

出于这个特定原因,我们使用ViewModel概念 它只是一个需要财产的模型

例如,假设您有一个名为test的模型现在要传递一些额外的属性,如isValid的boolean和datetime Created 所以

你的观点=模型将是

public class YourViewMode
{
public test mainModel{get;set;}
public bool isValid {get;set;}
public datetime Created {get;set;}
}

现在只需将此模型初始化为您的视图,这就是viewmodel的工作原理