2

問題

現在、MVC プロジェクトに自動マッピングを追加していますが、行き詰っています。現在、データベース内のデータを表すために使用される User モデルがあります。そのモデルを、Edit メソッドが呼び出されたときに使用される EditUserModel にマップする必要があります。EditUserModel にはIEnumerable<SelectListItem>(ドロップダウン メニューの場合) マッピング方法がわかりません。

試みられた解決策

今のところ、私は何も実装しようとしていません。に最適な場所、IEnumerable<SelectListItem>または配置する場所がわかりません。現在、コントローラーに入力されています。

ユーザー.cs

public class User
{
    [Key]
    public int UserID { get; set; }

    public string Username { get; set; }

    public string Password { get; set; }

    public int RoleID { get; set; }

    [ForeignKey("RoleID")]
    public virtual Role Role { get; set; }
}

EditUserModel.cs

public class EditUserViewModel
{
    [HiddenInput(DisplayValue = false)]
    public int UserID { get; set; }

    [Required]
    public String Username { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public string Password { get; set; }

    [DisplayName("Role")]
    [Required]
    public int RoleID { get; set; }

    //The trouble field
    public IEnumerable<SelectListItem> Roles { get; set; }
}

Controller.cs

EditUserViewModel model = new EditUserViewModel();
//Population of the dropdown menu
model.Roles = context.Roles
    .ToList()
    .Select(x => new SelectListItem
    {
        Text = x.Description,
        Value = x.RoleID.ToString()
    });
//Mapping that the automaper will take care of
model.UserID = user.UserID;
model.Username = user.Username;
model.RoleID = user.RoleID;
4

2 に答える 2

7

記録のために、Jakubの回答へのコメントで私が話していたことは次のとおりです。

public static class EnumerableExtensions
{
    public static IEnumerable<SelectListItem> ToSelectList<T, TTextProperty, TValueProperty>(this IEnumerable<T> instance, Func<T, TTextProperty> text, Func<T, TValueProperty> value, Func<T, bool> selectedItem = null)
    {
        return instance.Select(t => new SelectListItem
        {
            Text = Convert.ToString(text(t)),
            Value = Convert.ToString(value(t)),
            Selected = selectedItem != null ? selectedItem(t) : false
        });
    }
}

言うまでもなく、これは劇的に単純で、同じことを実現します (Jakub のソリューションはネストされたプロパティでは機能しないため、プロパティ パスが単純でない場合は実際により堅牢です)。

(これは実際には答えではありません。要点を詳しく説明するために、コミュニティ wiki として投稿しています)

于 2012-06-07T19:57:28.193 に答える
1

コントローラーは、ビュー モデルを設定するのに最適な場所です。

この拡張メソッドを使用して配管コードを削除できます。

public static class EnumerableExtensions
{
    public static IEnumerable<SelectListItem> ToSelectList<T, TTextProperty, TValueProperty>(this IEnumerable<T> instance, Expression<Func<T, TTextProperty>> text, Expression<Func<T, TValueProperty>> value, Func<T, bool> selectedItem = null)
    {
        return instance.Select(t => new SelectListItem
        {
            Text = Convert.ToString(text.ToPropertyInfo().GetValue(t, null)),
            Value = Convert.ToString(value.ToPropertyInfo().GetValue(t, null)),
            Selected = selectedItem != null ? selectedItem(t) : false
        });
    }

    public static PropertyInfo ToPropertyInfo(this LambdaExpression expression)
    {
        MemberExpression body = expression.Body as MemberExpression;

        if (body != null)
        {
            PropertyInfo member = body.Member as PropertyInfo;
            if (member != null)
            {
                return member;
            }
        }

        throw new ArgumentException("Expression is not a Property");
    }
}

model.Roles = context.Roles.ToSelectList(r => r.RoleID, r => r.Description);
于 2012-06-07T19:44:53.250 に答える