NHibernate ModelBinder for mvc3

所有源码在 https://github.com/luqizheng/Qi4Net

 

特色

  1. 支持DTO和Mapping Entity,并且会自动忽略没有Set的Property(包括集合属性也会被忽略)
  2. 支持Array,IList,IList<T>,Iesi.Collection.ISet<T>, Iesi.Collection.ISet, 但是并不支持System.Collection.Generic.ISet<T>

     

注意事项

  1.  获取的Mapping entity 都是Deatached的,所以如果包保存要使用Session.SaveOrUpdate的方法保存。


 

和一个持久化对象自动绑定

//持久化对象
//Qi4Net\src\Qi\MvcTest\Models\User.cs
public class User : DomainObject<Guid>
    {
        public string LoginId { getset; }
        public string Name { getset; }
        public string Password { getset; }
        public override int GetHashCode()
        {
            return (Name + Password).GetHashCode();
        }
    }

 

Post上来的数据会自动set到User里面,而且是自动匹配类型(其实就是NHibernate.Type.IType,提供的方法进行转换) 。NHibernateBinder会自动忽略只有Get的方法,另外IList,ISet是不支持的,因为不能简单地Clear and Add.所以只能靠手工了

//D:\GitQi\Qi4Net\src\Qi\MvcTest\Controllers\UserController.cs
[HttpPost,Session]
public ActionResult Edit([ModelBinder(typeof(NHModelBinder))]User user)
        {
            SessionManager.Instance.CurrentSession.SaveOrUpdate(user); 
            return RedirectToAction("Index");
        }

 

第二种,持久化对象是某个对象的其中一个。

 

是ChangeUserPasswordModel,而不是ChangePasswordModel,不太严谨,请见谅。

属性User是会默认使用IdFoundAttribute进行绑定的

 

//\Qi4Net\src\Qi\MvcTest\Models\ChangeUserPasswordModel.cs
public class ChangeUserPasswordModel
    {
        [Required]
        public User User { getset; }

        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "New password")]
        public string NewPassword { getset; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm new password")]
        [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
        public string ConfirmPassword { getset; }
    }

 

 

View要做稍稍处理,用HiddenFor是不行的。我用了

@Html.Hidden("User"this.Model.User.Id),其中"User"和

ChangeUserPasswordModel.User 名称是一样的。

 

//Qi4Net\src\Qi\MvcTest\Views\User\ChangePassword.cshtml
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>ChangeUserPasswordModel</legend>
        @*请留意这里*@
        @Html.Hidden("User"this.Model.User.Id) 
        <div class="editor-label">
            @Html.LabelFor(model => model.NewPassword)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.NewPassword)
            @Html.ValidationMessageFor(model => model.NewPassword)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.ConfirmPassword)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ConfirmPassword)
            @Html.ValidationMessageFor(model => model.ConfirmPassword)
        </div>
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

 

 

NHModelBinder默认的情况下,是用IdFoundAttribute进行查询的. 如果不是,那么就要对Model做一些处理。

 

  public class ChangeUserPasswordModel
    {
        [Required]             

        [Qi.Web.Mvc.PropertyFounder("LoginId",true)]
        public User User { getset; }
        .....
       
    }


假设User是使用LoginId进行查询的,那么就用NhModelFounderAttribute告诉NhModelBinder, 这个Property使用LoginId,进行查询的,后面的True告诉查询结构集合石唯一的,还是有多个,如果多个就用拿第一个。

 

当然也可以用 Hql,如:

 

        [Required]
        [NhModelFounder("From User u where u.Id=:User", "Guid")]
        public User[] User { get; set; }        

 

集合支持

 

暂时支持 IList<T>,IList, Iesi.Collection.ISet<T> Iesi.Collection.ISet,以及 Array,测试如下,可以参考

 Qi4Net\src\Qi\MvcTest\Models\ListDemo.cs

 

  [PropertyFounder("LoginId")]
        public User[] UsersByLoginId { getset; }

        public User[] UsersById { getset; }

        [IdFounder]
        public IList<Role> RolesByDeclareIdFounder { getset; }

        public Iesi.Collections.Generic.ISet<Role> RolesBySet { getset; }

        [HqlFounder("from User u where u.Name like :UserByHql or u.LoginId like :UserByHql""String")]
        public Iesi.Collections.Generic.ISet<User> UserByHql { getset; }

 

已经发布了1.0,只能说基本能用。

 

posted @ 2012-02-02 14:45  沉默的糕点  阅读(737)  评论(4编辑  收藏  举报