2012-02-13 52 views
2

我想创建这样的模型形式:Razor视图引擎和模型在HTML辅助

class NewContractorModel 
{ 
    //... 
    public PhotoModel photos { get; set; } 
    //... 
} 
class PhotoModel 
{ 
    public List<Photo> f { get; set; } 
} 

从控制器我做一些操作(其实我删除了一些照片,从集合)的模型对象和把它们放到查看页面使用这个:

return new View("SomeView", model); 

我试着为每张照片创建输入(可以说隐藏的输入)。

for (int i = 0; i < Model.photos.f.Count; ++i) 
{ 
    @Html.HiddenFor(m => m.photos.f[i].Uri) 
    @Html.HiddenFor(m => m.photos.f[i].ThumbnailUri) 
    @Html.HiddenFor(m => m.photos.f[i].SmallThumbnailUri) 
    @Html.TextBoxFor(m => m.photos.f[i].Description, new { placeholder = "Dodaj opis" }) 
} 

但正如我注意到,这是行不通的,因为它关闭所有模型修改的(它仍然存储在列表中的所有照片尽管我在的Controler方法去除它们)。

然后我尝试这种代码:

for (int i = 0; i < Model.photos.f.Count; ++i) 
{ 
    Photo photo = Model.photos.f[i]; 
    <input id="[email protected]{@i}__Uri" name="photos.f[@{@i}].Uri" type="hidden" value="@photo.Uri"/> 
    <input id="[email protected]{@i}__ThumbnailUri" name="photos.f[@{@i}].ThumbnailUri" type="hidden" value="@photo.ThumbnailUri"/> 
    <input id="[email protected]{@i}__SmallThumbnailUri" name="photos.f[@{@i}].SmallThumbnailUri" type="hidden" value="@photo.SmallThumbnailUri"/> 
    <input id="[email protected]{@i}__Description" name="photos.f[@{@i}].Description" placeholder="Dodaj opis" type="text" value="@photo.Description"/> 
} 

...这时候IT WORKS!

任何人都可以解释我这两部分代码之间有什么区别? 我试着把这段代码翻了十几遍,它总是工作一样,所以它不是我的错。 ;) 我认为HtmlHelper方法中存在一个错误,但是是否有任何步行?我想使用助手方法,而不是原始的HTML。编辑: 这是简化的控制器类。

public class MyController 
{ 
    private NewContractorModel _model = null; 

    protected override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     _model = SerializationUtility.Deserialize(Request.Form["Data"]) as NewContractorModel; 
     if (_model == null) 
       _model = TempData["Data"] as NewContractorModel; 
     if (_model == null) 
       _model = new NewContractorModel() as NewContractorModel; 

     TryUpdateModel(_model); 
    } 

    protected override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     if (filterContext.Result is RedirectToRouteResult) 
      TempData["Data"] = _model; 
    } 

    private bool CheckModel(object model) 
    { 
     Type type = model.GetType(); 

     PropertyInfo[] properties = type.GetProperties(); 
     foreach (PropertyInfo p in properties) 
     { 
      object[] attr = p.GetCustomAttributes(true); 
      foreach (object a in attr) 
      { 
       if (a is ValidationAttribute) 
       { 
        object value = p.GetValue(model, null); 
        if (!((ValidationAttribute)a).IsValid(value)) 
         return false; 
       } 
      } 
     } 
     return true; 
    } 

    protected ActionResult SelectPage(string delPhoto) 
    { 
     if (!CheckModel(_model)) 
     { 
      // Do some action 
     } 
     //..... 
     foreach (ZAY.Database.Photo p in _model.photos.f) 
     { 
      if (p.Uri == Request["delPhoto"]) 
      { 
       _model.photos.f.Remove(p); 
       break; 
      } 
     } 
     //..... 
     return View("SomeView", _model); 
    } 
} 

我注意到里面的lambdas模型看起来就像在TryUpdateModel调用之后(在修改之前)。如果我不使用lambda表达式的模型被修改...:/

,也是我的照片级(从产生的EntityFramework - 所以没有什么有趣的),也简化为:

public class Photo : EntityObject 
{ 
    [Required] 
    public string Uri { get; set; } 

    [Required] 
    public string ThumbnailUri { get; set; } 

    [Required] 
    public string SmallThumbnailUri { get; set; } 

    public string Description { get; set; } 
} 

我对不起,我只写这样的小片段,但整个代码更复杂 - 只有最有趣的部分。

+0

请张贴你的'Photo'类定义和你的Controller的Action方法(s)属于这个问题。另外,如果你可以放置你的View的大部分(不仅仅是你的循环代码),这也会有帮助。 – 2012-02-13 18:22:11

回答

0

从您的描述中,我不太了解您的第一个样本中出现了什么问题。但是你肯定对循环变量i的范围有问题。

由于表达式m => m.photos.f[i]涉及闭包,因此将在稍后时间,for循环已完成时进行评估。该表达式捕获变量i(而不是变量i的值)。最终评估时,它会在变量i中找到值Model.photos.f.Count。因此,所有隐藏的字段和文本框将使用相同的无效值i

您的第二个代码示例通过在for循环中使用局部变量来避免此问题。

+0

不,这不是问题,因为如果我(0,1,2,3,4,...)所有隐藏字段都有有效值。 问题是,当lambda被评估为获取模型数据...它使用错误的模型对象:/不是这个我作为参数返回View()。 – 2012-02-13 18:38:24

+0

看起来 “m => m ...”(lambda表达式) 并不意味着与简单的 “Model ...”(不含lambda)相同。这很奇怪。 我也试着为Photo类创建EditorTemplate,然后调用@Html.EditorFor(m => m.photos.f),但它仍然给出相同的结果。 – 2012-02-13 18:49:53