diff --git a/samples/MvcSample.Web/Components/TagCloud.cs b/samples/MvcSample.Web/Components/TagCloud.cs index c6a214a5a9..5d9803addc 100644 --- a/samples/MvcSample.Web/Components/TagCloud.cs +++ b/samples/MvcSample.Web/Components/TagCloud.cs @@ -17,9 +17,19 @@ namespace MvcSample.Web.Components .OrderBy(s => Guid.NewGuid().ToString()) .ToArray(); - public async Task InvokeAsync(int count) + public async Task InvokeAsync(int count, string returnAs) { var tags = await GetTagsAsync(count); + + if (returnAs.Equals("Content", StringComparison.OrdinalIgnoreCase)) + { + return Content(string.Join(", ", tags)); + } + if (returnAs.Equals("Json", StringComparison.OrdinalIgnoreCase)) + { + return Json(tags); + } + return View(tags); } diff --git a/samples/MvcSample.Web/Views/Shared/MyView.cshtml b/samples/MvcSample.Web/Views/Shared/MyView.cshtml index d3662dbdf8..18ae092b23 100644 --- a/samples/MvcSample.Web/Views/Shared/MyView.cshtml +++ b/samples/MvcSample.Web/Views/Shared/MyView.cshtml @@ -146,7 +146,12 @@
- @await Component.InvokeAsync("Tags", 15) +

Tags from View():

+ @await Component.InvokeAsync("Tags", 5, "View") +

Tags from Content():

+

@await Component.InvokeAsync("Tags", 5, "Content")

+

Tags from Json():

+

@await Component.InvokeAsync("Tags", 5, "Json")

'@ViewBag.Title' should match page heading (still)

