Make `ViewComponent.View()` overloads respect explicitly passed in model even when `null`

This commit is contained in:
Ajay Bhargav Baaskaran 2017-02-01 15:07:24 -08:00
parent 35edc299d7
commit 44048331e9
4 changed files with 225 additions and 19 deletions

View File

@ -113,7 +113,7 @@ namespace Microsoft.AspNetCore.Mvc
[NonAction] [NonAction]
public virtual ViewResult View(string viewName) public virtual ViewResult View(string viewName)
{ {
return View(viewName, model: null); return View(viewName, model: ViewData.Model);
} }
/// <summary> /// <summary>
@ -138,10 +138,7 @@ namespace Microsoft.AspNetCore.Mvc
[NonAction] [NonAction]
public virtual ViewResult View(string viewName, object model) public virtual ViewResult View(string viewName, object model)
{ {
if (model != null) ViewData.Model = model;
{
ViewData.Model = model;
}
return new ViewResult() return new ViewResult()
{ {
@ -169,7 +166,7 @@ namespace Microsoft.AspNetCore.Mvc
[NonAction] [NonAction]
public virtual PartialViewResult PartialView(string viewName) public virtual PartialViewResult PartialView(string viewName)
{ {
return PartialView(viewName, model: null); return PartialView(viewName, model: ViewData.Model);
} }
/// <summary> /// <summary>
@ -194,10 +191,7 @@ namespace Microsoft.AspNetCore.Mvc
[NonAction] [NonAction]
public virtual PartialViewResult PartialView(string viewName, object model) public virtual PartialViewResult PartialView(string viewName, object model)
{ {
if (model != null) ViewData.Model = model;
{
ViewData.Model = model;
}
return new PartialViewResult() return new PartialViewResult()
{ {

View File

@ -237,7 +237,7 @@ namespace Microsoft.AspNetCore.Mvc
/// <returns>A <see cref="ViewViewComponentResult"/>.</returns> /// <returns>A <see cref="ViewViewComponentResult"/>.</returns>
public ViewViewComponentResult View() public ViewViewComponentResult View()
{ {
return View<object>(null, null); return View(viewName: null);
} }
/// <summary> /// <summary>
@ -247,7 +247,7 @@ namespace Microsoft.AspNetCore.Mvc
/// <returns>A <see cref="ViewViewComponentResult"/>.</returns> /// <returns>A <see cref="ViewViewComponentResult"/>.</returns>
public ViewViewComponentResult View(string viewName) public ViewViewComponentResult View(string viewName)
{ {
return View<object>(viewName, null); return View(viewName, ViewData.Model);
} }
/// <summary> /// <summary>
@ -257,7 +257,7 @@ namespace Microsoft.AspNetCore.Mvc
/// <returns>A <see cref="ViewViewComponentResult"/>.</returns> /// <returns>A <see cref="ViewViewComponentResult"/>.</returns>
public ViewViewComponentResult View<TModel>(TModel model) public ViewViewComponentResult View<TModel>(TModel model)
{ {
return View(null, model); return View(viewName: null, model: model);
} }
/// <summary> /// <summary>
@ -268,12 +268,7 @@ namespace Microsoft.AspNetCore.Mvc
/// <returns>A <see cref="ViewViewComponentResult"/>.</returns> /// <returns>A <see cref="ViewViewComponentResult"/>.</returns>
public ViewViewComponentResult View<TModel>(string viewName, TModel model) public ViewViewComponentResult View<TModel>(string viewName, TModel model)
{ {
if (model != null) var viewData = new ViewDataDictionary<TModel>(ViewData, model);
{
ViewData.Model = model;
}
var viewData = new ViewDataDictionary<TModel>(ViewData);
return new ViewViewComponentResult return new ViewViewComponentResult
{ {
ViewEngine = ViewEngine, ViewEngine = ViewEngine,

View File

@ -87,6 +87,30 @@ namespace Microsoft.AspNetCore.Mvc.Test
Assert.Null(actualViewResult.ViewData.Model); Assert.Null(actualViewResult.ViewData.Model);
} }
[Fact]
public void Controller_View_WithoutParameter_MaintainsModelInViewData()
{
// Arrange
var controller = new TestableController()
{
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()),
TempData = new TempDataDictionary(new DefaultHttpContext(), Mock.Of<ITempDataProvider>()),
};
var model = new object();
controller.ViewData.Model = model;
// Act
var actualViewResult = controller.View();
// Assert
Assert.IsType<ViewResult>(actualViewResult);
Assert.Null(actualViewResult.ViewName);
Assert.Same(controller.ViewData, actualViewResult.ViewData);
Assert.Same(controller.TempData, actualViewResult.TempData);
Assert.Same(model, actualViewResult.ViewData.Model);
}
[Fact] [Fact]
public void Controller_View_WithParameterViewName_SetsResultViewNameAndNullViewDataModelAndSameTempData() public void Controller_View_WithParameterViewName_SetsResultViewNameAndNullViewDataModelAndSameTempData()
{ {
@ -152,6 +176,141 @@ namespace Microsoft.AspNetCore.Mvc.Test
Assert.Same(model, actualViewResult.ViewData.Model); Assert.Same(model, actualViewResult.ViewData.Model);
} }
[Fact]
public void Controller_View_WithNullModelParameter_OverwritesViewDataModel()
{
// Arrange
var controller = new TestableController()
{
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()),
TempData = new TempDataDictionary(new DefaultHttpContext(), Mock.Of<ITempDataProvider>()),
};
controller.ViewData.Model = new object();
// Act
var actualViewResult = controller.View(model: null);
// Assert
Assert.IsType<ViewResult>(actualViewResult);
Assert.Null(actualViewResult.ViewName);
Assert.Same(controller.ViewData, actualViewResult.ViewData);
Assert.Same(controller.TempData, actualViewResult.TempData);
Assert.Null(actualViewResult.ViewData.Model);
}
[Fact]
public void Controller_PartialView_WithoutParameter_MaintainsModelInViewData()
{
// Arrange
var controller = new TestableController()
{
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()),
TempData = new TempDataDictionary(new DefaultHttpContext(), Mock.Of<ITempDataProvider>()),
};
var model = new object();
controller.ViewData.Model = model;
// Act
var actualViewResult = controller.PartialView();
// Assert
Assert.IsType<PartialViewResult>(actualViewResult);
Assert.Null(actualViewResult.ViewName);
Assert.Same(controller.ViewData, actualViewResult.ViewData);
Assert.Same(controller.TempData, actualViewResult.TempData);
Assert.Same(model, actualViewResult.ViewData.Model);
}
[Fact]
public void Controller_PartialView_WithParameterViewName_SetsResultViewNameAndMaintainsSameViewDataModelAndTempData()
{
// Arrange
var controller = new TestableController()
{
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()),
TempData = new TempDataDictionary(new DefaultHttpContext(), Mock.Of<ITempDataProvider>()),
};
var model = new object();
controller.ViewData.Model = model;
// Act
var actualViewResult = controller.PartialView("CustomViewName");
// Assert
Assert.IsType<PartialViewResult>(actualViewResult);
Assert.Equal("CustomViewName", actualViewResult.ViewName);
Assert.Same(controller.ViewData, actualViewResult.ViewData);
Assert.Same(controller.TempData, actualViewResult.TempData);
Assert.Same(model, actualViewResult.ViewData.Model);
}
[Fact]
public void Controller_PartialView_WithParameterViewModel_SetsResultNullViewNameAndViewDataModelAndSameTempData()
{
// Arrange
var controller = new TestableController()
{
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()),
TempData = new TempDataDictionary(new DefaultHttpContext(), Mock.Of<ITempDataProvider>()),
};
var model = new object();
// Act
var actualViewResult = controller.PartialView(model);
// Assert
Assert.IsType<PartialViewResult>(actualViewResult);
Assert.Null(actualViewResult.ViewName);
Assert.Same(controller.ViewData, actualViewResult.ViewData);
Assert.Same(controller.TempData, actualViewResult.TempData);
Assert.Same(model, actualViewResult.ViewData.Model);
}
[Fact]
public void Controller_PartialView_WithParameterViewNameAndViewModel_SetsResultViewNameAndViewDataModelAndSameTempData()
{
// Arrange
var controller = new TestableController()
{
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()),
TempData = new TempDataDictionary(new DefaultHttpContext(), Mock.Of<ITempDataProvider>()),
};
var model = new object();
// Act
var actualViewResult = controller.PartialView("CustomViewName", model);
// Assert
Assert.IsType<PartialViewResult>(actualViewResult);
Assert.Equal("CustomViewName", actualViewResult.ViewName);
Assert.Same(controller.ViewData, actualViewResult.ViewData);
Assert.Same(controller.TempData, actualViewResult.TempData);
Assert.Same(model, actualViewResult.ViewData.Model);
}
[Fact]
public void Controller_PartialView_WithNullModelParameter_OverwritesViewDataModel()
{
// Arrange
var controller = new TestableController()
{
ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider()),
TempData = new TempDataDictionary(new DefaultHttpContext(), Mock.Of<ITempDataProvider>()),
};
controller.ViewData.Model = new object();
// Act
var actualViewResult = controller.PartialView(model: null);
// Assert
Assert.IsType<PartialViewResult>(actualViewResult);
Assert.Null(actualViewResult.ViewName);
Assert.Same(controller.ViewData, actualViewResult.ViewData);
Assert.Same(controller.TempData, actualViewResult.TempData);
Assert.Null(actualViewResult.ViewData.Model);
}
[Fact] [Fact]
public void Controller_Json_WithParameterValue_SetsResultData() public void Controller_Json_WithParameterValue_SetsResultData()
{ {

View File

@ -139,6 +139,64 @@ namespace Microsoft.AspNetCore.Mvc
Assert.Null(actualResult.ViewName); Assert.Null(actualResult.ViewName);
} }
[Fact]
public void ViewComponent_View_WithNullModelParameter_SetsResultViewWithDefaultViewNameAndNullModel()
{
// Arrange
var viewComponent = new TestViewComponent();
viewComponent.ViewData.Model = new object();
object model = null;
// Act
var actualResult = viewComponent.View(model: model);
// Assert
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.Null(actualResult.ViewName);
}
[Fact]
public void ViewComponent_View_WithViewNameAndNullModelParameter_SetsResultViewWithViewNameAndNullModel()
{
// Arrange
var viewComponent = new TestViewComponent();
viewComponent.ViewData.Model = new object();
// Act
var actualResult = viewComponent.View<object>("CustomViewName", model: null);
// Assert
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_WithViewNameAndNonObjectNullModelParameter_SetsResultViewWithViewNameAndNullModel()
{
// Arrange
var viewComponent = new TestViewComponent();
viewComponent.ViewData.Model = "Hello World!";
// Act
var actualResult = viewComponent.View<string>("CustomViewName", model: null);
// Assert
Assert.IsType<ViewViewComponentResult>(actualResult);
Assert.IsType<ViewDataDictionary<string>>(actualResult.ViewData);
Assert.NotSame(viewComponent.ViewData, actualResult.ViewData);
Assert.Equal(new ViewDataDictionary<string>(viewComponent.ViewData), actualResult.ViewData);
Assert.Null(actualResult.ViewData.Model);
Assert.Equal("CustomViewName", actualResult.ViewName);
}
[Fact] [Fact]
public void ViewComponent_View_WithViewNameAndModelParameters_SetsResultViewWithCustomViewNameAndModel() public void ViewComponent_View_WithViewNameAndModelParameters_SetsResultViewWithCustomViewNameAndModel()
{ {