Issue #1214: Cannot pass a int parameter to the views from ViewComponent.

Fix: Checking if the model is not null in the Copy constructor of ViewDataDictionary.
This commit is contained in:
sornaks 2014-10-17 15:41:26 -07:00
parent 75405e3b76
commit 5b1bcb6079
7 changed files with 82 additions and 1 deletions

View File

@ -51,7 +51,12 @@ namespace Microsoft.AspNet.Mvc
new TemplateInfo(source.TemplateInfo))
{
_modelMetadata = source.ModelMetadata;
SetModel(model);
// If we're constructing a derived ViewDataDictionary (or any other value type),
// SetModel will throw if we try to set it to null. We should not throw in that case.
if (model != null)
{
SetModel(model);
}
}
private ViewDataDictionary(IModelMetadataProvider metadataProvider,

View File

@ -116,6 +116,46 @@ namespace Microsoft.AspNet.Mvc.Core
Assert.IsType<CopyOnWriteDictionary<string, object>>(viewData.Data);
}
[Fact]
public void CopyConstructorDoesNotThrowOnNullModel()
{
// Arrange
var metadataProvider = new EmptyModelMetadataProvider();
var source = new ViewDataDictionary(metadataProvider);
source["key1"] = "value1";
// Act
var viewData = new ViewDataDictionary(source, null);
// Assert
Assert.NotNull(viewData.ModelState);
Assert.NotNull(viewData.TemplateInfo);
Assert.Null(viewData.Model);
Assert.Null(viewData.ModelMetadata);
Assert.Equal("value1", viewData["key1"]);
Assert.IsType<CopyOnWriteDictionary<string, object>>(viewData.Data);
}
[Fact]
public void CopyConstructorDoesNotThrowOnNullModel_WithValueTypeTModel()
{
// Arrange
var metadataProvider = new EmptyModelMetadataProvider();
var source = new ViewDataDictionary(metadataProvider);
source["key1"] = "value1";
// Act
var viewData = new ViewDataDictionary<int>(source, null);
// Assert
Assert.NotNull(viewData.ModelState);
Assert.NotNull(viewData.TemplateInfo);
Assert.Throws<NullReferenceException>(() => viewData.Model);
Assert.NotNull(viewData.ModelMetadata);
Assert.Equal("value1", viewData["key1"]);
Assert.IsType<CopyOnWriteDictionary<string, object>>(viewData.Data);
}
private class TestModel
{
}

View File

@ -51,5 +51,18 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
// Assert
Assert.Equal(expected, body.Trim());
}
[Fact]
public async Task ViewComponents_SupportsValueType()
{
var server = TestServer.Create(_provider, _app);
var client = server.CreateClient();
// Act
var body = await client.GetStringAsync("http://localhost/Home/ViewWithIntegerViewComponent");
// Assert
Assert.Equal("10", body.Trim());
}
}
}

View File

@ -16,5 +16,10 @@ namespace ViewComponentWebSite
{
return new ViewResult();
}
public ViewResult ViewWithIntegerViewComponent()
{
return new ViewResult();
}
}
}

View File

@ -0,0 +1,15 @@
// 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;
namespace ViewComponentWebSite
{
public class IntegerViewComponent : ViewComponent
{
public IViewComponentResult Invoke(int valueFromView)
{
return View(valueFromView);
}
}
}

View File

@ -0,0 +1,2 @@
@model int
@Model

View File

@ -0,0 +1 @@
@Component.Invoke("Integer", 10)