[C#.NET][ASP.NET] Use Model Binding implement ViewModel in Web Form

[C#.NET][ASP.NET] Use Model Binding implement ViewModel in Web Form

續上篇,http://www.dotblogs.com.tw/yc421206/archive/2014/12/17/147690.aspx

延續上篇範例,我把 ViewModel 加進去,必須要自己實作查詢、分頁、排序

準備動作

Entity Model

https://dotblogsamples.codeplex.com/SourceControl/latest#Simple.ModelBindingSortAndPaging/Simple.ModelBindingSortAndPaging/Models/Account.cs

View Model

https://dotblogsamples.codeplex.com/SourceControl/latest#Simple.ModelBindingSortAndPaging/Simple.ModelBindingSortAndPaging/Models/AccountViewModel.cs

 

專案引用了兩個元件,在 Nuget 上取得

  1. AutoMapper.dll
  2. System.Linq.Dynamic

 

AccountMapperProfile.cs

定義 Model 跟 ViewModel 的對應關係

https://dotblogsamples.codeplex.com/SourceControl/latest#Simple.ModelBindingSortAndPaging/Simple.ModelBindingSortAndPaging/Models/AccountMapperProfile.cs

 

CRUD

SelectMethod

UpdateMethod

DeleteMethod

InsertMethod


前端:

跟上一篇差不多,就不再描述

https://dotblogsamples.codeplex.com/SourceControl/latest#Simple.ModelBindingSortAndPaging/Simple.ModelBindingSortAndPaging/WebForm1.aspx

 

後端

專注在後端程式碼,要注意的是 SelectMethod

https://dotblogsamples.codeplex.com/SourceControl/latest#Simple.ModelBindingSortAndPaging/Simple.ModelBindingSortAndPaging/WebForm1.aspx.cs

 

SelectMethod

1.參數都是 GridView 觸發傳遞進來,其中 sortByExpression 參數,第一次會觸發時會帶 null,我會給它一個預設值

    if (string.IsNullOrWhiteSpace(sortByExpression))
    {
        sortByExpression = "帳號 ASC";
    }

2.透過 Mapper.FindTypeMapFor 取得 AccountViewModel 對應 Account 的欄位

    var mapName = Mapper.FindTypeMapFor<AccountViewModel, Account>()
                          .GetPropertyMaps()
                          .FirstOrDefault(p => p.SourceMember.Name == columnName)
                          .DestinationProperty.Name;

3.System.Linq.Dynamic,替 IEnumerable<T>.OrderBy 加入了查詢字串的功能, 若對實作方式有興趣請參考 http://www.dotblogs.com.tw/yc421206/archive/2014/11/25/147419.aspx

4.使用 EF 取得 Account 特定欄位,然後塞到 AccountViewModel

    var accounts = this._db.Accounts.OrderBy(mapName + " " + sort)
                    .Skip(startRowIndex)
                    .Take(maximumRows)
                    .Select(p => new AccountViewModel()
                    {
                        帳號 = p.UserId,
                        年齡 = p.Age,
                        電話 = p.Phone,
                        外號 = p.NickName
                    });

程式碼如下:


{
    if (string.IsNullOrWhiteSpace(sortByExpression))
    {
        sortByExpression = "帳號 ASC";
    }

    string[] split = null;
    var columnName = string.Empty;
    var sort = string.Empty;

    if (sortByExpression.Contains(' '))
    {
        split = sortByExpression.Split(' ');
        columnName = split[0];
        sort = split[1];
    }
    else
    {
        columnName = sortByExpression;
        sort = "ASC";
    }
    var mapName = Mapper.FindTypeMapFor<AccountViewModel, Account>()
                          .GetPropertyMaps()
                          .FirstOrDefault(p => p.SourceMember.Name == columnName)
                          .DestinationProperty.Name;

    //這樣寫同等 select * from 
    //var accounts = this._db.Accounts.OrderBy(mapName + " " + sort)
    //                       .Skip(startRowIndex)
    //                       .Take(maximumRows)
    //                       .Select(Mapper.Map<AccountViewModel>);

    var accounts = this._db.Accounts.OrderBy(mapName + " " + sort)
                    .Skip(startRowIndex)
                    .Take(maximumRows)
                    .Select(p => new AccountViewModel()
                    {
                        帳號 = p.UserId,
                        年齡 = p.Age,
                        電話 = p.Phone,
                        外號 = p.NickName
                    });
    totalRowCount = this._db.Accounts.Count();

    return accounts;
}

其餘的 Method..

UpdateMethod


{
    if (!ModelState.IsValid)
    {
        return;
    }

    var account = Mapper.Map<Account>(accountViewModel);
    var query = this._db.Accounts.FirstOrDefault(a => a.UserId == account.UserId);
    if (query == null)
    {
        return;
    }

    Mapper.Map(accountViewModel, query);
    this._db.SaveChanges();
}

DeleteMethod


{
    var account = Mapper.Map<Account>(accountViewModel);

    var query = this._db.Accounts.FirstOrDefault(a => a.UserId == account.UserId);
    if (query == null)
    {
        return;
    }
    this._db.Accounts.Remove(query);
    this._db.SaveChanges();
}

InsertMethod


{
    if (!ModelState.IsValid)
    {
        return;
    }

    var account = Mapper.Map<Account>(accountViewModel);

    this._db.Accounts.Add(account);
    try
    {
        this._db.SaveChanges();
    }
    catch (Exception ex)
    {
        throw;
    }
}

 


本文出自:http://www.dotblogs.com.tw/yc421206/archive/2014/12/19/147713.aspx

 

專案位置:https://dotblogsamples.codeplex.com/SourceControl/latest#Simple.ModelBindingSortAndPaging/

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo