32

私はかなり苛立たしい問題を経験しています。私のMVCサイトはほとんどの部分で正常に動作しますが、ランダムにエラーをスローします(これはユーザーにわかりやすいエラーを示します)。ログを確認すると、次のようになります。

System.InvalidOperationException: The model item passed into the dictionary is of type 'System.Web.Mvc.HandleErrorInfo' but this dictionary requires a model item of type 'BaseViewData'.

しばらくすると、同じユーザーが更新を押してページが正常に読み込まれる可能性があります。私は立ち往生しています。;(

更新:スタックトレースを追加

System.Web.HttpUnhandledException: Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.InvalidOperationException: The model item passed into the dictionary is of type 'System.Web.Mvc.HandleErrorInfo' but this dictionary requires a model item of type 'BaseViewData'.
   at System.Web.Mvc.ViewDataDictionary`1.SetModel(Object value)
   at System.Web.Mvc.ViewDataDictionary..ctor(ViewDataDictionary dictionary)
   at System.Web.Mvc.HtmlHelper`1..ctor(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection)
   at System.Web.Mvc.ViewMasterPage`1.get_Html()
   at ASP.views_shared_site_master.__Render__control1(HtmlTextWriter __w, Control parameterContainer)
   at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
   at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
   at System.Web.UI.Control.Render(HtmlTextWriter writer)
   at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer)
   at System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children)
   at System.Web.UI.Control.RenderChildren(HtmlTextWriter writer)
   at System.Web.UI.Page.Render(HtmlTextWriter writer)
   at System.Web.Mvc.ViewPage.Render(HtmlTextWriter writer)
   at System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter)
   at System.Web.UI.Control.RenderControl(HtmlTextWriter writer)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   --- End of inner exception stack trace ---
   at System.Web.UI.Page.HandleError(Exception e)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest()
   at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context)
   at System.Web.UI.Page.ProcessRequest(HttpContext context)
   at ASP.views_shared_error_aspx.ProcessRequest(HttpContext context)
   at System.Web.Mvc.ViewPage.RenderView(ViewContext viewContext)
   at System.Web.Mvc.WebFormView.RenderViewPage(ViewContext context, ViewPage page)
   at System.Web.Mvc.WebFormView.Render(ViewContext viewContext, TextWriter writer)
   at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
   at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
   at System.Web.Mvc.Controller.ExecuteCore()
   at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
   at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext)
   at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext)
   at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext)
   at System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
4

4 に答える 4

19

これは、そのエラーが発生する理由を説明するcodeplexの問題です。

元のリンクが無効になっているため、 http://web.archive.org/web/20131004122626/http: //aspnet.codeplex.com/workitem/1795から引用します。

HandleError属性は、ViewDataに例外情報を格納するべきではありません

属性が例外を処理するとき、HandleError例外情報をに格納しますViewData。これは、Error.aspxから継承しsite.mastersite.masterクラスが次のように宣言されている場合に問題になります。

public partial class Site : System.Web.Mvc.ViewMasterPage<SiteViewData>
{
}

SiteViewData含まれています:

public class SiteViewData 
{
  public String Title { get; set; } 
}

各ページViewDataクラスはクラスを継承し、次のSiteViewDataようになります。

public class IndexViewData : SiteViewData
{
  public String Message { get; set; }
  public String SupportedLanguages {get; set;}
}

Site.Masterこのアプローチにより、次のようにページにコードを記述できます。

<title><%= Html.Encode(ViewData.Model.Title) %></title>

残念ながら、例外がスローされると、モデルはHandleErrorInfoクラスのインスタンスに置き換えられます。これによりInvalidOperationException、情報とともにがスローされます

ディクショナリに渡されるモデルアイテムはタイプですSystem.Web.Mvc.HandleErrorInfoが、このディクショナリにはタイプのモデルアイテムが必要Igwt.Boh.Website.Web.Controllers.SiteViewDataです。

代わりにクラスのインスタンスを格納するために、新しいErrorDataプロパティをクラスに追加することは可能ですか?このように、は変更されません。ViewResultHandleErrorInfoViewData

IndexViewData(およびSiteViewData)プロパティがすでに初期化された後に、アクションでスローされる例外が発生する可能性はかなりあります。

2010年1月27日午前0時24分に閉店

修正されません-コメントを参照してください。


「wontfix」で言及されているコメントは、Microsoftチームの元メンバーからのものであり、それを回避するための提案(太字)が付いています。

[HandleError]属性が実行されるまでに、元のActionResultオブジェクトへの参照が失われています。とにかくビューを表示するつもりだったのかどうかさえわかりません-おそらくリダイレ​​クトするつもりだったのでしょう。コントローラーからビューにモデルを渡す役割を果たしていたパイプラインの部分(ViewResult)はなくなりました。

例外が発生した場合、アプリケーションが作業していたモデルは、おそらく破損しているか、使用できないものとして扱われる必要があります。ベストプラクティスは、エラービューもその依存関係(マスターページなど)も元のモデルを必要としないようにエラービューを作成することです。

于 2010-01-04T06:18:33.540 に答える
10

この問題に対処するための私の解決策は、レイアウトページの上部にある@modelディレクティブを削除してから、通常はモデルが渡される可能性のあるさまざまなモデル間で切り替わると予想される場所でいくつかのチェックを行うことです。

@if (Model is System.Web.Mvc.HandleErrorInfo)
{
    <title>Error</title>
}
else if (Model.GetType() == typeof(MyApp.Models.BaseViewModel))
{
    <meta name="description" content="@Model.PageMetaDescription">
    <title>@Model.PageTitleComplete</title>
}
于 2015-05-28T23:05:32.840 に答える
4

アプリで同様の問題を追跡したところ、修正について説明したいと思います。私の場合、次の例外が発生していました。

System.InvalidOperationException: The model item passed into the dictionary is of 
type 'System.Web.Mvc.HandleErrorInfo', but this dictionary requires a model item of
type 'Web.Models.Admin.Login'.

そして、私は[HandleError]を使用してエラーをにルーティングしていました~/Shared/Error.cshtml

[少なくとも私の場合]起こった ~/Shared/Error.cshtmlことLayout = "~/Views/SiteLayout.cshtml";は、レイアウト/ cssインクルードを複製せずに、エラーページが(サイトの他の部分と同様に)正しくスタイル設定されていることを確認する必要があったことです。

~/Views/SiteLayout.cshtml部分的に含まれていました:~/Shared/LightboxLogin.cshtmlログイン用のインラインライトボックスを提供します。 ~/Shared/LightboxLogin.cshtml実際のログインフォームを埋め込むための部分がさらにありました。@Html.Partial("Login")これに~/Shared/Login.cshtml は、サイトのフロントエンドのログイン機能に使用されます。

サイトの管理エリアでエラーが発生したため、コントローラーは「管理者」であり、エラーが発生すると、モデルError.cshtmlに含まれるが呼び出されました。これには、パーシャルが含まれる、...含まれていましたが、代わりに含まれる別のビューがありました。SiteLayout.cshtmlHandleErrorInfoLightboxLoginLogin~/Admin/Login.cshtml@Html.Partial("Login")

このビューに~/Admin/Login.cshtmlは次のようなものがあります。@model Web.Models.Admin.Login

したがって、ここで学んだ教訓は、含めたいパーシャルの命名に注意することです。~/Shared/Login.cshtml使用され~/Shared/PublicLoginForm.cshtmlていた場合@Html.Partial("PublicLoginForm")、この問題は回避されたはずです。

補足:これを次のように修正しました[ビューを再構築したくなかったため]:

@if (!(Model is HandleErrorInfo))
{
   @Html.Partial("LightboxLogin")
}

つまり、レイアウトがエラー状態に含まれている場合、パーシャルは含まれません。

于 2014-12-11T20:47:11.840 に答える
1

強く型付けされたビューでこのエラーが発生し、元のリクエストコンテキストのRouteData.Values["controller"]と"action"をエラーページコントローラーとアクション名に一致するように設定することで修正しました。

ここを見ると、拡張されたHandleErrorAttribute実装が表示されます。これは、JSONサポートに加えて、結果ビューで基本クラスで何が起こっているかを示します。

https://www.dotnettricks.com/learn/mvc/exception-or-error-handling-and-logging-in-mvc4

ここでのViewResultの構成が、Microsoftで使用されているロジックのようなものである場合、問題は、コントローラーやアクション(元の要求から変更されているため)ではなく、新しい(エラー条件)ビューのみを指定できることである可能性があります。おそらくそれが、MVCフレームワーク/ハンドラーが型付きビューと混同されている理由です。それは私にはバグのようです。

上記の例にはこの修正が含まれていないため、次のように編集する必要があります(最後の2行とコメントは新しいものです)。

var model = new HandleErrorInfo(httpError, controllerName, actionName);
filterContext.Result = new ViewResult
{
    ViewName = View,
    MasterName = Master,
    ViewData = new ViewDataDictionary(model),
    TempData = filterContext.Controller.TempData
};

// Correct routing data when required, e.g. to prevent error with typed views
filterContext.RouteData.Values["controller"] = "MyError";  // MyErrorController.Index(HandleErrorInfo)
filterContext.RouteData.Values["action"] = "Index";

フィルタ/属性で処理していない場合は、ルーティングデータを処理している最後の2行のようなことを行うだけで済みます。たとえば、多くの「OnError」の例では、エラーコントローラを作成してから、IContoller.Executeを呼び出します。しかし、それは別の話です。

とにかく、このエラーが発生した場合は、エラーを処理している場所で、元の「コントローラー」と「アクション」の名前を使用している名前にリセットするだけで、修正される可能性があります。

于 2013-10-17T15:17:10.440 に答える