3

ビューモデルが指定されていない場合(nullの場合)、ビューモデルの自動インスタンス化を実現しようとしています。

コントローラ アクション

public ActionResult SomeAction()
{
    return View("~/.../SomeView.cshtml"); //No model is given
}

SomeView.cshtml

@model Models.SomeModel //According to this type...
<h2>@Model.Title</h2>
//...auto instantiate @Model when it is null

RazorViewEngine をオーバーライドしようとしましたが、ViewEngine の時点でモデル タイプにアクセスできないようです (間違っている可能性があります)。提供されていても、常に null です。そして、インスタンス化しようとしているので、null モデルの型を学習できるはずなので、ビューのモデル型を取得するための別のメタデータが必要です。

DefaultModelBinder を拡張しようとしましたが、Http リクエストからモデルをバインドするためだけのようで、手動でビューを作成しても起動しませんでした。

私はアイデアがありません。実行可能であることを願っています。

4

1 に答える 1

3

BorysG の助けを借りて解決し、パーシャルで動作するように改善しました。

ディスカッション: http://forums.asp.net/t/1924332.aspx/1?ASP+NET+MVC+Automatic+Model+Instantiation+if+Model+is+not+provided

ここにもコードをコピーします。

public class CustomViewEngine : RazorViewEngine
{
    protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
    {
        var view = base.CreatePartialView(controllerContext, partialPath);

        return new ViewWrapper(view);
    }

    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
    {
        var view = base.CreateView(controllerContext, viewPath, masterPath);

        return new ViewWrapper(view);
    }
}

public class ViewWrapper : IView
{
    protected IView View;

    public ViewWrapper(IView view)
    {
        View = view;
    }

    public void Render(ViewContext viewContext, TextWriter writer)
    {
        //Type modelType = BuildManager.GetCompiledType(razorView.ViewPath);
        var razorView = View as RazorView;

        if (razorView != null)
        {
            //if we could not get the model object - try to get it from what is declared in view
            var compiledViewType = BuildManager.GetCompiledType(razorView.ViewPath);

            var model = viewContext.ViewData.Model;

            Type baseType = compiledViewType.BaseType;
            //model is passed as generic parameter, like this MyView1 : WebViewPage<MyModel1>
            if (baseType != null && baseType.IsGenericType)
            {
                //and here the trick begins - extract type of model from generic arguments
                var modelType = baseType.GetGenericArguments()[0]; //the same as typeof(MyModel1)

                // ReSharper disable UseMethodIsInstanceOfType
                //If model is null, or model is not type of the given model (for partials)
                if (model == null || !modelType.IsAssignableFrom(model.GetType()))
                // ReSharper restore UseMethodIsInstanceOfType
                {
                    //Set @model and render the view
                    viewContext.ViewData.Model = Activator.CreateInstance(modelType);
                }
            }
        }

        View.Render(viewContext, writer);
    }
}

また、Application_Start() の Global.asax.cs にも挿入されます。

//remove default Razor and WebForm view engines
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomViewEngine());
于 2013-07-23T10:38:06.293 に答える