From c61cc65db3f53fc6bb01179bce5a3792ef4e04ab Mon Sep 17 00:00:00 2001 From: javiercn Date: Tue, 15 Dec 2015 12:20:06 -0800 Subject: [PATCH] [Fixes #3705] Bring back render partial --- .../Rendering/HtmlHelperPartialExtensions.cs | 88 +++++++++++++++++++ .../HtmlHelperPartialExtensionsTest.cs | 73 +++++++++++++++ 2 files changed, 161 insertions(+) diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/Rendering/HtmlHelperPartialExtensions.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/Rendering/HtmlHelperPartialExtensions.cs index 3871618a4b..7fedb6e218 100644 --- a/src/Microsoft.AspNet.Mvc.ViewFeatures/Rendering/HtmlHelperPartialExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/Rendering/HtmlHelperPartialExtensions.cs @@ -234,6 +234,94 @@ namespace Microsoft.AspNet.Mvc.Rendering return result.GetAwaiter().GetResult(); } + /// + /// Renders HTML markup for the specified partial view. + /// + /// The instance this method extends. + /// + /// The name of the partial view used to create the HTML markup. Must not be null. + /// + /// + /// In this context, "renders" means the method writes its output using . + /// + public static void RenderPartial( + this IHtmlHelper htmlHelper, + string partialViewName) + { + if (htmlHelper == null) + { + throw new ArgumentNullException(nameof(htmlHelper)); + } + + if (partialViewName == null) + { + throw new ArgumentNullException(nameof(partialViewName)); + } + + var result = htmlHelper.RenderPartialAsync(partialViewName, htmlHelper.ViewData.Model, viewData: null); + result.GetAwaiter().GetResult(); + } + + /// + /// Renders HTML markup for the specified partial view. + /// + /// The instance this method extends. + /// + /// The name of the partial view used to create the HTML markup. Must not be null. + /// + /// A to pass into the partial view. + /// + /// In this context, "renders" means the method writes its output using . + /// + public static void RenderPartial( + this IHtmlHelper htmlHelper, + string partialViewName, + ViewDataDictionary viewData) + { + if (htmlHelper == null) + { + throw new ArgumentNullException(nameof(htmlHelper)); + } + + if (partialViewName == null) + { + throw new ArgumentNullException(nameof(partialViewName)); + } + + var result = htmlHelper.RenderPartialAsync(partialViewName, htmlHelper.ViewData.Model, viewData); + result.GetAwaiter().GetResult(); + } + + /// + /// Renders HTML markup for the specified partial view. + /// + /// The instance this method extends. + /// + /// The name of the partial view used to create the HTML markup. Must not be null. + /// + /// A model to pass into the partial view. + /// + /// In this context, "renders" means the method writes its output using . + /// + public static void RenderPartial( + this IHtmlHelper htmlHelper, + string partialViewName, + object model) + { + if (htmlHelper == null) + { + throw new ArgumentNullException(nameof(htmlHelper)); + } + + if (partialViewName == null) + { + throw new ArgumentNullException(nameof(partialViewName)); + } + + var result = htmlHelper.RenderPartialAsync(partialViewName, model, viewData: null); + result.GetAwaiter().GetResult(); + } + /// /// Renders HTML markup for the specified partial view. /// diff --git a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Rendering/HtmlHelperPartialExtensionsTest.cs b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Rendering/HtmlHelperPartialExtensionsTest.cs index f1c974a4be..c35cc434e6 100644 --- a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Rendering/HtmlHelperPartialExtensionsTest.cs +++ b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Rendering/HtmlHelperPartialExtensionsTest.cs @@ -140,6 +140,79 @@ namespace Microsoft.AspNet.Mvc.Rendering helper.VerifyAll(); } + // Func, expected Model, expected ViewDataDictionary + public static TheoryData, object, ViewDataDictionary> RenderPartialExtensionMethods + { + get + { + var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider()); + var model = new object(); + return new TheoryData, object, ViewDataDictionary> + { + { helper => helper.RenderPartial("test"), null, null }, + { helper => helper.RenderPartial("test", model), model, null }, + { helper => helper.RenderPartial("test", viewData), null, viewData }, + }; + } + } + + [Theory] + [MemberData(nameof(RenderPartialExtensionMethods))] + public void RenderPartialMethods_DoesNotWrapThrownException( + Action partialMethod, + object unusedModel, + ViewDataDictionary unusedViewData) + { + // Arrange + var expected = new InvalidOperationException(); + var helper = new Mock(); + helper.Setup(h => h.RenderPartialAsync("test", It.IsAny(), It.IsAny())) + .Callback(() => + { + // Workaround for compilation issue with Moq. + helper.ToString(); + throw expected; + }); + helper.SetupGet(h => h.ViewData) + .Returns(new ViewDataDictionary(new EmptyModelMetadataProvider())); + + // Act and Assert + var actual = Assert.Throws(() => partialMethod(helper.Object)); + Assert.Same(expected, actual); + } + + [Theory] + [MemberData(nameof(RenderPartialAsyncExtensionMethods))] + public async Task RenderPartialMethods_CallHtmlHelperWithExpectedArguments( + Func renderPartialAsyncMethod, + object expectedModel, + ViewDataDictionary expectedViewData) + { + // Arrange + var htmlContent = Mock.Of(); + var helper = new Mock(MockBehavior.Strict); + if (expectedModel == null) + { + // Extension methods without model parameter use ViewData.Model to get Model. + var viewData = expectedViewData ?? new ViewDataDictionary(new EmptyModelMetadataProvider()); + helper + .SetupGet(h => h.ViewData) + .Returns(viewData) + .Verifiable(); + } + + helper + .Setup(h => h.RenderPartialAsync("test", expectedModel, expectedViewData)) + .Returns(Task.FromResult(true)) + .Verifiable(); + + // Act + await renderPartialAsyncMethod(helper.Object); + + // Assert + helper.VerifyAll(); + } + // Func, expected Model, expected ViewDataDictionary public static TheoryData, object, ViewDataDictionary> RenderPartialAsyncExtensionMethods {