diff --git a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/DefaultViewComponentResultHelper.cs b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/DefaultViewComponentResultHelper.cs index 5ba316e75d..4fde664ca3 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/DefaultViewComponentResultHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/DefaultViewComponentResultHelper.cs @@ -14,17 +14,17 @@ namespace Microsoft.AspNet.Mvc _viewEngine = viewEngine; } - public IViewComponentResult Content([NotNull] string content) + public virtual ContentViewComponentResult Content([NotNull] string content) { return new ContentViewComponentResult(content); } - public IViewComponentResult Json([NotNull] object value) + public virtual JsonViewComponentResult Json([NotNull] object value) { return new JsonViewComponentResult(value); } - public IViewComponentResult View([NotNull] string viewName, [NotNull] ViewDataDictionary viewData) + public virtual ViewViewComponentResult View([NotNull] string viewName, [NotNull] ViewDataDictionary viewData) { return new ViewViewComponentResult(_viewEngine, viewName, viewData); } diff --git a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/IViewComponentResultHelper.cs b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/IViewComponentResultHelper.cs index fc4569bc45..5be2e44f5e 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/IViewComponentResultHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/IViewComponentResultHelper.cs @@ -7,10 +7,10 @@ namespace Microsoft.AspNet.Mvc { public interface IViewComponentResultHelper { - IViewComponentResult Content([NotNull] string content); + ContentViewComponentResult Content([NotNull] string content); - IViewComponentResult Json([NotNull] object value); + JsonViewComponentResult Json([NotNull] object value); - IViewComponentResult View([NotNull] string viewName, [NotNull] ViewDataDictionary viewData); + ViewViewComponentResult View([NotNull] string viewName, [NotNull] ViewDataDictionary viewData); } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewComponent.cs b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewComponent.cs index 734ab88e12..3504f51efd 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewComponent.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewComponent.cs @@ -35,27 +35,37 @@ namespace Microsoft.AspNet.Mvc public ViewDataDictionary ViewData { get; set; } + public ContentViewComponentResult Content(string content) + { + return Result.Content(content); + } + public void Initialize(IViewComponentResultHelper result) { Result = result; } - public IViewComponentResult View() + public JsonViewComponentResult Json(object value) + { + return Result.Json(value); + } + + public ViewViewComponentResult View() { return View(null, null); } - public IViewComponentResult View(string viewName) + public ViewViewComponentResult View(string viewName) { return View(viewName, null); } - public IViewComponentResult View(TModel model) + public ViewViewComponentResult View(TModel model) { return View(null, model); } - public IViewComponentResult View(string viewName, TModel model) + public ViewViewComponentResult View(string viewName, TModel model) { var viewData = new ViewDataDictionary(ViewData); if (model != null) diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj b/test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj index 54aa5c4496..088dc97262 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj @@ -54,6 +54,7 @@ + - \ No newline at end of file + diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponentTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponentTests.cs new file mode 100644 index 0000000000..f18ee36211 --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponentTests.cs @@ -0,0 +1,196 @@ +// 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 System.IO; +using System.Reflection; +using System.Threading.Tasks; +using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Mvc.Rendering; +using Moq; +using Xunit; + +namespace Microsoft.AspNet.Mvc +{ + public class ViewComponentTests + { + [Fact] + public void ViewComponent_ViewBag_UsesViewData() + { + // Arrange + var viewComponent = new TestViewComponent() + { + ViewData = new ViewDataDictionary(metadataProvider: null), + }; + + // Act + viewComponent.ViewBag.A = "Alice"; + viewComponent.ViewBag.B = "Bob"; + + // Assert + Assert.Equal(2, viewComponent.ViewData.Count); + Assert.Equal("Alice", viewComponent.ViewData["A"]); + Assert.Equal("Bob", viewComponent.ViewData["B"]); + } + + [Fact] + public void ViewComponent_ViewData_StoresDataForViewBag() + { + // Arrange + var viewComponent = new TestViewComponent() + { + ViewData = new ViewDataDictionary(metadataProvider: null), + }; + + // Act + viewComponent.ViewData["A"] = "Alice"; + viewComponent.ViewData["B"] = "Bob"; + + // Assert + Assert.Equal(2, viewComponent.ViewData.Count); + Assert.Equal("Alice", viewComponent.ViewBag.A); + Assert.Equal("Bob", viewComponent.ViewBag.B); + } + + [Fact] + public void ViewComponent_Content_CallsResultContentWithTestContent() + { + // Arrange + var viewComponent = new TestViewComponent(); + var resultHelperMock = new Mock(It.IsAny()); + var resultMock = new Mock("TestContent"); + resultHelperMock.Setup(r => r.Content(It.IsAny())) + .Returns(resultMock.Object); + viewComponent.Initialize(resultHelperMock.Object); + + // Act + var actualResult = viewComponent.Content("TestContent"); + + // Assert + resultHelperMock.Verify(r => r.Content("TestContent")); + Assert.Same(resultMock.Object, actualResult); + } + + [Fact] + public void ViewComponent_Json_CallsResultJsonWithTestValue() + { + // Arrange + var viewComponent = new TestViewComponent(); + var resultHelperMock = new Mock(It.IsAny()); + var resultMock = new Mock(It.IsAny()); + resultHelperMock.Setup(r => r.Json(It.IsAny())) + .Returns(resultMock.Object); + viewComponent.Initialize(resultHelperMock.Object); + var testValue = new object(); + + // Act + var actualResult = viewComponent.Json(testValue); + + // Assert + resultHelperMock.Verify(r => r.Json(testValue)); + Assert.Same(resultMock.Object, actualResult); + } + + [Fact] + public void ViewComponent_View_WithEmptyParameter_CallsResultViewWithDefaultViewName() + { + // Arrange + var viewComponent = new TestViewComponent() + { + ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()), + }; + var resultHelperMock = new Mock(It.IsAny()); + var resultMock = new Mock(It.IsAny(), + It.IsAny(), + It.IsAny()); + resultHelperMock.Setup(r => r.View(It.IsAny(), It.IsAny())) + .Returns(resultMock.Object); + viewComponent.Initialize(resultHelperMock.Object); + + // Act + var actualResult = viewComponent.View(); + + // Assert + resultHelperMock.Verify(r => r.View("Default", viewComponent.ViewData)); + Assert.Same(resultMock.Object, actualResult); + } + + [Fact] + public void ViewComponent_View_WithViewNameParameter_CallsResultViewWithCustomViewName() + { + // Arrange + var viewComponent = new TestViewComponent() + { + ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()), + }; + var resultHelperMock = new Mock(It.IsAny()); + var resultMock = new Mock(It.IsAny(), + It.IsAny(), + It.IsAny()); + resultHelperMock.Setup(r => r.View(It.IsAny(), It.IsAny())) + .Returns(resultMock.Object); + viewComponent.Initialize(resultHelperMock.Object); + + // Act + var actualResult = viewComponent.View("CustomViewName"); + + // Assert + resultHelperMock.Verify(r => r.View("CustomViewName", viewComponent.ViewData)); + Assert.Same(resultMock.Object, actualResult); + } + + [Fact] + public void ViewComponent_View_WithModelParameter_CallsResultViewWithDefaultViewNameAndModel() + { + // Arrange + var viewComponent = new TestViewComponent() + { + ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()), + }; + var resultHelperMock = new Mock(It.IsAny()); + var resultMock = new Mock(It.IsAny(), + It.IsAny(), + It.IsAny()); + resultHelperMock.Setup(r => r.View(It.IsAny(), It.IsAny())) + .Returns(resultMock.Object); + viewComponent.Initialize(resultHelperMock.Object); + var model = new object(); + + // Act + var actualResult = viewComponent.View(model); + + // Assert + resultHelperMock.Verify(r => r.View("Default", viewComponent.ViewData)); + Assert.Same(resultMock.Object, actualResult); + } + + [Fact] + public void ViewComponent_View_WithViewNameAndModelParameters_CallsResultViewWithCustomViewNameAndModel() + { + // Arrange + var viewComponent = new TestViewComponent() + { + ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()), + }; + var resultHelperMock = new Mock(It.IsAny()); + var resultMock = new Mock(It.IsAny(), + It.IsAny(), + It.IsAny()); + resultHelperMock.Setup(r => r.View(It.IsAny(), It.IsAny())) + .Returns(resultMock.Object); + viewComponent.Initialize(resultHelperMock.Object); + var model = new object(); + + // Act + var actualResult = viewComponent.View("CustomViewName", model); + + // Assert + resultHelperMock.Verify(r => r.View("CustomViewName", viewComponent.ViewData)); + Assert.Same(resultMock.Object, actualResult); + } + + private class TestViewComponent : ViewComponent + { + } + } +}