diff --git a/Settings.StyleCop b/Settings.StyleCop index c04ef7cc93..e4c19d4399 100644 --- a/Settings.StyleCop +++ b/Settings.StyleCop @@ -409,10 +409,10 @@ - + - Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + 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. diff --git a/build.cmd b/build.cmd index 903d532df3..3aaf957583 100644 --- a/build.cmd +++ b/build.cmd @@ -18,6 +18,8 @@ copy %CACHED_NUGET% .nuget\nuget.exe > nul IF EXIST packages\KoreBuild goto run .nuget\NuGet.exe install KoreBuild -ExcludeVersion -o packages -nocache -pre .nuget\NuGet.exe install Sake -version 0.2 -o packages -ExcludeVersion + +IF "%SKIP_KRE_INSTALL%"=="1" goto run CALL packages\KoreBuild\build\kvm upgrade -svr50 -x86 CALL packages\KoreBuild\build\kvm install default -svrc50 -x86 diff --git a/samples/MvcSample.Web/Components/TagCloud.cs b/samples/MvcSample.Web/Components/TagCloud.cs index c6a214a5a9..5d9803addc 100644 --- a/samples/MvcSample.Web/Components/TagCloud.cs +++ b/samples/MvcSample.Web/Components/TagCloud.cs @@ -17,9 +17,19 @@ namespace MvcSample.Web.Components .OrderBy(s => Guid.NewGuid().ToString()) .ToArray(); - public async Task InvokeAsync(int count) + public async Task InvokeAsync(int count, string returnAs) { 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); } diff --git a/samples/MvcSample.Web/Views/Home/ValidationSummary.cshtml b/samples/MvcSample.Web/Views/Home/ValidationSummary.cshtml index 9188ca196c..d1b888f97f 100644 --- a/samples/MvcSample.Web/Views/Home/ValidationSummary.cshtml +++ b/samples/MvcSample.Web/Views/Home/ValidationSummary.cshtml @@ -15,9 +15,9 @@
@Html.ValidationSummary() @Html.ValidationSummary(excludePropertyErrors: true) - @Html.ValidationSummary(message: "Hello from validation message summary 1.") + @Html.ValidationSummary(message: "Hello from validation message summary 1.", tag: "h2") @Html.ValidationSummary(excludePropertyErrors: true, message: "Hello from validation message summary 2") @Html.ValidationSummary(message: "Hello from validation message summary 3", htmlAttributes: new { style = "color: red" }) @Html.ValidationSummary(excludePropertyErrors: true, message: "Hello from validation message summary 4", htmlAttributes: new { style = "color: green" }) - @Html.ValidationSummary(message: "Hello from validation message summary 5", htmlAttributes: new Dictionary { { "style", "color: blue" } }) + @Html.ValidationSummary(message: "Hello from validation message summary 5", htmlAttributes: new Dictionary { { "style", "color: blue" } }, tag: "h1")
\ No newline at end of file diff --git a/samples/MvcSample.Web/Views/Shared/MyView.cshtml b/samples/MvcSample.Web/Views/Shared/MyView.cshtml index d3662dbdf8..18ae092b23 100644 --- a/samples/MvcSample.Web/Views/Shared/MyView.cshtml +++ b/samples/MvcSample.Web/Views/Shared/MyView.cshtml @@ -146,7 +146,12 @@
- @await Component.InvokeAsync("Tags", 15) +

Tags from View():

+ @await Component.InvokeAsync("Tags", 5, "View") +

Tags from Content():

+

@await Component.InvokeAsync("Tags", 5, "Content")

+

Tags from Json():

+

@await Component.InvokeAsync("Tags", 5, "Json")

'@ViewBag.Title' should match page heading (still)

