Fix #266: Throw when views aren't found at call sites

- note `htmlHelper.Display()` does not throw on failures
This commit is contained in:
dougbu 2014-04-16 15:43:10 -07:00
parent f19fe0cbef
commit b8eb16d98d
8 changed files with 78 additions and 73 deletions

View File

@ -4,6 +4,7 @@ using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.DependencyInjection;
using Microsoft.AspNet.Mvc.Core;
using Microsoft.AspNet.Mvc.Rendering;
namespace Microsoft.AspNet.Mvc
@ -42,6 +43,18 @@ namespace Microsoft.AspNet.Mvc
private IView FindView([NotNull] IDictionary<string, object> context, [NotNull] string viewName)
{
var result = _viewEngine.FindView(context, viewName);
if (!result.Success)
{
var locations = string.Empty;
if (result.SearchedLocations != null)
{
locations = Environment.NewLine +
string.Join(Environment.NewLine, result.SearchedLocations);
}
throw new InvalidOperationException(Resources.FormatViewEngine_ViewNotFound(viewName, locations));
}
return result.View;
}
}

View File

@ -586,6 +586,38 @@ namespace Microsoft.AspNet.Mvc.Core
return string.Format(CultureInfo.CurrentCulture, GetString("AsyncResultFilter_InvalidShortCircuit"), p0, p1, p2, p3);
}
/// <summary>
/// The partial view '{0}' was not found. The following locations were searched:{1}
/// </summary>
internal static string ViewEngine_PartialViewNotFound
{
get { return GetString("ViewEngine_PartialViewNotFound"); }
}
/// <summary>
/// The partial view '{0}' was not found. The following locations were searched:{1}
/// </summary>
internal static string FormatViewEngine_PartialViewNotFound(object p0, object p1)
{
return string.Format(CultureInfo.CurrentCulture, GetString("ViewEngine_PartialViewNotFound"), p0, p1);
}
/// <summary>
/// The view '{0}' was not found. The following locations were searched:{1}.
/// </summary>
internal static string ViewEngine_ViewNotFound
{
get { return GetString("ViewEngine_ViewNotFound"); }
}
/// <summary>
/// The view '{0}' was not found. The following locations were searched:{1}.
/// </summary>
internal static string FormatViewEngine_ViewNotFound(object p0, object p1)
{
return string.Format(CultureInfo.CurrentCulture, GetString("ViewEngine_ViewNotFound"), p0, p1);
}
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);

View File

@ -321,11 +321,21 @@ namespace Microsoft.AspNet.Mvc.Rendering
var newViewData = new ViewDataDictionary(baseViewData, model);
var viewEngineResult = _viewEngine.FindPartialView(ViewContext.RouteValues, partialViewName);
var view = viewEngineResult.View;
if (!viewEngineResult.Success)
{
var locations = string.Empty;
if (viewEngineResult.SearchedLocations != null)
{
locations = Environment.NewLine +
string.Join(Environment.NewLine, viewEngineResult.SearchedLocations);
}
throw new InvalidOperationException(
Resources.FormatViewEngine_PartialViewNotFound(partialViewName, locations));
}
var view = viewEngineResult.View;
using (view as IDisposable)
{
var viewContext = new ViewContext(ViewContext, view, newViewData, writer);

View File

@ -225,4 +225,10 @@
<data name="AsyncResultFilter_InvalidShortCircuit" xml:space="preserve">
<value>If an {0} cancels execution by setting the {1} property of {2} to 'true', then the it should not call the next filter by invoking {3}.</value>
</data>
<data name="ViewEngine_PartialViewNotFound" xml:space="preserve">
<value>The partial view '{0}' was not found. The following locations were searched:{1}</value>
</data>
<data name="ViewEngine_ViewNotFound" xml:space="preserve">
<value>The view '{0}' was not found. The following locations were searched:{1}.</value>
</data>
</root>

View File

@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.Core;
using Microsoft.AspNet.Mvc.Rendering;
namespace Microsoft.AspNet.Mvc
@ -74,6 +75,18 @@ namespace Microsoft.AspNet.Mvc
private IView FindView([NotNull] IDictionary<string, object> context, [NotNull] string viewName)
{
var result = _viewEngine.FindView(context, viewName);
if (!result.Success)
{
var locations = string.Empty;
if (result.SearchedLocations != null)
{
locations = Environment.NewLine +
string.Join(Environment.NewLine, result.SearchedLocations);
}
throw new InvalidOperationException(Resources.FormatViewEngine_ViewNotFound(viewName, locations));
}
return result.View;
}
}

