ViewLocationExpanderContext should have a flag that indicates if the
lookup is for a full or partial view Fixes #1212
This commit is contained in:
parent
b821b706b7
commit
73f44889f2
|
|
@ -51,8 +51,10 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
var routeValues = context.ActionContext.RouteData.Values;
|
||||
var controller = routeValues.GetValueOrDefault<string>(RazorViewEngine.ControllerKey);
|
||||
|
||||
// format is "{viewName}:{controllerName}:{areaName}:"
|
||||
// format is "{viewName}:{isPartial}:{controllerName}:{areaName}:"
|
||||
keyBuilder.Append(context.ViewName)
|
||||
.Append(CacheKeySeparator)
|
||||
.Append(context.IsPartial ? 1 : 0)
|
||||
.Append(CacheKeySeparator)
|
||||
.Append(controller);
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(viewName));
|
||||
}
|
||||
|
||||
var pageResult = GetRazorPageResult(context, viewName);
|
||||
var pageResult = GetRazorPageResult(context, viewName, isPartial: false);
|
||||
return CreateViewEngineResult(pageResult, _viewFactory, isPartial: false);
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(partialViewName));
|
||||
}
|
||||
|
||||
var pageResult = GetRazorPageResult(context, partialViewName);
|
||||
var pageResult = GetRazorPageResult(context, partialViewName, isPartial: true);
|
||||
return CreateViewEngineResult(pageResult, _viewFactory, isPartial: true);
|
||||
}
|
||||
|
||||
|
|
@ -130,11 +130,12 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(pageName));
|
||||
}
|
||||
|
||||
return GetRazorPageResult(context, pageName);
|
||||
return GetRazorPageResult(context, pageName, isPartial: true);
|
||||
}
|
||||
|
||||
private RazorPageResult GetRazorPageResult(ActionContext context,
|
||||
string pageName)
|
||||
string pageName,
|
||||
bool isPartial)
|
||||
{
|
||||
if (IsApplicationRelativePath(pageName))
|
||||
{
|
||||
|
|
@ -154,12 +155,13 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
}
|
||||
else
|
||||
{
|
||||
return LocatePageFromViewLocations(context, pageName);
|
||||
return LocatePageFromViewLocations(context, pageName, isPartial);
|
||||
}
|
||||
}
|
||||
|
||||
private RazorPageResult LocatePageFromViewLocations(ActionContext context,
|
||||
string pageName)
|
||||
string pageName,
|
||||
bool isPartial)
|
||||
{
|
||||
// Initialize the dictionary for the typical case of having controller and action tokens.
|
||||
var routeValues = context.RouteData.Values;
|
||||
|
|
@ -169,7 +171,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
var viewLocations = !string.IsNullOrEmpty(areaName) ? AreaViewLocationFormats :
|
||||
ViewLocationFormats;
|
||||
|
||||
var expanderContext = new ViewLocationExpanderContext(context, pageName);
|
||||
var expanderContext = new ViewLocationExpanderContext(context, pageName, isPartial);
|
||||
if (_viewLocationExpanders.Count > 0)
|
||||
{
|
||||
expanderContext.Values = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
|
|
|
|||
|
|
@ -11,22 +11,35 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
/// </summary>
|
||||
public class ViewLocationExpanderContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="ViewLocationExpanderContext"/>.
|
||||
/// </summary>
|
||||
/// <param name="actionContext">The <see cref="Mvc.ActionContext"/> for the current executing action.</param>
|
||||
/// <param name="viewName">The view name.</param>
|
||||
/// <param name="isPartial">Determines if the view being discovered is a partial.</param>
|
||||
public ViewLocationExpanderContext([NotNull] ActionContext actionContext,
|
||||
[NotNull] string viewName)
|
||||
[NotNull] string viewName,
|
||||
bool isPartial)
|
||||
{
|
||||
ActionContext = actionContext;
|
||||
ViewName = viewName;
|
||||
IsPartial = isPartial;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ActionContext"/> for the current executing action.
|
||||
/// Gets the <see cref="Mvc.ActionContext"/> for the current executing action.
|
||||
/// </summary>
|
||||
public ActionContext ActionContext { get; private set; }
|
||||
public ActionContext ActionContext { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the view name
|
||||
/// Gets the view name.
|
||||
/// </summary>
|
||||
public string ViewName { get; private set; }
|
||||
public string ViewName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that determines if a partial view is being discovered.
|
||||
/// </summary>
|
||||
public bool IsPartial { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="IDictionary{TKey, TValue}"/> that is populated with values as part of
|
||||
|
|
|
|||
|
|
@ -165,6 +165,33 @@ component-content";
|
|||
Assert.Equal(expected, body.Trim());
|
||||
}
|
||||
|
||||
public static TheoryData ViewLocationExpanders_PassesInIsPartialToViewLocationExpanderContextData
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TheoryData<string, string>
|
||||
{
|
||||
{ "Index", "<expander-view><shared-views>/Shared-Views/ExpanderViews/_ExpanderPartial.cshtml</shared-views></expander-view>" },
|
||||
{ "Partial", "<shared-views>/Shared-Views/ExpanderViews/_ExpanderPartial.cshtml</shared-views>" }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(ViewLocationExpanders_PassesInIsPartialToViewLocationExpanderContextData))]
|
||||
public async Task ViewLocationExpanders_PassesInIsPartialToViewLocationExpanderContext(string action, string expected)
|
||||
{
|
||||
// Arrange
|
||||
var server = TestServer.Create(_provider, _app);
|
||||
var client = server.CreateClient();
|
||||
|
||||
// Act
|
||||
var body = await client.GetStringAsync($"http://localhost/ExpanderViews/{action}");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, body.Trim());
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> RazorViewEngine_RendersPartialViewsData
|
||||
{
|
||||
get
|
||||
|
|
|
|||
|
|
@ -15,10 +15,12 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
{
|
||||
get
|
||||
{
|
||||
yield return new[] { new ViewLocationExpanderContext(GetActionContext(), "test") };
|
||||
yield return new[] { new ViewLocationExpanderContext(GetActionContext(), "test", isPartial: false) };
|
||||
yield return new[] { new ViewLocationExpanderContext(GetActionContext(), "test", isPartial: true) };
|
||||
|
||||
var areaActionContext = GetActionContext("controller2", "myarea");
|
||||
yield return new[] { new ViewLocationExpanderContext(areaActionContext, "test2") };
|
||||
yield return new[] { new ViewLocationExpanderContext(areaActionContext, "test2", isPartial: false) };
|
||||
yield return new[] { new ViewLocationExpanderContext(areaActionContext, "test2", isPartial: true) };
|
||||
|
||||
var actionContext = GetActionContext("controller3", "area3");
|
||||
var values = new Dictionary<string, string>(StringComparer.Ordinal)
|
||||
|
|
@ -26,11 +28,16 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
{ "culture", "fr" },
|
||||
{ "theme", "sleek" }
|
||||
};
|
||||
var expanderContext = new ViewLocationExpanderContext(actionContext, "test3")
|
||||
var expanderContext = new ViewLocationExpanderContext(actionContext, "test3", isPartial: false)
|
||||
{
|
||||
Values = values
|
||||
};
|
||||
yield return new[] { expanderContext };
|
||||
|
||||
expanderContext = new ViewLocationExpanderContext(actionContext, "test3", isPartial: true)
|
||||
{
|
||||
Values = values
|
||||
};
|
||||
yield return new[] { expanderContext };
|
||||
}
|
||||
}
|
||||
|
|
@ -71,15 +78,26 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
{
|
||||
yield return new object[]
|
||||
{
|
||||
new ViewLocationExpanderContext(GetActionContext(), "test"),
|
||||
"test:mycontroller"
|
||||
new ViewLocationExpanderContext(GetActionContext(), "test", isPartial: false),
|
||||
"test:0:mycontroller"
|
||||
};
|
||||
|
||||
yield return new object[]
|
||||
{
|
||||
new ViewLocationExpanderContext(GetActionContext(), "test", isPartial: true),
|
||||
"test:1:mycontroller"
|
||||
};
|
||||
|
||||
var areaActionContext = GetActionContext("controller2", "myarea");
|
||||
yield return new object[]
|
||||
{
|
||||
new ViewLocationExpanderContext(areaActionContext, "test2"),
|
||||
"test2:controller2:myarea"
|
||||
new ViewLocationExpanderContext(areaActionContext, "test2", isPartial: false),
|
||||
"test2:0:controller2:myarea"
|
||||
};
|
||||
yield return new object[]
|
||||
{
|
||||
new ViewLocationExpanderContext(areaActionContext, "test2", isPartial: true),
|
||||
"test2:1:controller2:myarea"
|
||||
};
|
||||
|
||||
var actionContext = GetActionContext("controller3", "area3");
|
||||
|
|
@ -88,7 +106,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
{ "culture", "fr" },
|
||||
{ "theme", "sleek" }
|
||||
};
|
||||
var expanderContext = new ViewLocationExpanderContext(actionContext, "test3")
|
||||
var expanderContext = new ViewLocationExpanderContext(actionContext, "test3", isPartial: false)
|
||||
{
|
||||
Values = values
|
||||
};
|
||||
|
|
@ -96,7 +114,17 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
yield return new object[]
|
||||
{
|
||||
expanderContext,
|
||||
"test3:controller3:area3:culture:fr:theme:sleek"
|
||||
"test3:0:controller3:area3:culture:fr:theme:sleek"
|
||||
};
|
||||
|
||||
expanderContext = new ViewLocationExpanderContext(actionContext, "test3", isPartial: true)
|
||||
{
|
||||
Values = values
|
||||
};
|
||||
yield return new object[]
|
||||
{
|
||||
expanderContext,
|
||||
"test3:1:controller3:area3:culture:fr:theme:sleek"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace RazorWebSite.Controllers
|
||||
{
|
||||
public class ExpanderViewsController : Controller
|
||||
{
|
||||
// This result discovers the Index.cshtml from /View but the partial is executed from /Shared-Views
|
||||
public ViewResult Index()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
public PartialViewResult Partial()
|
||||
{
|
||||
return PartialView("_ExpanderPartial");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNet.Mvc.Razor;
|
||||
|
||||
namespace RazorWebSite
|
||||
{
|
||||
public class CustomPartialDirectoryViewLocationExpander : IViewLocationExpander
|
||||
{
|
||||
public void PopulateValues(ViewLocationExpanderContext context)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context,
|
||||
IEnumerable<string> viewLocations)
|
||||
{
|
||||
if (context.IsPartial)
|
||||
{
|
||||
return ExpandViewLocationsCore(viewLocations);
|
||||
}
|
||||
|
||||
return viewLocations;
|
||||
}
|
||||
|
||||
private IEnumerable<string> ExpandViewLocationsCore(IEnumerable<string> viewLocations)
|
||||
{
|
||||
foreach (var location in viewLocations)
|
||||
{
|
||||
yield return "/Shared-Views/{1}/{0}.cshtml";
|
||||
yield return location;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
@{
|
||||
throw new Exception("This view should not be executed");
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
<shared-views>@ViewContext.View.Path</shared-views>
|
||||
|
|
@ -27,6 +27,7 @@ namespace RazorWebSite
|
|||
var expander = new LanguageViewLocationExpander(
|
||||
context => context.HttpContext.Request.Query["language-expander-value"]);
|
||||
options.ViewLocationExpanders.Add(expander);
|
||||
options.ViewLocationExpanders.Add(new CustomPartialDirectoryViewLocationExpander());
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
<expander-view>@Html.Partial("_ExpanderPartial")</expander-view>
|
||||
Loading…
Reference in New Issue