Fix for #215 - nullref trying to generate link in a partial
The fix here is to do some cleanup we've been planning to do for a while, rather than flowing IUrlHelper and IComponentHelper as part of the ViewContext, they now are just grabbed from the service provider. This simplifies the code for invoking a view, and gets us closer to the desired API surface of ViewContext
This commit is contained in:
parent
749789c486
commit
ab605ef935
|
|
@ -1,4 +1,6 @@
|
|||
@using MvcSample.Web.Models
|
||||
@model User
|
||||
|
||||
<strong>Hello @Model.Name from Partial</strong>
|
||||
<strong>Hello @Model.Name from Partial</strong>
|
||||
|
||||
<a href="@Url.Action("Edit", "Home")">Edit Something!</a>
|
||||
|
|
@ -51,16 +51,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
var viewContext = new ViewContext(_serviceProvider, actionContext.HttpContext, actionContext.RouteValues)
|
||||
{
|
||||
Url = urlHelper,
|
||||
ViewData = ViewData,
|
||||
Writer = writer,
|
||||
};
|
||||
|
||||
viewContext.Component = new DefaultViewComponentHelper(
|
||||
_serviceProvider.GetService<IViewComponentSelector>(),
|
||||
_serviceProvider.GetService<IViewComponentInvokerFactory>(),
|
||||
viewContext);
|
||||
|
||||
return viewContext;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,16 +28,23 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
|
||||
private const string HiddenListItem = @"<li style=""display:none""></li>";
|
||||
|
||||
private readonly IUrlHelper _urlHelper;
|
||||
private readonly IViewEngine _viewEngine;
|
||||
|
||||
private ViewContext _viewContext;
|
||||
private IViewEngine _viewEngine;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HtmlHelper"/> class.
|
||||
/// </summary>
|
||||
public HtmlHelper([NotNull] IViewEngine viewEngine, [NotNull] IModelMetadataProvider metadataProvider)
|
||||
public HtmlHelper(
|
||||
[NotNull] IViewEngine viewEngine,
|
||||
[NotNull] IModelMetadataProvider metadataProvider,
|
||||
[NotNull] IUrlHelper urlHelper)
|
||||
{
|
||||
_viewEngine = viewEngine;
|
||||
MetadataProvider = metadataProvider;
|
||||
_urlHelper = urlHelper;
|
||||
|
||||
// Underscores are fine characters in id's.
|
||||
IdAttributeDotReplacement = "_";
|
||||
|
|
@ -445,8 +452,7 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
protected virtual MvcForm GenerateForm(string actionName, string controllerName, object routeValues,
|
||||
FormMethod method, IDictionary<string, object> htmlAttributes)
|
||||
{
|
||||
var urlHelper = ViewContext.Url;
|
||||
var formAction = urlHelper.Action(action: actionName, controller: controllerName, values: routeValues);
|
||||
var formAction = _urlHelper.Action(action: actionName, controller: controllerName, values: routeValues);
|
||||
|
||||
var tagBuilder = new TagBuilder("form");
|
||||
tagBuilder.MergeAttributes(htmlAttributes);
|
||||
|
|
|
|||
|
|
@ -13,8 +13,11 @@ namespace Microsoft.AspNet.Mvc.Rendering
|
|||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HtmlHelper{TModel}"/> class.
|
||||
/// </summary>
|
||||
public HtmlHelper([NotNull] IViewEngine viewEngine, [NotNull] IModelMetadataProvider metadataProvider)
|
||||
: base(viewEngine, metadataProvider)
|
||||
public HtmlHelper(
|
||||
[NotNull] IViewEngine viewEngine,
|
||||
[NotNull] IModelMetadataProvider metadataProvider,
|
||||
[NotNull] IUrlHelper urlHelper)
|
||||
: base(viewEngine, metadataProvider, urlHelper)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,19 +8,22 @@ using Microsoft.AspNet.Mvc.Rendering;
|
|||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public class DefaultViewComponentHelper : IViewComponentHelper
|
||||
public class DefaultViewComponentHelper : IViewComponentHelper, ICanHasViewContext
|
||||
{
|
||||
private readonly IViewComponentInvokerFactory _invokerFactory;
|
||||
private readonly IViewComponentSelector _selector;
|
||||
private readonly ViewContext _viewContext;
|
||||
private ViewContext _viewContext;
|
||||
|
||||
public DefaultViewComponentHelper(
|
||||
[NotNull] IViewComponentSelector selector,
|
||||
[NotNull] IViewComponentInvokerFactory invokerFactory,
|
||||
[NotNull] ViewContext viewContext)
|
||||
[NotNull] IViewComponentInvokerFactory invokerFactory)
|
||||
{
|
||||
_selector = selector;
|
||||
_invokerFactory = invokerFactory;
|
||||
}
|
||||
|
||||
public void Contextualize([NotNull] ViewContext viewContext)
|
||||
{
|
||||
_viewContext = viewContext;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,8 +36,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
context.ViewContext.HttpContext,
|
||||
context.ViewContext.ViewEngineContext)
|
||||
{
|
||||
Component = context.ViewContext.Component,
|
||||
Url = context.ViewContext.Url,
|
||||
ViewData = _viewData ?? context.ViewContext.ViewData,
|
||||
Writer = context.Writer,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
ClientValidationEnabled = true;
|
||||
}
|
||||
|
||||
public IViewComponentHelper Component { get; set; }
|
||||
|
||||
public virtual FormContext FormContext
|
||||
{
|
||||
get
|
||||
|
|
@ -52,8 +50,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
public IServiceProvider ServiceProvider { get; private set; }
|
||||
|
||||
public IUrlHelper Url { get; set; }
|
||||
|
||||
public bool UnobtrusiveJavaScriptEnabled { get; set; }
|
||||
|
||||
public bool ClientValidationEnabled { get; set; }
|
||||
|
|
|
|||
|
|
@ -15,21 +15,13 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
private readonly HashSet<string> _renderedSections = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
private bool _renderedBody;
|
||||
|
||||
public IViewComponentHelper Component
|
||||
{
|
||||
get { return Context == null ? null : Context.Component; }
|
||||
}
|
||||
|
||||
public ViewContext Context { get; set; }
|
||||
|
||||
public string Layout { get; set; }
|
||||
|
||||
protected TextWriter Output { get; set; }
|
||||
|
||||
public IUrlHelper Url
|
||||
{
|
||||
get { return Context == null ? null : Context.Url; }
|
||||
}
|
||||
public IUrlHelper Url { get; private set; }
|
||||
|
||||
public dynamic ViewBag
|
||||
{
|
||||
|
|
@ -50,6 +42,8 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
SectionWriters = new Dictionary<string, HelperResult>(StringComparer.OrdinalIgnoreCase);
|
||||
Context = context;
|
||||
|
||||
Url = context.ServiceProvider.GetService<IUrlHelper>();
|
||||
|
||||
var contentBuilder = new StringBuilder(1024);
|
||||
using (var bodyWriter = new StringWriter(contentBuilder))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
|
||||
public ViewDataDictionary<TModel> ViewData { get; private set; }
|
||||
|
||||
public IViewComponentHelper Component { get; private set; }
|
||||
|
||||
public IHtmlHelper<TModel> Html { get; set; }
|
||||
|
||||
public override Task RenderAsync([NotNull] ViewContext context)
|
||||
|
|
@ -53,6 +55,14 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
{
|
||||
contextable.Contextualize(context);
|
||||
}
|
||||
|
||||
Component = context.ServiceProvider.GetService<IViewComponentHelper>();
|
||||
|
||||
contextable = Component as ICanHasViewContext;
|
||||
if (contextable != null)
|
||||
{
|
||||
contextable.Contextualize(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
yield return describe.Transient<IViewComponentInvokerFactory, DefaultViewComponentInvokerFactory>();
|
||||
yield return describe.Transient<INestedProvider<ViewComponentInvokerProviderContext>, DefaultViewComponentInvokerProvider>();
|
||||
yield return describe.Transient<IViewComponentResultHelper, DefaultViewComponentResultHelper>();
|
||||
yield return describe.Transient<IViewComponentHelper, DefaultViewComponentHelper>();
|
||||
|
||||
yield return
|
||||
describe.Describe(
|
||||
|
|
|
|||
Loading…
Reference in New Issue