Remove ComponentResultHelper

Fix #598
This commit is contained in:
Tian Pan 2014-06-11 11:28:19 -07:00
parent e95585dfbd
commit 31915f0b46
9 changed files with 75 additions and 146 deletions

View File

@ -212,14 +212,12 @@
<Compile Include="ViewComponents\DefaultViewComponentInvoker.cs" />
<Compile Include="ViewComponents\DefaultViewComponentInvokerFactory.cs" />
<Compile Include="ViewComponents\DefaultViewComponentInvokerProvider.cs" />
<Compile Include="ViewComponents\DefaultViewComponentResultHelper.cs" />
<Compile Include="ViewComponents\DefaultViewComponentSelector.cs" />
<Compile Include="ViewComponents\IViewComponentHelper.cs" />
<Compile Include="ViewComponents\IViewComponentInvoker.cs" />
<Compile Include="ViewComponents\IViewComponentInvokerFactory.cs" />
<Compile Include="ViewComponents\IViewComponentInvokerProvider.cs" />
<Compile Include="ViewComponents\IViewComponentResult.cs" />
<Compile Include="ViewComponents\IViewComponentResultHelper.cs" />
<Compile Include="ViewComponents\IViewComponentSelector.cs" />
<Compile Include="ViewComponents\JsonViewComponentResult.cs" />
<Compile Include="ViewComponents\ViewComponent.cs" />

View File

@ -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());
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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)

View File

@ -77,7 +77,6 @@ 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.Transient<IAuthorizationService, DefaultAuthorizationService>();

View File

@ -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<DefaultViewComponentResultHelper>(It.IsAny<IViewEngine>());
var resultMock = new Mock<ContentViewComponentResult>("TestContent");
resultHelperMock.Setup(r => r.Content(It.IsAny<string>()))
.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<ContentViewComponentResult>(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<DefaultViewComponentResultHelper>(It.IsAny<IViewEngine>());
var resultMock = new Mock<JsonViewComponentResult>(It.IsAny<object>());
resultHelperMock.Setup(r => r.Json(It.IsAny<object>()))
.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<JsonViewComponentResult>(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<DefaultViewComponentResultHelper>(It.IsAny<IViewEngine>());
var resultMock = new Mock<ViewViewComponentResult>(It.IsAny<IViewEngine>(),
It.IsAny<string>(),
It.IsAny<ViewDataDictionary>());
resultHelperMock.Setup(r => r.View(It.IsAny<string>(), It.IsAny<ViewDataDictionary>()))
.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<ViewViewComponentResult>(actualResult);
Assert.NotSame(viewComponent.ViewData, actualResult.ViewData);
Assert.Equal(new ViewDataDictionary<object>(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<DefaultViewComponentResultHelper>(It.IsAny<IViewEngine>());
var resultMock = new Mock<ViewViewComponentResult>(It.IsAny<IViewEngine>(),
It.IsAny<string>(),
It.IsAny<ViewDataDictionary>());
resultHelperMock.Setup(r => r.View(It.IsAny<string>(), It.IsAny<ViewDataDictionary>()))
.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<ViewViewComponentResult>(actualResult);
Assert.IsType<ViewDataDictionary<object>>(actualResult.ViewData);
Assert.NotSame(viewComponent.ViewData, actualResult.ViewData);
Assert.Equal(new ViewDataDictionary<object>(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<DefaultViewComponentResultHelper>(It.IsAny<IViewEngine>());
var resultMock = new Mock<ViewViewComponentResult>(It.IsAny<IViewEngine>(),
It.IsAny<string>(),
It.IsAny<ViewDataDictionary>());
resultHelperMock.Setup(r => r.View(It.IsAny<string>(), It.IsAny<ViewDataDictionary>()))
.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<ViewViewComponentResult>(actualResult);
Assert.IsType<ViewDataDictionary<object>>(actualResult.ViewData);
Assert.NotSame(viewComponent.ViewData, actualResult.ViewData);
Assert.Equal(new ViewDataDictionary<object>(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<DefaultViewComponentResultHelper>(It.IsAny<IViewEngine>());
var resultMock = new Mock<ViewViewComponentResult>(It.IsAny<IViewEngine>(),
It.IsAny<string>(),
It.IsAny<ViewDataDictionary>());
resultHelperMock.Setup(r => r.View(It.IsAny<string>(), It.IsAny<ViewDataDictionary>()))
.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<ViewViewComponentResult>(actualResult);
Assert.IsType<ViewDataDictionary<object>>(actualResult.ViewData);
Assert.NotSame(viewComponent.ViewData, actualResult.ViewData);
Assert.Equal(new ViewDataDictionary<object>(viewComponent.ViewData), actualResult.ViewData);
Assert.Same(model, actualResult.ViewData.Model);
Assert.Equal("CustomViewName", actualResult.ViewName);
}
private class TestViewComponent : ViewComponent