web-dev-qa-db-ja.com

MVC5 RazorViewで動的モデルを渡す

動的な結果をコントローラーからビューに渡そうとしています。メソッドShowColorは動的な結果を返します。ビューでコレクションをループしようとしましたが、エラーが発生します

「オブジェクト」には「ColorID」の定義が含まれていません。

コントローラとビューに次のコードがあります

public class myColor
{
    public int ID { get; set; }
    public string  Name { get; set; }
    public string Like { get; set; }
}

public dynamic ShowColor()
{
    IList<myColor> color = new List<myColor>();
    color.Add(new myColor { ID = 1, Name = "Red", Like = "***" });
    color.Add(new myColor { ID = 2, Name = "Green", Like = "*****" });
    color.Add(new myColor { ID = 3, Name = "Blue", Like = "**" });
    color.Add(new myColor { ID = 4, Name = "Yellow", Like = "*" });

    var select = (from c in color
                  select new
                  {                     
                      ColorID = c.ID,
                      ColorName = c.Name
                  }).ToList();

    return select;
}
public ActionResult DBDynamic()
{
    return View(ShowColor());
}

見る

@model dynamic

@{
    ViewBag.Title = "DBDynamic";
}

<h2>DBDynamic</h2>

<p>
    <ul>
        @foreach (var m in Model)
        {
            <li> @m.ColorID</li>            
        }
    </ul>

</p>

Error

Debug Image

解決策を見つけましたここ そして素敵なブログ ここ

public static ExpandoObject ToExpando(this object anonymousObject)
{
    IDictionary<string, object> expando = new ExpandoObject();
    foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(anonymousObject))
    {
        var obj = propertyDescriptor.GetValue(anonymousObject);
        expando.Add(propertyDescriptor.Name, obj);
    }

    return (ExpandoObject)expando;
}

そしてそれをこのように呼ぶ

    var select = (from c in color
                select new
                {
                    ColorID = c.ID,
                    ColorName = c.Name
                })
                .AsEnumerable()
                .Select(x => x.ToExpando());

return View(select);
6
sairfan

匿名オブジェクトはdynamicと同じものではありません。 dynamicのように使用したい場合は、次のようにキャストします。

@foreach (dynamic m in Model)

ただし、ダイナミクスは可能な限り避けるのが最善です。すべてのコンパイル時チェックとインテリセンスさえも失います。実行時までプロパティ名を太くしたかどうか、または実行時まで間違った種類のものを誤って間違った方法で使用したかどうかはわかりません。何かが壊れている場合は、コンパイル時に知りたいのですが、それがすでに稼働していてユーザーに影響を与えているときではなく、ユーザーが通知しない限りエラーが発生したことさえ知らない可能性があります。これは、アプリにとって恐ろしい状況です。

長短、強いタイプを使用してください。 ColorIDColorNameのプロパティを持つものが必要な場合は、それらのプロパティを持つビューモデルを作成し、そのタイプのインスタンスへのクエリを選択します。そうすれば、すべてが素晴らしく、強く型付けされ、コードにエラーや問題があるかどうかを事前に知ることができます。

4
Chris Pratt