diff --git a/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj b/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj index a4fccb3e05..49e0486a3d 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj +++ b/src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj @@ -212,14 +212,12 @@ - - diff --git a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ContentViewComponentResult.cs b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ContentViewComponentResult.cs index 3e3db73163..4b2efddf57 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ContentViewComponentResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ContentViewComponentResult.cs @@ -9,26 +9,30 @@ namespace Microsoft.AspNet.Mvc { public class ContentViewComponentResult : IViewComponentResult { - private readonly HtmlString _encoded; - public ContentViewComponentResult([NotNull] string content) { - _encoded = new HtmlString(WebUtility.HtmlEncode(content)); + Content = content; + EncodedContent = new HtmlString(WebUtility.HtmlEncode(content)); } - public ContentViewComponentResult([NotNull] HtmlString encoded) + public ContentViewComponentResult([NotNull] HtmlString encodedContent) { - _encoded = encoded; + EncodedContent = encodedContent; + Content = WebUtility.HtmlDecode(encodedContent.ToString()); } + public string Content { get; private set; } + + public HtmlString EncodedContent { get; private set; } + public void Execute([NotNull] ViewComponentContext context) { - context.Writer.Write(_encoded.ToString()); + context.Writer.Write(EncodedContent.ToString()); } public async Task ExecuteAsync([NotNull] ViewComponentContext context) { - await context.Writer.WriteAsync(_encoded.ToString()); + await context.Writer.WriteAsync(EncodedContent.ToString()); } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/DefaultViewComponentResultHelper.cs b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/DefaultViewComponentResultHelper.cs deleted file mode 100644 index 4fde664ca3..0000000000 --- a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/DefaultViewComponentResultHelper.cs +++ /dev/null @@ -1,32 +0,0 @@ -// 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.Rendering; - -namespace Microsoft.AspNet.Mvc -{ - public class DefaultViewComponentResultHelper : IViewComponentResultHelper - { - private readonly IViewEngine _viewEngine; - - public DefaultViewComponentResultHelper(IViewEngine viewEngine) - { - _viewEngine = viewEngine; - } - - public virtual ContentViewComponentResult Content([NotNull] string content) - { - return new ContentViewComponentResult(content); - } - - public virtual JsonViewComponentResult Json([NotNull] object value) - { - return new JsonViewComponentResult(value); - } - - 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 deleted file mode 100644 index 5be2e44f5e..0000000000 --- a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/IViewComponentResultHelper.cs +++ /dev/null @@ -1,16 +0,0 @@ -// 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.Rendering; - -namespace Microsoft.AspNet.Mvc -{ - public interface IViewComponentResultHelper - { - ContentViewComponentResult Content([NotNull] string content); - - JsonViewComponentResult Json([NotNull] object value); - - ViewViewComponentResult View([NotNull] string viewName, [NotNull] ViewDataDictionary viewData); - } -} diff --git a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/JsonViewComponentResult.cs b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/JsonViewComponentResult.cs index 50159d9573..143c5c45be 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/JsonViewComponentResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/JsonViewComponentResult.cs @@ -9,16 +9,16 @@ namespace Microsoft.AspNet.Mvc { public class JsonViewComponentResult : IViewComponentResult { - private readonly object _value; - private JsonSerializerSettings _jsonSerializerSettings; - public JsonViewComponentResult([NotNull] object value) + public JsonViewComponentResult([NotNull] object data) { - _value = value; + Data = data; _jsonSerializerSettings = JsonOutputFormatter.CreateDefaultSettings(); } + public object Data { get; private set; } + public JsonSerializerSettings SerializerSettings { get { return _jsonSerializerSettings; } @@ -42,7 +42,7 @@ namespace Microsoft.AspNet.Mvc public void Execute([NotNull] ViewComponentContext context) { var formatter = new JsonOutputFormatter(SerializerSettings, Indent); - formatter.WriteObject(context.Writer, _value); + formatter.WriteObject(context.Writer, Data); } #pragma warning disable 1998 diff --git a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewComponent.cs b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewComponent.cs index 3504f51efd..e6de823b01 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewComponent.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewComponent.cs @@ -10,14 +10,13 @@ namespace Microsoft.AspNet.Mvc public abstract class ViewComponent { private dynamic _viewBag; + private IViewEngine _viewEngine; public HttpContext Context { get { return ViewContext == null ? null : ViewContext.HttpContext; } } - public IViewComponentResultHelper Result { get; private set; } - public dynamic ViewBag { get @@ -35,19 +34,19 @@ namespace Microsoft.AspNet.Mvc public ViewDataDictionary ViewData { get; set; } - public ContentViewComponentResult Content(string content) + public ContentViewComponentResult Content([NotNull] string content) { - return Result.Content(content); + return new ContentViewComponentResult(content); } - public void Initialize(IViewComponentResultHelper result) + public void Initialize(IViewEngine viewEngine) { - Result = result; + _viewEngine = viewEngine; } - public JsonViewComponentResult Json(object value) + public JsonViewComponentResult Json([NotNull] object value) { - return Result.Json(value); + return new JsonViewComponentResult(value); } public ViewViewComponentResult View() @@ -73,7 +72,7 @@ namespace Microsoft.AspNet.Mvc viewData.Model = model; } - return Result.View(viewName ?? "Default", viewData); + return new ViewViewComponentResult(_viewEngine, viewName, viewData); } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewViewComponentResult.cs b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewViewComponentResult.cs index 0001eb01ea..48a4ff575d 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewViewComponentResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewViewComponentResult.cs @@ -14,19 +14,20 @@ namespace Microsoft.AspNet.Mvc { // {0} is the component name, {1} is the view name. private const string ViewPathFormat = "Components/{0}/{1}"; - private readonly IViewEngine _viewEngine; - private readonly string _viewName; - private readonly ViewDataDictionary _viewData; - public ViewViewComponentResult([NotNull] IViewEngine viewEngine, [NotNull] string viewName, + public ViewViewComponentResult([NotNull] IViewEngine viewEngine, string viewName, ViewDataDictionary viewData) { _viewEngine = viewEngine; - _viewName = viewName; - _viewData = viewData; + ViewName = viewName; + ViewData = viewData; } + public string ViewName { get; private set; } + + public ViewDataDictionary ViewData { get; private set; } + public void Execute([NotNull] ViewComponentContext context) { throw new NotImplementedException("There's no support for syncronous views right now."); @@ -35,10 +36,10 @@ namespace Microsoft.AspNet.Mvc public async Task ExecuteAsync([NotNull] ViewComponentContext context) { string qualifiedViewName; - if (_viewName.Length > 0 && _viewName[0] == '/') + if (ViewName != null && ViewName.Length > 0 && ViewName[0] == '/') { // View name that was passed in is already a rooted path, the view engine will handle this. - qualifiedViewName = _viewName; + qualifiedViewName = ViewName; } else { @@ -57,7 +58,7 @@ namespace Microsoft.AspNet.Mvc CultureInfo.InvariantCulture, ViewPathFormat, ViewComponentConventions.GetComponentName(context.ComponentType), - _viewName); + ViewName ?? "Default"); } var view = FindView(context.ViewContext.RouteData.Values, qualifiedViewName); @@ -65,7 +66,7 @@ namespace Microsoft.AspNet.Mvc var childViewContext = new ViewContext( context.ViewContext, view, - _viewData ?? context.ViewContext.ViewData, + ViewData ?? context.ViewContext.ViewData, context.Writer); using (view as IDisposable) diff --git a/src/Microsoft.AspNet.Mvc/MvcServices.cs b/src/Microsoft.AspNet.Mvc/MvcServices.cs index 25b145e44f..4c8b671034 100644 --- a/src/Microsoft.AspNet.Mvc/MvcServices.cs +++ b/src/Microsoft.AspNet.Mvc/MvcServices.cs @@ -77,7 +77,6 @@ namespace Microsoft.AspNet.Mvc yield return describe.Transient(); yield return describe.Transient, DefaultViewComponentInvokerProvider>(); - yield return describe.Transient(); yield return describe.Transient(); yield return describe.Transient(); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponentTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponentTests.cs index f18ee36211..9cbb7b14a6 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponentTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponentTests.cs @@ -1,13 +1,9 @@ // 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 System.Net; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.Rendering; -using Moq; using Xunit; namespace Microsoft.AspNet.Mvc @@ -53,140 +49,120 @@ namespace Microsoft.AspNet.Mvc } [Fact] - public void ViewComponent_Content_CallsResultContentWithTestContent() + public void ViewComponent_Content_SetsResultContentAndEncodedContent() { // 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); + var expectedContent = "TestContent&"; + var expectedEncodedContent = new HtmlString(WebUtility.HtmlEncode(expectedContent)); // Act - var actualResult = viewComponent.Content("TestContent"); + var actualResult = viewComponent.Content(expectedContent); // Assert - resultHelperMock.Verify(r => r.Content("TestContent")); - Assert.Same(resultMock.Object, actualResult); + Assert.IsType(actualResult); + Assert.Same(expectedContent, actualResult.Content); + Assert.Equal(expectedEncodedContent.ToString(), actualResult.EncodedContent.ToString()); } [Fact] - public void ViewComponent_Json_CallsResultJsonWithTestValue() + public void ViewComponent_Json_SetsResultData() { // 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(); + var testData = new object(); // Act - var actualResult = viewComponent.Json(testValue); + var actualResult = viewComponent.Json(testData); // Assert - resultHelperMock.Verify(r => r.Json(testValue)); - Assert.Same(resultMock.Object, actualResult); + Assert.IsType(actualResult); + Assert.Same(testData, actualResult.Data); } [Fact] - public void ViewComponent_View_WithEmptyParameter_CallsResultViewWithDefaultViewName() + public void ViewComponent_View_WithEmptyParameter_SetsResultViewWithDefaultViewName() { // 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); + Assert.IsType(actualResult); + Assert.NotSame(viewComponent.ViewData, actualResult.ViewData); + Assert.Equal(new ViewDataDictionary(viewComponent.ViewData), actualResult.ViewData); + Assert.Null(actualResult.ViewData.Model); + Assert.Null(actualResult.ViewName); } [Fact] - public void ViewComponent_View_WithViewNameParameter_CallsResultViewWithCustomViewName() + public void ViewComponent_View_WithViewNameParameter_SetsResultViewWithCustomViewName() { // 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); + Assert.IsType(actualResult); + Assert.IsType>(actualResult.ViewData); + Assert.NotSame(viewComponent.ViewData, actualResult.ViewData); + Assert.Equal(new ViewDataDictionary(viewComponent.ViewData), actualResult.ViewData); + Assert.Null(actualResult.ViewData.Model); + Assert.Equal("CustomViewName", actualResult.ViewName); } [Fact] - public void ViewComponent_View_WithModelParameter_CallsResultViewWithDefaultViewNameAndModel() + public void ViewComponent_View_WithModelParameter_SetsResultViewWithDefaultViewNameAndModel() { // 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); + Assert.IsType(actualResult); + Assert.IsType>(actualResult.ViewData); + Assert.NotSame(viewComponent.ViewData, actualResult.ViewData); + Assert.Equal(new ViewDataDictionary(viewComponent.ViewData), actualResult.ViewData); + Assert.Same(model, actualResult.ViewData.Model); + Assert.Null(actualResult.ViewName); } [Fact] - public void ViewComponent_View_WithViewNameAndModelParameters_CallsResultViewWithCustomViewNameAndModel() + public void ViewComponent_View_WithViewNameAndModelParameters_SetsResultViewWithCustomViewNameAndModel() { // 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); + Assert.IsType(actualResult); + Assert.IsType>(actualResult.ViewData); + Assert.NotSame(viewComponent.ViewData, actualResult.ViewData); + Assert.Equal(new ViewDataDictionary(viewComponent.ViewData), actualResult.ViewData); + Assert.Same(model, actualResult.ViewData.Model); + Assert.Equal("CustomViewName", actualResult.ViewName); } private class TestViewComponent : ViewComponent