2016-01-31 57 views
1

我有一个控制器使用两个类。一个叫IndexModel,另一个叫IndexViewModel。 我将IndexViewModel传递给IndexModel构造函数。.NET MVC - 集合属性应该是只读的通过删除属性更改为只读

[HttpGet] 
public ActionResult Index() 
{ 
    var model = new IndexModel(new IndexViewModel()); 
    var vm = model.GetViewModel(); 
    return View("Index", vm); 
} 

这是视图模型类。注意setter是私人的。

public class IndexViewModel 
{ 
    public IList<SelectListItem> SelectListItems { get; private set; } 
    public IndexViewModel() 
    { 
     this.SelectListItems = new List<SelectListItem>(); 
    } 
} 

这是模型。当调用GetViewModel时,将填充SelectListItems列表并返回视图模型。

public class IndexModel 
{ 
    private IndexViewModel vm; 

    public IndexModel(IndexViewModel IndexViewModel) 
    { 
     this.vm = IndexViewModel; 
    } 

    public IndexViewModel GetViewModel() 
    { 
     this.FillSelectListItems(); 
     return vm; 
    } 

    private void FillSelectListItems() 
    { 
     // this data is pulled in from another class that queries a database... 
     var data = ... 
     foreach (var itm in data) 
     { 
      vm.SelectListItems.Add(new SelectListItem() 
      { 
       Value = itm.Id.ToString(), 
       Text = itm.Text, 
      }); 
     } 
    } 
} 

我将不胜感激这是如何目前的结构有任何意见,但我的主要问题是:

它是不好的做法,写一堆的方法,如FillSelectListItems(),即改变收集数据和不要返回结果?

我应该让setter公开所以我可以从我的方法返回一个列表并设置视图模型属性的方式?

回答

2

你有什么需要通过使其私密?头痛......公开:)

在其他视图模型中使用视图模型没有任何问题...想象一下有博客帖子... BlogPostViewModel ...你会期望它也有评论对? BlogPostViewModel> CommentViewModel

public class BlogPostViewModel 
{ 
    public string BlogPostId { get; set; } 
    public string Title { get; set; } 
    public string Content { get; set; } 
    public List<CommentViewModel> Comments { get; set; } 
} 

现在,当你渲染,你的PostsController,在Posts/{id},视图Posts/Index.cshtml将呈现,你的意见可以在局部视图中被渲染...

// Take this as pseudo code as there's some syntatic errors (can't be asked to open VS) 
@for(int i = ... i < Model.Comments.Length... i++){ 
    this.Html.Partial("_CommentsPartial.cshtml, Model.Comments[i]) 
} 

在另一方面,如果你愿意,你可以在你的模型传递给视图作为JSON对象以及没有与此整洁的小黑客...在你的控制器动作......

this.ViewBag.Json = JsonConvert.SerializeObject<TViewModel>(viewModel); 

而且在你看来只是捡起来备份...

<script> var json = @this.ViewBag.Json </script> 

希望这提供了关于这些视图模型达到目的的一些见解...

+0

我想原因我认为最好保持setter私有是因为这个代码分析警告:'集合属性应该是只读的通过删除属性setter.Reset'IndexViewModel.SelectListItems'是只读的。尽管离开公共集合似乎没有其他消极的副作用所以我想我可以忽略这里的警告。谢谢! – ooXei1sh

+0

之所以这样说,是因为你没有从梯子上方的范围访问属性......一旦你这样做了,那个警告就会消失。代码分析是很好的,因为它可以帮助您保持代码清洁,但它会假定您当前的代码状态为最终状态,并基于此提供建议。 –