View File

@ -186,38 +186,6 @@ namespace Microsoft.AspNet.Mvc.Razor
return string.Format(CultureInfo.CurrentCulture, GetString("SectionsNotRendered"), p0);
}
/// <summary>
/// The partial view '{0}' was not found. The following locations were searched:{1}
/// </summary>
internal static string ViewEngine_PartialViewNotFound
{
get { return GetString("ViewEngine_PartialViewNotFound"); }
}
/// <summary>
/// The partial view '{0}' was not found. The following locations were searched:{1}
/// </summary>
internal static string FormatViewEngine_PartialViewNotFound(object p0, object p1)
{
return string.Format(CultureInfo.CurrentCulture, GetString("ViewEngine_PartialViewNotFound"), p0, p1);
}
/// <summary>
/// The view '{0}' was not found. The following locations were searched:{1}.
/// </summary>
internal static string ViewEngine_ViewNotFound
{
get { return GetString("ViewEngine_ViewNotFound"); }
}
/// <summary>
/// The view '{0}' was not found. The following locations were searched:{1}.
/// </summary>
internal static string FormatViewEngine_ViewNotFound(object p0, object p1)
{
return string.Format(CultureInfo.CurrentCulture, GetString("ViewEngine_ViewNotFound"), p0, p1);
}
/// <summary>
/// The method '{0}' cannot be invoked by this view.
/// </summary>

View File

@ -150,12 +150,6 @@
<data name="SectionsNotRendered" xml:space="preserve">
<value>The following sections have been defined but have not been rendered: '{0}'.</value>
</data>
<data name="ViewEngine_PartialViewNotFound" xml:space="preserve">
<value>The partial view '{0}' was not found. The following locations were searched:{1}</value>
</data>
<data name="ViewEngine_ViewNotFound" xml:space="preserve">
<value>The view '{0}' was not found. The following locations were searched:{1}.</value>
</data>
<data name="View_MethodCannotBeCalled" xml:space="preserve">
<value>The method '{0}' cannot be invoked by this view.</value>
</data>

View File

@ -32,26 +32,13 @@ namespace Microsoft.AspNet.Mvc.Razor
[NotNull] string viewName)
{
var viewEngineResult = CreateViewEngineResult(context, viewName);
var errorMessage = Resources.FormatViewEngine_ViewNotFound(
viewName,
ToLocationString(viewEngineResult.SearchedLocations));
EnsureViewEngineResult(viewEngineResult, viewName, errorMessage);
return viewEngineResult;
}
public ViewEngineResult FindPartialView([NotNull] IDictionary<string, object> context,
[NotNull] string partialViewName)
{
var viewEngineResult = CreateViewEngineResult(context, partialViewName);
var errorMessage = Resources.FormatViewEngine_PartialViewNotFound(
partialViewName,
ToLocationString(viewEngineResult.SearchedLocations));
EnsureViewEngineResult(viewEngineResult, partialViewName, errorMessage);
return viewEngineResult;
return FindView(context, partialViewName);
}
private ViewEngineResult CreateViewEngineResult([NotNull] IDictionary<string, object> context,
@ -86,24 +73,6 @@ namespace Microsoft.AspNet.Mvc.Razor
}
}
private void EnsureViewEngineResult(ViewEngineResult viewEngineResult, string viewName, string errorMessage)
{
if (!viewEngineResult.Success)
{
throw new InvalidOperationException(errorMessage);
}
}
private string ToLocationString(IEnumerable<string> locations)
{
if (locations != null)
{
return Environment.NewLine + string.Join(Environment.NewLine, locations);
}
return string.Empty;
}
private static bool IsSpecificPath(string name)
{
char c = name[0];