diff --git a/src/Microsoft.AspNet.Mvc.Core/ActionResults/RedirectResult.cs b/src/Microsoft.AspNet.Mvc.Core/ActionResults/RedirectResult.cs index 60c692d3ec..a9c9d86b1d 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ActionResults/RedirectResult.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ActionResults/RedirectResult.cs @@ -3,6 +3,7 @@ using System; using Microsoft.AspNet.Mvc.Core; +using Microsoft.Framework.DependencyInjection; namespace Microsoft.AspNet.Mvc { @@ -30,10 +31,18 @@ namespace Microsoft.AspNet.Mvc public override void ExecuteResult([NotNull] ActionContext context) { - // It is redirected directly to the input URL. - // We would use the context to construct the full URL, - // only when relative URLs are supported. (Issue - WEBFX-202) - context.HttpContext.Response.Redirect(Url, Permanent); + var destinationUrl = Url; + var urlHelper = context.HttpContext + .RequestServices + .GetService(); + + // IsLocalUrl is called to handle Urls starting with '~/'. + if (urlHelper.IsLocalUrl(destinationUrl)) + { + destinationUrl = urlHelper.Content(Url); + } + + context.HttpContext.Response.Redirect(destinationUrl, Permanent); } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs index 232ced77a4..9746106e1d 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelper.cs @@ -443,13 +443,16 @@ namespace Microsoft.AspNet.Mvc.Rendering } /// - public HtmlString ValidationMessage(string expression, string message, object htmlAttributes) + public HtmlString ValidationMessage(string expression, string message, object htmlAttributes, string tag) { - return GenerateValidationMessage(expression, message, htmlAttributes); + return GenerateValidationMessage(expression, message, htmlAttributes, tag); } /// - public virtual HtmlString ValidationSummary(bool excludePropertyErrors, string message, IDictionary htmlAttributes) + public virtual HtmlString ValidationSummary(bool excludePropertyErrors, + string message, + IDictionary htmlAttributes, + string tag) { var formContext = ViewContext.ClientValidationEnabled ? ViewContext.FormContext : null; @@ -464,16 +467,20 @@ namespace Microsoft.AspNet.Mvc.Rendering } } - string messageSpan; + string wrappedMessage; if (!string.IsNullOrEmpty(message)) { - var spanTag = new TagBuilder("span"); - spanTag.SetInnerText(message); - messageSpan = spanTag.ToString(TagRenderMode.Normal) + Environment.NewLine; + if (string.IsNullOrEmpty(tag)) + { + tag = ViewContext.ValidationSummaryMessageElement; + } + var messageTag = new TagBuilder(tag); + messageTag.SetInnerText(message); + wrappedMessage = messageTag.ToString(TagRenderMode.Normal) + Environment.NewLine; } else { - messageSpan = null; + wrappedMessage = null; } var htmlSummary = new StringBuilder(); @@ -516,7 +523,7 @@ namespace Microsoft.AspNet.Mvc.Rendering divBuilder.AddCssClass(HtmlHelper.ValidationSummaryCssClassName); } - divBuilder.InnerHtml = messageSpan + unorderedList.ToString(TagRenderMode.Normal); + divBuilder.InnerHtml = wrappedMessage + unorderedList.ToString(TagRenderMode.Normal); if (formContext != null) { @@ -1261,8 +1268,10 @@ namespace Microsoft.AspNet.Mvc.Rendering return tagBuilder.ToHtmlString(TagRenderMode.SelfClosing); } - protected virtual HtmlString GenerateValidationMessage(string expression, string message, - object htmlAttributes) + protected virtual HtmlString GenerateValidationMessage(string expression, + string message, + object htmlAttributes, + string tag) { var modelName = ViewData.TemplateInfo.GetFullHtmlFieldName(expression); if (string.IsNullOrEmpty(modelName)) @@ -1294,7 +1303,11 @@ namespace Microsoft.AspNet.Mvc.Rendering // Even if there are no model errors, we generate the span and add the validation message // if formContext is not null. - var builder = new TagBuilder("span"); + if (string.IsNullOrEmpty(tag)) + { + tag = ViewContext.ValidationMessageElement; + } + var builder = new TagBuilder(tag); builder.MergeAttributes(AnonymousObjectToHtmlAttributes(htmlAttributes)); // Only the style of the span is changed according to the errors if message is null or empty. diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelperOfT.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelperOfT.cs index 16d88f75eb..0008e5ce29 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelperOfT.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/Html/HtmlHelperOfT.cs @@ -229,9 +229,14 @@ namespace Microsoft.AspNet.Mvc.Rendering /// public HtmlString ValidationMessageFor([NotNull] Expression> expression, - string message, object htmlAttributes) + string message, + object htmlAttributes, + string tag) { - return GenerateValidationMessage(ExpressionHelper.GetExpressionText(expression), message, htmlAttributes); + return GenerateValidationMessage(ExpressionHelper.GetExpressionText(expression), + message, + htmlAttributes, + tag); } /// diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/HtmlHelperValidationExtensions.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/HtmlHelperValidationExtensions.cs index edbcba84ae..0f751bfbc1 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/HtmlHelperValidationExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/HtmlHelperValidationExtensions.cs @@ -12,95 +12,202 @@ namespace Microsoft.AspNet.Mvc.Rendering public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper, string expression) { - return htmlHelper.ValidationMessage(expression, message: null, htmlAttributes: null); + return htmlHelper.ValidationMessage(expression, message: null, htmlAttributes: null, tag: null); } public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper, - string expression, string message) + string expression, + string message) { - return htmlHelper.ValidationMessage(expression, message, htmlAttributes: null); + return htmlHelper.ValidationMessage(expression, message, htmlAttributes: null, tag: null); } public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper, - string expression, object htmlAttributes) + string expression, + object htmlAttributes) { - return htmlHelper.ValidationMessage(expression, message: null, htmlAttributes: htmlAttributes); + return htmlHelper.ValidationMessage(expression, message: null, htmlAttributes: htmlAttributes, tag: null); } public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper, - string expression, string message, object htmlAttributes) + string expression, + string message, + string tag) { - return htmlHelper.ValidationMessage(expression, message, htmlAttributes); + return htmlHelper.ValidationMessage(expression, message, htmlAttributes: null, tag: tag); + } + + public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper, + string expression, + string message, + object htmlAttributes) + { + return htmlHelper.ValidationMessage(expression, message, htmlAttributes, tag: null); + } + + public static HtmlString ValidationMessage([NotNull] this IHtmlHelper htmlHelper, + string expression, + string message, + object htmlAttributes, + string tag) + { + return htmlHelper.ValidationMessage(expression, message, htmlAttributes, tag); } public static HtmlString ValidationMessageFor([NotNull] this IHtmlHelper htmlHelper, [NotNull] Expression> expression) { - return htmlHelper.ValidationMessageFor(expression, message: null, htmlAttributes: null); + return htmlHelper.ValidationMessageFor(expression, message: null, htmlAttributes: null, tag: null); } public static HtmlString ValidationMessageFor([NotNull] this IHtmlHelper htmlHelper, - [NotNull] Expression> expression, string message) + [NotNull] Expression> expression, + string message) { - return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes: null); + return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes: null, tag: null); } public static HtmlString ValidationMessageFor([NotNull] this IHtmlHelper htmlHelper, - [NotNull] Expression> expression, string message, object htmlAttributes) + [NotNull] Expression> expression, + string message, + object htmlAttributes) { - return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes); + return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes, tag: null); + } + + public static HtmlString ValidationMessageFor([NotNull] this IHtmlHelper htmlHelper, + [NotNull] Expression> expression, + string message, + string tag) + { + return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes: null, tag: tag); + } + + public static HtmlString ValidationMessageFor([NotNull] this IHtmlHelper htmlHelper, + [NotNull] Expression> expression, + string message, + object htmlAttributes, + string tag) + { + return htmlHelper.ValidationMessageFor(expression, message, htmlAttributes, tag); } public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper) { - return ValidationSummary(htmlHelper, excludePropertyErrors: false); + return htmlHelper.ValidationSummary(excludePropertyErrors: false, + message: null, + htmlAttributes: null, + tag: null); } public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, bool excludePropertyErrors) { - return ValidationSummary(htmlHelper, excludePropertyErrors, message: null); + return htmlHelper.ValidationSummary(excludePropertyErrors, + message: null, + htmlAttributes: null, + tag: null); } public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, string message) { - return ValidationSummary(htmlHelper, excludePropertyErrors: false, message: message, - htmlAttributes: (object)null); + return htmlHelper.ValidationSummary(excludePropertyErrors: false, + message: message, + htmlAttributes: null, + tag: null); } - public static HtmlString ValidationSummary( - [NotNull] this IHtmlHelper htmlHelper, + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, string message, string tag) + { + return htmlHelper.ValidationSummary(excludePropertyErrors: false, + message: message, + htmlAttributes: null, + tag: tag); + } + + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, bool excludePropertyErrors, string message) { - return ValidationSummary(htmlHelper, excludePropertyErrors, message, htmlAttributes: (object)null); + return htmlHelper.ValidationSummary(excludePropertyErrors, + message, + htmlAttributes: null, + tag: null); } - public static HtmlString ValidationSummary( - [NotNull] this IHtmlHelper htmlHelper, + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, string message, object htmlAttributes) { - return ValidationSummary(htmlHelper, excludePropertyErrors: false, message: message, - htmlAttributes: HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); + return htmlHelper.ValidationSummary(excludePropertyErrors: false, + message: message, + htmlAttributes: HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), + tag: null); } - public static HtmlString ValidationSummary( - [NotNull] this IHtmlHelper htmlHelper, + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, + string message, + object htmlAttributes, + string tag) + { + return htmlHelper.ValidationSummary(excludePropertyErrors: false, + message: message, + htmlAttributes: HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), + tag: tag); + } + + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, + bool excludePropertyErrors, + string message, + string tag) + { + return htmlHelper.ValidationSummary(excludePropertyErrors, + message, + htmlAttributes: null, + tag: tag); + } + + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, bool excludePropertyErrors, string message, object htmlAttributes) { - return htmlHelper.ValidationSummary(excludePropertyErrors, message, - HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes)); + return htmlHelper.ValidationSummary(excludePropertyErrors, + message, + HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), + tag: null); } - public static HtmlString ValidationSummary( - [NotNull] this IHtmlHelper htmlHelper, + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, + bool excludePropertyErrors, + string message, + object htmlAttributes, + string tag) + { + return htmlHelper.ValidationSummary(excludePropertyErrors, + message, + HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes), + tag); + } + + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, string message, IDictionary htmlAttributes) { - return htmlHelper.ValidationSummary(excludePropertyErrors: false, message: message, - htmlAttributes: htmlAttributes); + return htmlHelper.ValidationSummary(excludePropertyErrors: false, + message: message, + htmlAttributes: htmlAttributes, + tag: null); + } + + public static HtmlString ValidationSummary([NotNull] this IHtmlHelper htmlHelper, + string message, + IDictionary htmlAttributes, + string tag) + { + return htmlHelper.ValidationSummary(excludePropertyErrors: false, + message: message, + htmlAttributes: htmlAttributes, + tag: tag); } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs index 3c81a06c39..dd7ef26d2a 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelper.cs @@ -447,8 +447,10 @@ namespace Microsoft.AspNet.Mvc.Rendering /// An object that contains the HTML attributes to set for the element. /// Alternatively, an instance containing the HTML attributes. /// + /// The tag to wrap the in the generated HTML. + /// Its default value is . /// An that contains the validation message - HtmlString ValidationMessage(string modelName, string message, object htmlAttributes); + HtmlString ValidationMessage(string modelName, string message, object htmlAttributes, string tag); /// /// Returns an unordered list (ul element) of validation messages that are in the @@ -458,12 +460,15 @@ namespace Microsoft.AspNet.Mvc.Rendering /// have the summary display all errors. /// The message to display with the validation summary. /// A dictionary that contains the HTML attributes for the element. + /// The tag to wrap the in the generated HTML. + /// Its default value is . /// An that contains an unordered list (ul element) of validation messages. /// HtmlString ValidationSummary( bool excludePropertyErrors, string message, - IDictionary htmlAttributes); + IDictionary htmlAttributes, + string tag); /// /// Returns the model value for the given expression . diff --git a/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelperOfT.cs b/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelperOfT.cs index 1f537dc549..7b934507cd 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelperOfT.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Rendering/IHtmlHelperOfT.cs @@ -253,9 +253,13 @@ namespace Microsoft.AspNet.Mvc.Rendering /// An object that contains the HTML attributes to set for the element. /// Alternatively, an /// instance containing the HTML attributes. /// + /// The tag to wrap the in the generated HTML. + /// Its default value is . /// An that contains the validation message HtmlString ValidationMessageFor([NotNull] Expression> expression, - string message, object htmlAttributes); + string message, + object htmlAttributes, + string tag); /// /// Returns the model value for the given expression . diff --git a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/DefaultViewComponentResultHelper.cs b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/DefaultViewComponentResultHelper.cs index 5ba316e75d..4fde664ca3 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/DefaultViewComponentResultHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/DefaultViewComponentResultHelper.cs @@ -14,17 +14,17 @@ namespace Microsoft.AspNet.Mvc _viewEngine = viewEngine; } - public IViewComponentResult Content([NotNull] string content) + public virtual ContentViewComponentResult Content([NotNull] string content) { return new ContentViewComponentResult(content); } - public IViewComponentResult Json([NotNull] object value) + public virtual JsonViewComponentResult Json([NotNull] object 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); } diff --git a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/IViewComponentResultHelper.cs b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/IViewComponentResultHelper.cs index fc4569bc45..5be2e44f5e 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/IViewComponentResultHelper.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/IViewComponentResultHelper.cs @@ -7,10 +7,10 @@ namespace Microsoft.AspNet.Mvc { 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); } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewComponent.cs b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewComponent.cs index 734ab88e12..3504f51efd 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewComponent.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ViewComponents/ViewComponent.cs @@ -35,27 +35,37 @@ namespace Microsoft.AspNet.Mvc public ViewDataDictionary ViewData { get; set; } + public ContentViewComponentResult Content(string content) + { + return Result.Content(content); + } + public void Initialize(IViewComponentResultHelper result) { Result = result; } - public IViewComponentResult View() + public JsonViewComponentResult Json(object value) + { + return Result.Json(value); + } + + public ViewViewComponentResult View() { return View(null, null); } - public IViewComponentResult View(string viewName) + public ViewViewComponentResult View(string viewName) { return View(viewName, null); } - public IViewComponentResult View(TModel model) + public ViewViewComponentResult View(TModel model) { return View(null, model); } - public IViewComponentResult View(string viewName, TModel model) + public ViewViewComponentResult View(string viewName, TModel model) { var viewData = new ViewDataDictionary(ViewData); if (model != null) diff --git a/src/Microsoft.AspNet.Mvc.Core/ViewContext.cs b/src/Microsoft.AspNet.Mvc.Core/ViewContext.cs index 67484b980d..7f3c47ca9d 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ViewContext.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ViewContext.cs @@ -29,6 +29,8 @@ namespace Microsoft.AspNet.Mvc _formContext = _defaultFormContext; UnobtrusiveJavaScriptEnabled = true; ClientValidationEnabled = true; + ValidationSummaryMessageElement = "span"; + ValidationMessageElement = "span"; } public ViewContext( @@ -41,6 +43,8 @@ namespace Microsoft.AspNet.Mvc _formContext = viewContext.FormContext; UnobtrusiveJavaScriptEnabled = viewContext.UnobtrusiveJavaScriptEnabled; ClientValidationEnabled = viewContext.ClientValidationEnabled; + ValidationSummaryMessageElement = viewContext.ValidationSummaryMessageElement; + ValidationMessageElement = viewContext.ValidationMessageElement; View = view; ViewData = viewData; @@ -64,6 +68,18 @@ namespace Microsoft.AspNet.Mvc public bool ClientValidationEnabled { get; set; } + /// + /// Element name used to wrap a top-level message generated by + /// and other overloads. + /// + public string ValidationSummaryMessageElement { get; set; } + + /// + /// Element name used to wrap a top-level message generated by + /// and other overloads. + /// + public string ValidationMessageElement { get; set; } + public dynamic ViewBag { get diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/RedirectResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/RedirectResultTest.cs new file mode 100644 index 0000000000..7a7f62b967 --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ActionResults/RedirectResultTest.cs @@ -0,0 +1,108 @@ +// 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; +using System.Collections.Generic; +using Microsoft.AspNet.Http; +using Microsoft.AspNet.Routing; +using Microsoft.Framework.DependencyInjection; +using Microsoft.Framework.DependencyInjection.Fallback; +using Moq; +using Xunit; + +namespace Microsoft.AspNet.Mvc.Core.Test +{ + public class RedirectResultTest + { + [Theory] + [InlineData("", "/Home/About", "/Home/About")] + [InlineData("/myapproot", "/test", "/test")] + public void Execute_ReturnsContentPath_WhenItDoesNotStartWithTilde(string appRoot, + string contentPath, + string expectedPath) + { + // Arrange + var httpResponse = new Mock(); + httpResponse.Setup(o => o.Redirect(expectedPath, false)) + .Verifiable(); + + var httpContext = GetHttpContext(appRoot, contentPath, expectedPath, httpResponse.Object); + var actionContext = GetActionContext(httpContext); + var result = new RedirectResult(contentPath); + + // Act + result.ExecuteResult(actionContext); + + // Assert + // Verifying if Redirect was called with the specific Url and parameter flag. + httpResponse.Verify(); + } + + [Theory] + [InlineData(null, "~/Home/About", "/Home/About")] + [InlineData("/", "~/Home/About", "/Home/About")] + [InlineData("/", "~/", "/")] + [InlineData("", "~/Home/About", "/Home/About")] + [InlineData("/myapproot", "~/", "/myapproot/")] + [InlineData("", "~/Home/About", "/Home/About")] + [InlineData("/myapproot", "~/", "/myapproot/")] + public void Execute_ReturnsAppRelativePath_WhenItStartsWithTilde(string appRoot, + string contentPath, + string expectedPath) + { + // Arrange + var httpResponse = new Mock(); + httpResponse.Setup(o => o.Redirect(expectedPath, false)) + .Verifiable(); + + var httpContext = GetHttpContext(appRoot, contentPath, expectedPath, httpResponse.Object); + var actionContext = GetActionContext(httpContext); + var result = new RedirectResult(contentPath); + + // Act + result.ExecuteResult(actionContext); + + // Assert + // Verifying if Redirect was called with the specific Url and parameter flag. + httpResponse.Verify(); + } + + private static ActionContext GetActionContext(HttpContext httpContext) + { + return new ActionContext(httpContext, + Mock.Of(), + new Dictionary(), + new ActionDescriptor()); + } + + private static IServiceProvider GetServiceProvider(IUrlHelper urlHelper) + { + var serviceCollection = new ServiceCollection(); + serviceCollection.AddInstance(urlHelper); + return serviceCollection.BuildServiceProvider(); + } + + private static HttpContext GetHttpContext(string appRoot, + string contentPath, + string expectedPath, + HttpResponse response) + { + var httpContext = new Mock(); + var actionContext = GetActionContext(httpContext.Object); + var mockContentAccessor = new Mock>(); + mockContentAccessor.SetupGet(o => o.Value).Returns(actionContext); + var mockActionSelector = new Mock(); + var urlHelper = new UrlHelper(mockContentAccessor.Object, mockActionSelector.Object); + var serviceProvider = GetServiceProvider(urlHelper); + + httpContext.Setup(o => o.Response) + .Returns(response); + httpContext.SetupGet(o => o.RequestServices) + .Returns(serviceProvider); + httpContext.Setup(o => o.Request.PathBase) + .Returns(new PathString(appRoot)); + + return httpContext.Object; + } + } +} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj b/test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj index 54aa5c4496..f150153062 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj @@ -25,6 +25,7 @@ + @@ -54,6 +55,7 @@ + - \ No newline at end of file + diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponentTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponentTests.cs new file mode 100644 index 0000000000..f18ee36211 --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ViewComponentTests.cs @@ -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(It.IsAny()); + var resultMock = new Mock("TestContent"); + resultHelperMock.Setup(r => r.Content(It.IsAny())) + .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(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(); + + // 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(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); + } + + [Fact] + public void ViewComponent_View_WithViewNameParameter_CallsResultViewWithCustomViewName() + { + // 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); + } + + [Fact] + public void ViewComponent_View_WithModelParameter_CallsResultViewWithDefaultViewNameAndModel() + { + // 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); + } + + [Fact] + public void ViewComponent_View_WithViewNameAndModelParameters_CallsResultViewWithCustomViewNameAndModel() + { + // 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); + } + + private class TestViewComponent : ViewComponent + { + } + } +}