View components - More built in return methods (Fix #354)
Modify Content/Json/View return type as strongly-typed.
This commit is contained in:
parent
cfe078059b
commit
6082cd9f36
|
|
@ -17,9 +17,19 @@ namespace MvcSample.Web.Components
|
||||||
.OrderBy(s => Guid.NewGuid().ToString())
|
.OrderBy(s => Guid.NewGuid().ToString())
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
public async Task<IViewComponentResult> InvokeAsync(int count)
|
public async Task<IViewComponentResult> InvokeAsync(int count, string returnAs)
|
||||||
{
|
{
|
||||||
var tags = await GetTagsAsync(count);
|
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);
|
return View(tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,12 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div style="float: left; border: 5px solid red; margin: 5px;">
|
<div style="float: left; border: 5px solid red; margin: 5px;">
|
||||||
@await Component.InvokeAsync("Tags", 15)
|
<p>Tags from View():</p>
|
||||||
|
@await Component.InvokeAsync("Tags", 5, "View")
|
||||||
|
<p>Tags from Content():</p>
|
||||||
|
<p>@await Component.InvokeAsync("Tags", 5, "Content")</p>
|
||||||
|
<p>Tags from Json():</p>
|
||||||
|
<p>@await Component.InvokeAsync("Tags", 5, "Json")</p>
|
||||||
<p style="padding: 0px 10px;">'@ViewBag.Title' should match page heading (still)</p>
|
<p style="padding: 0px 10px;">'@ViewBag.Title' should match page heading (still)</p>
|
||||||
</div>
|
</div>
|
||||||
<div style="float: left; border: thick solid lightskyblue; margin: 5px; padding: 7px;">
|
<div style="float: left; border: thick solid lightskyblue; margin: 5px; padding: 7px;">
|
||||||
|
|
|
||||||
|
|
@ -14,17 +14,17 @@ namespace Microsoft.AspNet.Mvc
|
||||||
_viewEngine = viewEngine;
|
_viewEngine = viewEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IViewComponentResult Content([NotNull] string content)
|
public virtual ContentViewComponentResult Content([NotNull] string content)
|
||||||
{
|
{
|
||||||
return new ContentViewComponentResult(content);
|
return new ContentViewComponentResult(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IViewComponentResult Json([NotNull] object value)
|
public virtual JsonViewComponentResult Json([NotNull] object value)
|
||||||
{
|
{
|
||||||
return new JsonViewComponentResult(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);
|
return new ViewViewComponentResult(_viewEngine, viewName, viewData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@ namespace Microsoft.AspNet.Mvc
|
||||||
{
|
{
|
||||||
public interface IViewComponentResultHelper
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,27 +35,37 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
public ViewDataDictionary ViewData { get; set; }
|
public ViewDataDictionary ViewData { get; set; }
|
||||||
|
|
||||||
|
public ContentViewComponentResult Content(string content)
|
||||||
|
{
|
||||||
|
return Result.Content(content);
|
||||||
|
}
|
||||||
|
|
||||||
public void Initialize(IViewComponentResultHelper result)
|
public void Initialize(IViewComponentResultHelper result)
|
||||||
{
|
{
|
||||||
Result = result;
|
Result = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IViewComponentResult View()
|
public JsonViewComponentResult Json(object value)
|
||||||
|
{
|
||||||
|
return Result.Json(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ViewViewComponentResult View()
|
||||||
{
|
{
|
||||||
return View<object>(null, null);
|
return View<object>(null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IViewComponentResult View(string viewName)
|
public ViewViewComponentResult View(string viewName)
|
||||||
{
|
{
|
||||||
return View<object>(viewName, null);
|
return View<object>(viewName, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IViewComponentResult View<TModel>(TModel model)
|
public ViewViewComponentResult View<TModel>(TModel model)
|
||||||
{
|
{
|
||||||
return View(null, model);
|
return View(null, model);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IViewComponentResult View<TModel>(string viewName, TModel model)
|
public ViewViewComponentResult View<TModel>(string viewName, TModel model)
|
||||||
{
|
{
|
||||||
var viewData = new ViewDataDictionary<TModel>(ViewData);
|
var viewData = new ViewDataDictionary<TModel>(ViewData);
|
||||||
if (model != null)
|
if (model != null)
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,7 @@
|
||||||
<Compile Include="TypeHelperTest.cs" />
|
<Compile Include="TypeHelperTest.cs" />
|
||||||
<Compile Include="UrlHelperTest.cs" />
|
<Compile Include="UrlHelperTest.cs" />
|
||||||
<Compile Include="ViewResultTest.cs" />
|
<Compile Include="ViewResultTest.cs" />
|
||||||
|
<Compile Include="ViewComponentTests.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -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<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);
|
||||||
|
|
||||||
|
// 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<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();
|
||||||
|
|
||||||
|
// 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<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);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ViewComponent_View_WithViewNameParameter_CallsResultViewWithCustomViewName()
|
||||||
|
{
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ViewComponent_View_WithModelParameter_CallsResultViewWithDefaultViewNameAndModel()
|
||||||
|
{
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ViewComponent_View_WithViewNameAndModelParameters_CallsResultViewWithCustomViewNameAndModel()
|
||||||
|
{
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestViewComponent : ViewComponent
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue