ProducesAttribute +
Adding Functional Tests Conflicts: src/Microsoft.AspNet.Mvc.Core/Formatters/OutputFormatter.cs src/Microsoft.AspNet.Mvc.Core/Resources.resx src/Microsoft.AspNet.Mvc.HeaderValueAbstractions/project.json test/Microsoft.AspNet.Mvc.FunctionalTests/project.json Adding Resources + tests Conflicts: src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs src/Microsoft.AspNet.Mvc.Core/Resources.resx Adding produces content Attribute Conflicts: src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj Conflicts: src/Microsoft.AspNet.Mvc.Core/Microsoft.AspNet.Mvc.Core.kproj test/Microsoft.AspNet.Mvc.Core.Test/Microsoft.AspNet.Mvc.Core.Test.kproj
This commit is contained in:
parent
099adda3d7
commit
6ee034e64f
17
Mvc.sln
17
Mvc.sln
|
|
@ -61,6 +61,12 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.Header
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.HeaderValueAbstractions.Tests", "test\Microsoft.AspNet.Mvc.HeaderValueAbstractions.Test\Microsoft.AspNet.Mvc.HeaderValueAbstractions.Tests.kproj", "{E69FD235-2042-43A4-9970-59CB29955B4E}"
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.HeaderValueAbstractions.Tests", "test\Microsoft.AspNet.Mvc.HeaderValueAbstractions.Test\Microsoft.AspNet.Mvc.HeaderValueAbstractions.Tests.kproj", "{E69FD235-2042-43A4-9970-59CB29955B4E}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FAD65E9C-3CF3-4F68-9757-C7358604030B}"
|
||||||
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
global.json = global.json
|
||||||
|
EndProjectSection
|
||||||
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ConnegWebsite", "test\WebSites\ConnegWebSite\ConnegWebsite.kproj", "{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|
@ -321,6 +327,16 @@ Global
|
||||||
{E69FD235-2042-43A4-9970-59CB29955B4E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
{E69FD235-2042-43A4-9970-59CB29955B4E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
{E69FD235-2042-43A4-9970-59CB29955B4E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
{E69FD235-2042-43A4-9970-59CB29955B4E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
{E69FD235-2042-43A4-9970-59CB29955B4E}.Release|x86.ActiveCfg = Release|Any CPU
|
{E69FD235-2042-43A4-9970-59CB29955B4E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
|
{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||||
|
{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
|
{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
|
{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
@ -352,5 +368,6 @@ Global
|
||||||
{14F79E79-AE79-48FA-95DE-D794EF4EABB3} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
{14F79E79-AE79-48FA-95DE-D794EF4EABB3} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
|
{98335B23-E4B9-4CAD-9749-0DED32A659A1} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
|
||||||
{E69FD235-2042-43A4-9970-59CB29955B4E} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
{E69FD235-2042-43A4-9970-59CB29955B4E} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||||
|
{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,12 @@ namespace MvcSample.Web
|
||||||
Context.Response.WriteAsync("Hello World raw");
|
Context.Response.WriteAsync("Hello World raw");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Produces("application/json", "application/custom", "text/json", Type = typeof(User))]
|
||||||
|
public object ReturnUser()
|
||||||
|
{
|
||||||
|
return CreateUser();
|
||||||
|
}
|
||||||
|
|
||||||
public User CreateUser()
|
public User CreateUser()
|
||||||
{
|
{
|
||||||
User user = new User()
|
User user = new User()
|
||||||
|
|
|
||||||
|
|
@ -71,9 +71,11 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
if (selectedFormatter == null)
|
if (selectedFormatter == null)
|
||||||
{
|
{
|
||||||
|
var requestContentType = formatterContext.ActionContext.HttpContext.Request.ContentType;
|
||||||
|
|
||||||
// No formatter found based on accept headers, fall back on request contentType.
|
// No formatter found based on accept headers, fall back on request contentType.
|
||||||
var incomingContentType =
|
MediaTypeHeaderValue incomingContentType = null;
|
||||||
MediaTypeHeaderValue.Parse(formatterContext.ActionContext.HttpContext.Request.ContentType);
|
MediaTypeHeaderValue.TryParse(requestContentType, out incomingContentType);
|
||||||
|
|
||||||
// In case the incomingContentType is null (as can be the case with get requests),
|
// In case the incomingContentType is null (as can be the case with get requests),
|
||||||
// we need to pick the first formatter which
|
// we need to pick the first formatter which
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
// 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 System.Linq;
|
||||||
|
using Microsoft.AspNet.Mvc.Core;
|
||||||
|
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies the allowed content types and the type of the value returned by the action
|
||||||
|
/// which can be used to select a formatter while executing <see cref="ObjectResult"/>.
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
|
||||||
|
public class ProducesAttribute : ResultFilterAttribute, IProducesMetadataProvider
|
||||||
|
{
|
||||||
|
public ProducesAttribute(string contentType, params string[] additionalContentTypes)
|
||||||
|
{
|
||||||
|
ContentTypes = GetContentTypes(contentType, additionalContentTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type Type { get; set; }
|
||||||
|
|
||||||
|
public IList<MediaTypeHeaderValue> ContentTypes { get; set; }
|
||||||
|
|
||||||
|
public override void OnResultExecuting([NotNull] ResultExecutingContext context)
|
||||||
|
{
|
||||||
|
base.OnResultExecuting(context);
|
||||||
|
var objectResult = context.Result as ObjectResult;
|
||||||
|
|
||||||
|
if (objectResult != null)
|
||||||
|
{
|
||||||
|
objectResult.ContentTypes = ContentTypes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<MediaTypeHeaderValue> GetContentTypes(string firstArg, string[] args)
|
||||||
|
{
|
||||||
|
var contentTypes = new List<MediaTypeHeaderValue>();
|
||||||
|
contentTypes.Add(MediaTypeHeaderValue.Parse(firstArg));
|
||||||
|
foreach (var item in args)
|
||||||
|
{
|
||||||
|
var contentType = MediaTypeHeaderValue.Parse(item);
|
||||||
|
contentTypes.Add(contentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return contentTypes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -53,8 +53,9 @@ namespace Microsoft.AspNet.Mvc
|
||||||
if (encoding == null)
|
if (encoding == null)
|
||||||
{
|
{
|
||||||
// Match based on request acceptHeader.
|
// Match based on request acceptHeader.
|
||||||
var requestContentType = MediaTypeHeaderValue.Parse(request.ContentType);
|
MediaTypeHeaderValue requestContentType = null;
|
||||||
if (requestContentType != null && !string.IsNullOrEmpty(requestContentType.Charset))
|
if (MediaTypeHeaderValue.TryParse(request.ContentType, out requestContentType) &&
|
||||||
|
!string.IsNullOrEmpty(requestContentType.Charset))
|
||||||
{
|
{
|
||||||
var requestCharset = requestContentType.Charset;
|
var requestCharset = requestContentType.Charset;
|
||||||
encoding = SupportedEncodings.FirstOrDefault(
|
encoding = SupportedEncodings.FirstOrDefault(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
// 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.Mvc.HeaderValueAbstractions;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides a return type and a set of possible content types returned by a successful execution of the action.
|
||||||
|
/// </summary>
|
||||||
|
public interface IProducesMetadataProvider
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Optimistic return type of the action.
|
||||||
|
/// </summary>
|
||||||
|
Type Type { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A collection of allowed content types which can be produced by the action.
|
||||||
|
/// </summary>
|
||||||
|
IList<MediaTypeHeaderValue> ContentTypes { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -35,28 +35,30 @@
|
||||||
<Compile Include="Logging\LoggerExtensions.cs" />
|
<Compile Include="Logging\LoggerExtensions.cs" />
|
||||||
<Compile Include="Logging\MvcRouteHandlerRouteAsyncValues.cs" />
|
<Compile Include="Logging\MvcRouteHandlerRouteAsyncValues.cs" />
|
||||||
<Compile Include="Logging\StringBuilderHelpers.cs" />
|
<Compile Include="Logging\StringBuilderHelpers.cs" />
|
||||||
<Compile Include="OptionDescriptors\DefaultModelBinderProvider.cs" />
|
<Compile Include="Filters\ProducesAttribute.cs" />
|
||||||
<Compile Include="OptionDescriptors\DefaultValueProviderFactoryProvider.cs" />
|
|
||||||
<Compile Include="OptionDescriptors\DefaultViewEngineProvider.cs" />
|
|
||||||
<Compile Include="OptionDescriptors\ModelBinderDescriptor.cs" />
|
|
||||||
<Compile Include="OptionDescriptors\OutputFormatterDescriptorExtensions.cs" />
|
|
||||||
<Compile Include="OptionDescriptors\ModelBinderDescriptorExtensions.cs" />
|
|
||||||
<Compile Include="OptionDescriptors\OptionDescriptorBasedProvider.cs" />
|
|
||||||
<Compile Include="OptionDescriptors\OptionDescriptor.cs" />
|
|
||||||
<Compile Include="OptionDescriptors\OutputFormatterDescriptor.cs" />
|
|
||||||
<Compile Include="OptionDescriptors\ValueProviderFactoryDescriptor.cs" />
|
|
||||||
<Compile Include="OptionDescriptors\ViewEngineDescriptor.cs" />
|
|
||||||
<Compile Include="OptionDescriptors\ValueProviderFactoryDescriptorExtensions.cs" />
|
|
||||||
<Compile Include="OptionDescriptors\ViewEngineDescriptorExtensions.cs" />
|
|
||||||
<Compile Include="Formatters\DefaultOutputFormattersProvider.cs" />
|
<Compile Include="Formatters\DefaultOutputFormattersProvider.cs" />
|
||||||
<Compile Include="Formatters\IOutputFormatter.cs" />
|
<Compile Include="Formatters\IOutputFormatter.cs" />
|
||||||
<Compile Include="Formatters\StringWithQualityHeaderValueComparer.cs" />
|
<Compile Include="Formatters\StringWithQualityHeaderValueComparer.cs" />
|
||||||
|
<Compile Include="IProducesMetadataProvider.cs" />
|
||||||
<Compile Include="Formatters\IOutputFormattersProvider.cs" />
|
<Compile Include="Formatters\IOutputFormattersProvider.cs" />
|
||||||
<Compile Include="Formatters\OutputFormatterContext.cs" />
|
<Compile Include="Formatters\OutputFormatterContext.cs" />
|
||||||
<Compile Include="Formatters\HeaderParsingHelpers.cs" />
|
<Compile Include="Formatters\HeaderParsingHelpers.cs" />
|
||||||
<Compile Include="Formatters\JsonOutputFormatter.cs" />
|
<Compile Include="Formatters\JsonOutputFormatter.cs" />
|
||||||
<Compile Include="Formatters\MediaTypeWithQualityHeaderValueComparer.cs" />
|
<Compile Include="Formatters\MediaTypeWithQualityHeaderValueComparer.cs" />
|
||||||
<Compile Include="Formatters\OutputFormatter.cs" />
|
<Compile Include="Formatters\OutputFormatter.cs" />
|
||||||
|
<Compile Include="OptionDescriptors\DefaultModelBinderProvider.cs" />
|
||||||
|
<Compile Include="OptionDescriptors\DefaultValueProviderFactoryProvider.cs" />
|
||||||
|
<Compile Include="OptionDescriptors\DefaultViewEngineProvider.cs" />
|
||||||
|
<Compile Include="OptionDescriptors\ModelBinderDescriptor.cs" />
|
||||||
|
<Compile Include="OptionDescriptors\ModelBinderDescriptorExtensions.cs" />
|
||||||
|
<Compile Include="OptionDescriptors\OptionDescriptor.cs" />
|
||||||
|
<Compile Include="OptionDescriptors\OptionDescriptorBasedProvider.cs" />
|
||||||
|
<Compile Include="OptionDescriptors\OutputFormatterDescriptor.cs" />
|
||||||
|
<Compile Include="OptionDescriptors\OutputFormatterDescriptorExtensions.cs" />
|
||||||
|
<Compile Include="OptionDescriptors\ValueProviderFactoryDescriptor.cs" />
|
||||||
|
<Compile Include="OptionDescriptors\ValueProviderFactoryDescriptorExtensions.cs" />
|
||||||
|
<Compile Include="OptionDescriptors\ViewEngineDescriptor.cs" />
|
||||||
|
<Compile Include="OptionDescriptors\ViewEngineDescriptorExtensions.cs" />
|
||||||
<Compile Include="ParameterBinding\ModelBindingHelper.cs" />
|
<Compile Include="ParameterBinding\ModelBindingHelper.cs" />
|
||||||
<Compile Include="ActionInvokerFactory.cs" />
|
<Compile Include="ActionInvokerFactory.cs" />
|
||||||
<Compile Include="ActionInvokerProviderContext.cs" />
|
<Compile Include="ActionInvokerProviderContext.cs" />
|
||||||
|
|
|
||||||
|
|
@ -52,16 +52,28 @@ namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
||||||
|
|
||||||
public static MediaTypeHeaderValue Parse(string input)
|
public static MediaTypeHeaderValue Parse(string input)
|
||||||
{
|
{
|
||||||
|
MediaTypeHeaderValue headerValue = null;
|
||||||
|
if (!TryParse(input, out headerValue))
|
||||||
|
{
|
||||||
|
throw new ArgumentException(Resources.FormatInvalidContentType(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
return headerValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryParse(string input, out MediaTypeHeaderValue headerValue)
|
||||||
|
{
|
||||||
|
headerValue = null;
|
||||||
if (string.IsNullOrEmpty(input))
|
if (string.IsNullOrEmpty(input))
|
||||||
{
|
{
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var inputArray = input.Split(new[] { ';' }, 2);
|
var inputArray = input.Split(new[] { ';' }, 2);
|
||||||
var mediaTypeParts = inputArray[0].Split('/');
|
var mediaTypeParts = inputArray[0].Split('/');
|
||||||
if (mediaTypeParts.Length != 2)
|
if (mediaTypeParts.Length != 2)
|
||||||
{
|
{
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: throw if the media type and subtypes are invalid.
|
// TODO: throw if the media type and subtypes are invalid.
|
||||||
|
|
@ -85,7 +97,7 @@ namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
||||||
parameters.TryGetValue("charset", out charset);
|
parameters.TryGetValue("charset", out charset);
|
||||||
}
|
}
|
||||||
|
|
||||||
var mediaTypeHeader = new MediaTypeHeaderValue()
|
headerValue = new MediaTypeHeaderValue()
|
||||||
{
|
{
|
||||||
MediaType = mediaType,
|
MediaType = mediaType,
|
||||||
MediaSubType = mediaSubType,
|
MediaSubType = mediaSubType,
|
||||||
|
|
@ -94,7 +106,7 @@ namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
||||||
Parameters = parameters ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase),
|
Parameters = parameters ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase),
|
||||||
};
|
};
|
||||||
|
|
||||||
return mediaTypeHeader;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Dictionary<string, string> ParseParameters(string inputString)
|
protected static Dictionary<string, string> ParseParameters(string inputString)
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,16 @@
|
||||||
<Compile Include="MediaTypeHeaderValue.cs" />
|
<Compile Include="MediaTypeHeaderValue.cs" />
|
||||||
<Compile Include="MediaTypeHeaderValueRange.cs" />
|
<Compile Include="MediaTypeHeaderValueRange.cs" />
|
||||||
<Compile Include="MediaTypeWithQualityHeaderValue.cs" />
|
<Compile Include="MediaTypeWithQualityHeaderValue.cs" />
|
||||||
|
<Compile Include="Properties\Resources.Designer.cs" />
|
||||||
<Compile Include="StringWithQualityHeaderValue.cs" />
|
<Compile Include="StringWithQualityHeaderValue.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="project.json" />
|
<Content Include="project.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="Resources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
</Project>
|
</Project>
|
||||||
46
src/Microsoft.AspNet.Mvc.HeaderValueAbstractions/Properties/Resources.Designer.cs
generated
Normal file
46
src/Microsoft.AspNet.Mvc.HeaderValueAbstractions/Properties/Resources.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
// <auto-generated />
|
||||||
|
namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
||||||
|
{
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Resources;
|
||||||
|
|
||||||
|
internal static class Resources
|
||||||
|
{
|
||||||
|
private static readonly ResourceManager _resourceManager
|
||||||
|
= new ResourceManager("Microsoft.AspNet.Mvc.HeaderValueAbstractions.Resources", typeof(Resources).GetTypeInfo().Assembly);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invalid Argument. Content type '{0}' could not be parsed.
|
||||||
|
/// </summary>
|
||||||
|
internal static string InvalidContentType
|
||||||
|
{
|
||||||
|
get { return GetString("InvalidContentType"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invalid Argument. Content type '{0}' could not be parsed.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatInvalidContentType(object p0)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("InvalidContentType"), p0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetString(string name, params string[] formatterNames)
|
||||||
|
{
|
||||||
|
var value = _resourceManager.GetString(name);
|
||||||
|
|
||||||
|
System.Diagnostics.Debug.Assert(value != null);
|
||||||
|
|
||||||
|
if (formatterNames != null)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < formatterNames.Length; i++)
|
||||||
|
{
|
||||||
|
value = value.Replace("{" + formatterNames[i] + "}", "{" + i + "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,123 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="InvalidContentType" xml:space="preserve">
|
||||||
|
<value>Invalid Argument. Content type '{0}' could not be parsed.</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
"k10": {
|
"k10": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"System.Collections": "4.0.10.0",
|
"System.Collections": "4.0.10.0",
|
||||||
|
"System.Diagnostics.Debug": "4.0.10.0",
|
||||||
|
"System.Resources.ResourceManager": "4.0.0.0",
|
||||||
"System.Runtime": "4.0.20.0",
|
"System.Runtime": "4.0.20.0",
|
||||||
"System.Runtime.Extensions": "4.0.10.0"
|
"System.Runtime.Extensions": "4.0.10.0"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
// 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.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||||
|
using Microsoft.AspNet.PipelineCore;
|
||||||
|
using Microsoft.AspNet.Routing;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc.Test
|
||||||
|
{
|
||||||
|
public class ProducesAttributeTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task ProducesContentAttribute_SetsContentType()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var mediaType1 = MediaTypeHeaderValue.Parse("application/json");
|
||||||
|
var mediaType2 = MediaTypeHeaderValue.Parse("text/json;charset=utf-8");
|
||||||
|
var producesContentAttribute = new ProducesAttribute("application/json", "text/json;charset=utf-8");
|
||||||
|
var resultExecutingContext = CreateResultExecutingContext(producesContentAttribute);
|
||||||
|
var next = new ResultExecutionDelegate(
|
||||||
|
() => Task.FromResult(CreateResultExecutedContext(resultExecutingContext)));
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await producesContentAttribute.OnResultExecutionAsync(resultExecutingContext, next);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
var objectResult = resultExecutingContext.Result as ObjectResult;
|
||||||
|
Assert.Equal(2, objectResult.ContentTypes.Count);
|
||||||
|
ValidateMediaType(mediaType1, objectResult.ContentTypes[0]);
|
||||||
|
ValidateMediaType(mediaType2, objectResult.ContentTypes[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("")]
|
||||||
|
[InlineData(null)]
|
||||||
|
[InlineData("invalid")]
|
||||||
|
public void ProducesAttribute_InvalidContentType_Throws(string content)
|
||||||
|
{
|
||||||
|
// Act & Assert
|
||||||
|
var ex = Assert.Throws<ArgumentException>(
|
||||||
|
() => new ProducesAttribute(content));
|
||||||
|
Assert.Equal("Invalid Argument. Content type '" + content + "' could not be parsed.",
|
||||||
|
ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ValidateMediaType(MediaTypeHeaderValue expectedMediaType, MediaTypeHeaderValue actualMediaType)
|
||||||
|
{
|
||||||
|
Assert.Equal(expectedMediaType.MediaType, actualMediaType.MediaType);
|
||||||
|
Assert.Equal(expectedMediaType.MediaSubType, actualMediaType.MediaSubType);
|
||||||
|
Assert.Equal(expectedMediaType.Charset, actualMediaType.Charset);
|
||||||
|
Assert.Equal(expectedMediaType.MediaTypeRange, actualMediaType.MediaTypeRange);
|
||||||
|
Assert.Equal(expectedMediaType.Parameters.Count, actualMediaType.Parameters.Count);
|
||||||
|
foreach (var item in expectedMediaType.Parameters)
|
||||||
|
{
|
||||||
|
Assert.Equal(item.Value, actualMediaType.Parameters[item.Key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ResultExecutedContext CreateResultExecutedContext(ResultExecutingContext context)
|
||||||
|
{
|
||||||
|
return new ResultExecutedContext(context, context.Filters, context.Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ResultExecutingContext CreateResultExecutingContext(IFilter filter)
|
||||||
|
{
|
||||||
|
return new ResultExecutingContext(
|
||||||
|
CreateActionContext(),
|
||||||
|
new IFilter[] { filter, },
|
||||||
|
new ObjectResult("Some Value"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ActionContext CreateActionContext()
|
||||||
|
{
|
||||||
|
return new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -31,6 +31,8 @@
|
||||||
<Compile Include="ActionResults\RedirectToActionResultTest.cs" />
|
<Compile Include="ActionResults\RedirectToActionResultTest.cs" />
|
||||||
<Compile Include="ActionResults\RedirectToRouteResultTest.cs" />
|
<Compile Include="ActionResults\RedirectToRouteResultTest.cs" />
|
||||||
<Compile Include="AntiXsrf\AntiForgeryOptionsTests.cs" />
|
<Compile Include="AntiXsrf\AntiForgeryOptionsTests.cs" />
|
||||||
|
<Compile Include="Filters\ProducesAttributeTests.cs" />
|
||||||
|
<Compile Include="Formatters\OutputFormatterTests.cs" />
|
||||||
<Compile Include="Formatters\TextPlainFormatterTests.cs" />
|
<Compile Include="Formatters\TextPlainFormatterTests.cs" />
|
||||||
<Compile Include="Logging\BeginScopeContext.cs" />
|
<Compile Include="Logging\BeginScopeContext.cs" />
|
||||||
<Compile Include="Logging\TestLoggerFactory.cs" />
|
<Compile Include="Logging\TestLoggerFactory.cs" />
|
||||||
|
|
@ -40,6 +42,7 @@
|
||||||
<Compile Include="Logging\NullLoggerFactory.cs" />
|
<Compile Include="Logging\NullLoggerFactory.cs" />
|
||||||
<Compile Include="Logging\TestSink.cs" />
|
<Compile Include="Logging\TestSink.cs" />
|
||||||
<Compile Include="Logging\TestLogger.cs" />
|
<Compile Include="Logging\TestLogger.cs" />
|
||||||
|
<Compile Include="MediaTypeWithQualityHeaderValueTests.cs" />
|
||||||
<Compile Include="MvcRouteHandlerTests.cs" />
|
<Compile Include="MvcRouteHandlerTests.cs" />
|
||||||
<Compile Include="OptionDescriptors\DefaultModelBindersProviderTest.cs" />
|
<Compile Include="OptionDescriptors\DefaultModelBindersProviderTest.cs" />
|
||||||
<Compile Include="OptionDescriptors\DefaultValueProviderFactoryProviderTest.cs" />
|
<Compile Include="OptionDescriptors\DefaultValueProviderFactoryProviderTest.cs" />
|
||||||
|
|
@ -48,12 +51,10 @@
|
||||||
<Compile Include="OptionDescriptors\ModelBinderDescriptorTest.cs" />
|
<Compile Include="OptionDescriptors\ModelBinderDescriptorTest.cs" />
|
||||||
<Compile Include="OptionDescriptors\OutputFormatterDescriptorExtensionTest.cs" />
|
<Compile Include="OptionDescriptors\OutputFormatterDescriptorExtensionTest.cs" />
|
||||||
<Compile Include="OptionDescriptors\OutputFormatterDescriptorTest.cs" />
|
<Compile Include="OptionDescriptors\OutputFormatterDescriptorTest.cs" />
|
||||||
|
<Compile Include="OptionDescriptors\ValueProviderFactoryDescriptorExtensionsTest.cs" />
|
||||||
<Compile Include="OptionDescriptors\ValueProviderFactoryDescriptorTest.cs" />
|
<Compile Include="OptionDescriptors\ValueProviderFactoryDescriptorTest.cs" />
|
||||||
<Compile Include="OptionDescriptors\ViewEngineDescriptorTest.cs" />
|
<Compile Include="OptionDescriptors\ViewEngineDescriptorTest.cs" />
|
||||||
<Compile Include="OptionDescriptors\ValueProviderFactoryDescriptorExtensionsTest.cs" />
|
|
||||||
<Compile Include="OptionDescriptors\ViewEngineDscriptorExtensionsTest.cs" />
|
<Compile Include="OptionDescriptors\ViewEngineDscriptorExtensionsTest.cs" />
|
||||||
<Compile Include="Formatters\OutputFormatterTests.cs" />
|
|
||||||
<Compile Include="MediaTypeWithQualityHeaderValueTests.cs" />
|
|
||||||
<Compile Include="ParameterBinding\ModelBindingHelperTest.cs" />
|
<Compile Include="ParameterBinding\ModelBindingHelperTest.cs" />
|
||||||
<Compile Include="AntiXsrf\AntiForgeryTokenSerializerTest.cs" />
|
<Compile Include="AntiXsrf\AntiForgeryTokenSerializerTest.cs" />
|
||||||
<Compile Include="AntiXsrf\ITokenProvider.cs" />
|
<Compile Include="AntiXsrf\ITokenProvider.cs" />
|
||||||
|
|
@ -92,8 +93,8 @@
|
||||||
<Compile Include="Rendering\DefaultDisplayTemplatesTests.cs" />
|
<Compile Include="Rendering\DefaultDisplayTemplatesTests.cs" />
|
||||||
<Compile Include="Rendering\DefaultEditorTemplatesTests.cs" />
|
<Compile Include="Rendering\DefaultEditorTemplatesTests.cs" />
|
||||||
<Compile Include="Rendering\DefaultTemplatesUtilities.cs" />
|
<Compile Include="Rendering\DefaultTemplatesUtilities.cs" />
|
||||||
<Compile Include="Rendering\HtmlHelperDisplayNameExtensionsTest.cs" />
|
|
||||||
<Compile Include="Rendering\HtmlAttributePropertyHelperTest.cs" />
|
<Compile Include="Rendering\HtmlAttributePropertyHelperTest.cs" />
|
||||||
|
<Compile Include="Rendering\HtmlHelperDisplayNameExtensionsTest.cs" />
|
||||||
<Compile Include="Rendering\HtmlHelperDisplayTextTest.cs" />
|
<Compile Include="Rendering\HtmlHelperDisplayTextTest.cs" />
|
||||||
<Compile Include="Rendering\HtmlHelperLabelExtensionsTest.cs" />
|
<Compile Include="Rendering\HtmlHelperLabelExtensionsTest.cs" />
|
||||||
<Compile Include="Rendering\HtmlHelperNameExtensionsTest.cs" />
|
<Compile Include="Rendering\HtmlHelperNameExtensionsTest.cs" />
|
||||||
|
|
@ -103,10 +104,10 @@
|
||||||
<Compile Include="KnownRouteValueConstraintTests.cs" />
|
<Compile Include="KnownRouteValueConstraintTests.cs" />
|
||||||
<Compile Include="Routing\AttributeRoutePrecedenceTests.cs" />
|
<Compile Include="Routing\AttributeRoutePrecedenceTests.cs" />
|
||||||
<Compile Include="Routing\AttributeRouteTemplateTests.cs" />
|
<Compile Include="Routing\AttributeRouteTemplateTests.cs" />
|
||||||
|
<Compile Include="Routing\AttributeRouteTests.cs" />
|
||||||
<Compile Include="Routing\AttributeRoutingTest.cs" />
|
<Compile Include="Routing\AttributeRoutingTest.cs" />
|
||||||
<Compile Include="StaticActionDiscoveryConventions.cs" />
|
<Compile Include="StaticActionDiscoveryConventions.cs" />
|
||||||
<Compile Include="StaticControllerAssemblyProvider.cs" />
|
<Compile Include="StaticControllerAssemblyProvider.cs" />
|
||||||
<Compile Include="Routing\AttributeRouteTests.cs" />
|
|
||||||
<Compile Include="TestController.cs" />
|
<Compile Include="TestController.cs" />
|
||||||
<Compile Include="TypeHelperTest.cs" />
|
<Compile Include="TypeHelperTest.cs" />
|
||||||
<Compile Include="UrlHelperTest.cs" />
|
<Compile Include="UrlHelperTest.cs" />
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.AspNet.Http": "1.0.0-*",
|
"Microsoft.AspNet.Http": "1.0.0-*",
|
||||||
|
"Microsoft.AspNet.PipelineCore": "1.0.0-*",
|
||||||
"Microsoft.AspNet.Mvc.HeaderValueAbstractions": "1.0.0-*",
|
"Microsoft.AspNet.Mvc.HeaderValueAbstractions": "1.0.0-*",
|
||||||
"Microsoft.AspNet.Mvc" : "",
|
"Microsoft.AspNet.Mvc" : "",
|
||||||
"Microsoft.AspNet.Mvc.Core" : "",
|
"Microsoft.AspNet.Mvc.Core" : "",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,253 @@
|
||||||
|
// 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.Threading.Tasks;
|
||||||
|
using ConnegWebsite;
|
||||||
|
using Microsoft.AspNet.Builder;
|
||||||
|
using Microsoft.AspNet.TestHost;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Mvc.FunctionalTests
|
||||||
|
{
|
||||||
|
public class ConnegTests
|
||||||
|
{
|
||||||
|
private readonly IServiceProvider _provider = TestHelper.CreateServices("ConnegWebsite");
|
||||||
|
private readonly Action<IBuilder> _app = new Startup().Configure;
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ProducesContentAttribute_SingleContentType_PicksTheFirstSupportedFormatter()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var server = TestServer.Create(_provider, _app);
|
||||||
|
var client = server.Handler;
|
||||||
|
|
||||||
|
// Selects custom even though it is last in the list.
|
||||||
|
var expectedContentType = "application/custom;charset=utf-8";
|
||||||
|
var expectedBody = "Written using custom format.";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await client.GetAsync("http://localhost/Normal/WriteUserUsingCustomFormat");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedContentType, result.HttpContext.Response.ContentType);
|
||||||
|
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||||
|
Assert.Equal(expectedBody, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ProducesContentAttribute_MultipleContentTypes_RunsConnegToSelectFormatter()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var server = TestServer.Create(_provider, _app);
|
||||||
|
var client = server.Handler;
|
||||||
|
var expectedContentType = "application/json;charset=utf-8";
|
||||||
|
var expectedBody = "{\r\n \"Name\": \"My name\",\r\n \"Address\": \"My address\"\r\n}";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await client.GetAsync("http://localhost/Normal/MultipleAllowedContentTypes");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedContentType, result.HttpContext.Response.ContentType);
|
||||||
|
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||||
|
Assert.Equal(expectedBody, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task NoProducesContentAttribute_ActionReturningString_RunsUsingTextFormatter()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var server = TestServer.Create(_provider, _app);
|
||||||
|
var client = server.Handler;
|
||||||
|
var expectedContentType = "text/plain;charset=utf-8";
|
||||||
|
var expectedBody = "NormalController";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await client.GetAsync("http://localhost/Normal/ReturnClassName");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedContentType, result.HttpContext.Response.ContentType);
|
||||||
|
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||||
|
Assert.Equal(expectedBody, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task NoProducesContentAttribute_ActionReturningAnyObject_RunsUsingDefaultFormatters()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var server = TestServer.Create(_provider, _app);
|
||||||
|
var client = server.Handler;
|
||||||
|
var expectedContentType = "application/json;charset=utf-8";
|
||||||
|
//var expectedBody = "\"NormalController\"";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await client.GetAsync("http://localhost/Normal/ReturnUser");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedContentType, result.HttpContext.Response.ContentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task NoMatchingFormatter_ForTheGivenContentType_Returns406()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var server = TestServer.Create(_provider, _app);
|
||||||
|
var client = server.Handler;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await client.GetAsync("http://localhost/Normal/ReturnUser_NoMatchingFormatter");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(406, result.HttpContext.Response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ProducesContentAttribute_OnAction_OverridesTheValueOnClass()
|
||||||
|
{
|
||||||
|
var server = TestServer.Create(_provider, _app);
|
||||||
|
var client = server.Handler;
|
||||||
|
|
||||||
|
// Value on the class is application/json.
|
||||||
|
var expectedContentType = "application/custom_ProducesContentBaseController_Action;charset=utf-8";
|
||||||
|
var expectedBody = "ProducesContentBaseController";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await client.GetAsync("http://localhost/ProducesContentBase/ReturnClassName");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedContentType, result.HttpContext.Response.ContentType);
|
||||||
|
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||||
|
Assert.Equal(expectedBody, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ProducesContentAttribute_OnDerivedClass_OverridesTheValueOnBaseClass()
|
||||||
|
{
|
||||||
|
var server = TestServer.Create(_provider, _app);
|
||||||
|
var client = server.Handler;
|
||||||
|
var expectedContentType = "application/custom_ProducesContentOnClassController;charset=utf-8";
|
||||||
|
var expectedBody = "ProducesContentOnClassController";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await client.GetAsync(
|
||||||
|
"http://localhost/ProducesContentOnClass/ReturnClassNameWithNoContentTypeOnAction");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedContentType, result.HttpContext.Response.ContentType);
|
||||||
|
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||||
|
Assert.Equal(expectedBody, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ProducesContentAttribute_OnDerivedAction_OverridesTheValueOnBaseClass()
|
||||||
|
{
|
||||||
|
var server = TestServer.Create(_provider, _app);
|
||||||
|
var client = server.Handler;
|
||||||
|
var expectedContentType = "application/custom_NoProducesContentOnClassController_Action;charset=utf-8";
|
||||||
|
var expectedBody = "NoProducesContentOnClassController";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await client.GetAsync("http://localhost/NoProducesContentOnClass/ReturnClassName");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedContentType, result.HttpContext.Response.ContentType);
|
||||||
|
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||||
|
Assert.Equal(expectedBody, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ProducesContentAttribute_OnDerivedAction_OverridesTheValueOnBaseAction()
|
||||||
|
{
|
||||||
|
var server = TestServer.Create(_provider, _app);
|
||||||
|
var client = server.Handler;
|
||||||
|
var expectedContentType = "application/custom_NoProducesContentOnClassController_Action;charset=utf-8";
|
||||||
|
var expectedBody = "NoProducesContentOnClassController";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await client.GetAsync("http://localhost/NoProducesContentOnClass/ReturnClassName");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedContentType, result.HttpContext.Response.ContentType);
|
||||||
|
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||||
|
Assert.Equal(expectedBody, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task ProducesContentAttribute_OnDerivedClassAndAction_OverridesTheValueOnBaseClass()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var server = TestServer.Create(_provider, _app);
|
||||||
|
var client = server.Handler;
|
||||||
|
var expectedContentType = "application/custom_ProducesContentOnClassController_Action;charset=utf-8";
|
||||||
|
var expectedBody = "ProducesContentOnClassController";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await client.GetAsync("http://localhost/ProducesContentOnClass/ReturnClassNameContentTypeOnDerivedAction");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedContentType, result.HttpContext.Response.ContentType);
|
||||||
|
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||||
|
Assert.Equal(expectedBody, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[InlineData("ReturnTaskOfString")]
|
||||||
|
[InlineData("ReturnTaskOfObject_StringValue")]
|
||||||
|
[InlineData("ReturnString")]
|
||||||
|
[InlineData("ReturnObject_StringValue")]
|
||||||
|
[InlineData("ReturnString_NullValue")]
|
||||||
|
public async Task TextPlainFormatter_ReturnsTextPlainContentType(string actionName)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var server = TestServer.Create(_provider, _app);
|
||||||
|
var client = server.Handler;
|
||||||
|
var expectedContentType = "text/plain;charset=utf-8";
|
||||||
|
var expectedBody = actionName;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await client.GetAsync("http://localhost/TextPlain/" + actionName);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedContentType, result.HttpContext.Response.ContentType);
|
||||||
|
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||||
|
Assert.Equal(expectedBody, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
[InlineData("ReturnTaskOfObject_ObjectValue")]
|
||||||
|
[InlineData("ReturnObject_ObjectValue")]
|
||||||
|
[InlineData("ReturnObject_NullValue")]
|
||||||
|
public async Task TextPlainFormatter_DoesNotSelectTextPlainFormatterForNonStringValue(string actionName)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var server = TestServer.Create(_provider, _app);
|
||||||
|
var client = server.Handler;
|
||||||
|
var expectedContentType = "application/json;charset=utf-8";
|
||||||
|
var expectedBody = actionName;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await client.GetAsync("http://localhost/TextPlain/" + actionName);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedContentType, result.HttpContext.Response.ContentType);
|
||||||
|
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
[InlineData("ReturnString_NullValue")]
|
||||||
|
public async Task TextPlainFormatter_DoesNotWriteNullValue(string actionName)
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var server = TestServer.Create(_provider, _app);
|
||||||
|
var client = server.Handler;
|
||||||
|
var expectedContentType = "text/plain;charset=utf-8";
|
||||||
|
string expectedBody = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await client.GetAsync("http://localhost/TextPlain/" + actionName);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedContentType, result.HttpContext.Response.ContentType);
|
||||||
|
var body = await result.HttpContext.Response.ReadBodyAsStringAsync();
|
||||||
|
Assert.Equal(expectedBody, body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -31,6 +31,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="BasicTests.cs" />
|
<Compile Include="BasicTests.cs" />
|
||||||
|
<Compile Include="ConnegTests.cs" />
|
||||||
<Compile Include="ViewEngineTests.cs" />
|
<Compile Include="ViewEngineTests.cs" />
|
||||||
<Compile Include="ActivatorTests.cs" />
|
<Compile Include="ActivatorTests.cs" />
|
||||||
<Compile Include="ValueProviderTests.cs" />
|
<Compile Include="ValueProviderTests.cs" />
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
"ActivatorWebSite": "",
|
"ActivatorWebSite": "",
|
||||||
"BasicWebSite": "",
|
"BasicWebSite": "",
|
||||||
"CompositeViewEngine": "",
|
"CompositeViewEngine": "",
|
||||||
|
"ConnegWebsite": "",
|
||||||
"FormatterWebSite": "",
|
"FormatterWebSite": "",
|
||||||
"InlineConstraintsWebSite": "",
|
"InlineConstraintsWebSite": "",
|
||||||
"Microsoft.AspNet.TestHost": "1.0.0-*",
|
"Microsoft.AspNet.TestHost": "1.0.0-*",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="__ToolsVersion__" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">12.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>c6e5affa-890a-448f-8de3-878b1d3c9fc7</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="$(OutputType) == 'Console'">
|
||||||
|
<DebuggerFlavor>ConsoleDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="$(OutputType) == 'Web'">
|
||||||
|
<DebuggerFlavor>WebDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="Configuration">
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="Configuration">
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Project.json" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Controllers\NormalController.cs" />
|
||||||
|
<Compile Include="Controllers\NoProducesContentOnClassController.cs" />
|
||||||
|
<Compile Include="Controllers\ProducesContentBaseController.cs" />
|
||||||
|
<Compile Include="Controllers\ProducesContentOnClassController.cs" />
|
||||||
|
<Compile Include="Controllers\HomeController.cs" />
|
||||||
|
<Compile Include="Controllers\TextPlainController.cs" />
|
||||||
|
<Compile Include="Models\User.cs" />
|
||||||
|
<Compile Include="ContentType.cs" />
|
||||||
|
<Compile Include="PlainTextFormatter.cs" />
|
||||||
|
<Compile Include="Startup.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
// 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.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
|
using Microsoft.AspNet.Mvc;
|
||||||
|
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||||
|
|
||||||
|
namespace ConnegWebsite
|
||||||
|
{
|
||||||
|
public class CustomFormatter : OutputFormatter
|
||||||
|
{
|
||||||
|
public string ContentType { get; private set; }
|
||||||
|
|
||||||
|
public CustomFormatter(string contentType)
|
||||||
|
{
|
||||||
|
ContentType = contentType;
|
||||||
|
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse(contentType));
|
||||||
|
SupportedEncodings.Add(Encoding.GetEncoding("utf-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue contentType)
|
||||||
|
{
|
||||||
|
if (base.CanWriteResult(context, contentType))
|
||||||
|
{
|
||||||
|
var actionReturnString = context.Object as string;
|
||||||
|
if (actionReturnString != null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task WriteResponseBodyAsync(OutputFormatterContext context)
|
||||||
|
{
|
||||||
|
var response = context.ActionContext.HttpContext.Response;
|
||||||
|
response.ContentType = ContentType + ";charset=utf-8";
|
||||||
|
await response.WriteAsync(context.Object as string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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 ConnegWebsite
|
||||||
|
{
|
||||||
|
public class HomeController : Controller
|
||||||
|
{
|
||||||
|
public IActionResult Index()
|
||||||
|
{
|
||||||
|
return new JsonResult("Index Method");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
// 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 ConnegWebsite
|
||||||
|
{
|
||||||
|
public class NoProducesContentOnClassController : ProducesContentBaseController
|
||||||
|
{
|
||||||
|
public override void OnActionExecuted(ActionExecutedContext context)
|
||||||
|
{
|
||||||
|
var result = context.Result as ObjectResult;
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
result.Formatters.Add(new CustomFormatter("application/custom_NoProducesContentOnClassController_Action"));
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnActionExecuted(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Produces("application/custom_NoProducesContentOnClassController_Action")]
|
||||||
|
public override string ReturnClassName()
|
||||||
|
{
|
||||||
|
// should be written using the formatter provided by this action and not the base action.
|
||||||
|
return "NoProducesContentOnClassController";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
// 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 ConnegWebsite
|
||||||
|
{
|
||||||
|
public class NormalController : Controller
|
||||||
|
{
|
||||||
|
public override void OnActionExecuted(ActionExecutedContext context)
|
||||||
|
{
|
||||||
|
var result = context.Result as ObjectResult;
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
result.Formatters.Add(new PlainTextFormatter());
|
||||||
|
result.Formatters.Add(new CustomFormatter("application/custom"));
|
||||||
|
result.Formatters.Add(new JsonOutputFormatter(JsonOutputFormatter.CreateDefaultSettings(),
|
||||||
|
indent: true));
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnActionExecuted(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ReturnClassName()
|
||||||
|
{
|
||||||
|
return "NormalController";
|
||||||
|
}
|
||||||
|
|
||||||
|
public User ReturnUser()
|
||||||
|
{
|
||||||
|
return CreateUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Produces("application/NoFormatter")]
|
||||||
|
public User ReturnUser_NoMatchingFormatter()
|
||||||
|
{
|
||||||
|
return CreateUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Produces("application/custom", "application/json", "text/json")]
|
||||||
|
public User MultipleAllowedContentTypes()
|
||||||
|
{
|
||||||
|
return CreateUser();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Produces("application/custom")]
|
||||||
|
public string WriteUserUsingCustomFormat()
|
||||||
|
{
|
||||||
|
return "Written using custom format.";
|
||||||
|
}
|
||||||
|
|
||||||
|
[NonAction]
|
||||||
|
public User CreateUser()
|
||||||
|
{
|
||||||
|
User user = new User()
|
||||||
|
{
|
||||||
|
Name = "My name",
|
||||||
|
Address = "My address",
|
||||||
|
};
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
// 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 ConnegWebsite
|
||||||
|
{
|
||||||
|
[Produces("application/custom_ProducesContentBaseController")]
|
||||||
|
public class ProducesContentBaseController : Controller
|
||||||
|
{
|
||||||
|
public override void OnActionExecuted(ActionExecutedContext context)
|
||||||
|
{
|
||||||
|
var result = context.Result as ObjectResult;
|
||||||
|
if(result != null)
|
||||||
|
{
|
||||||
|
result.Formatters.Add(new PlainTextFormatter());
|
||||||
|
result.Formatters.Add(new CustomFormatter("application/custom_ProducesContentBaseController"));
|
||||||
|
result.Formatters.Add(new CustomFormatter("application/custom_ProducesContentBaseController_Action"));
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnActionExecuted(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Produces("application/custom_ProducesContentBaseController_Action")]
|
||||||
|
public virtual string ReturnClassName()
|
||||||
|
{
|
||||||
|
// Should be written using the action's content type. Overriding the one at the class.
|
||||||
|
return "ProducesContentBaseController";
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual string ReturnClassNameWithNoContentTypeOnAction()
|
||||||
|
{
|
||||||
|
// Should be written using the action's content type. Overriding the one at the class.
|
||||||
|
return "ProducesContentBaseController";
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual string ReturnClassNameContentTypeOnDerivedAction()
|
||||||
|
{
|
||||||
|
return "ProducesContentBaseController";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
// 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 ConnegWebsite
|
||||||
|
{
|
||||||
|
[Produces("application/custom_ProducesContentOnClassController")]
|
||||||
|
public class ProducesContentOnClassController : ProducesContentBaseController
|
||||||
|
{
|
||||||
|
public override void OnActionExecuted(ActionExecutedContext context)
|
||||||
|
{
|
||||||
|
var result = context.Result as ObjectResult;
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
result.Formatters.Add(new CustomFormatter("application/custom_ProducesContentOnClassController"));
|
||||||
|
result.Formatters.Add(
|
||||||
|
new CustomFormatter("application/custom_ProducesContentOnClassController_Action"));
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnActionExecuted(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// No Content type defined by the derived class action.
|
||||||
|
public override string ReturnClassName()
|
||||||
|
{
|
||||||
|
// should be written using the content defined at base class's action.
|
||||||
|
return "ProducesContentOnClassController";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ReturnClassNameWithNoContentTypeOnAction()
|
||||||
|
{
|
||||||
|
// should be written using the content defined at derived class's class.
|
||||||
|
return "ProducesContentOnClassController";
|
||||||
|
}
|
||||||
|
|
||||||
|
[Produces("application/custom_ProducesContentOnClassController_Action")]
|
||||||
|
public override string ReturnClassNameContentTypeOnDerivedAction()
|
||||||
|
{
|
||||||
|
// should be written using the content defined at derived class's class.
|
||||||
|
return "ProducesContentOnClassController";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
// 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.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Mvc;
|
||||||
|
|
||||||
|
namespace ConnegWebsite
|
||||||
|
{
|
||||||
|
public class TextPlainController : Controller
|
||||||
|
{
|
||||||
|
public Task<string> ReturnTaskOfString()
|
||||||
|
{
|
||||||
|
return Task.FromResult<string>("ReturnTaskOfString");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<object> ReturnTaskOfObject_StringValue()
|
||||||
|
{
|
||||||
|
return Task.FromResult<object>("ReturnTaskOfObject_StringValue");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<object> ReturnTaskOfObject_ObjectValue()
|
||||||
|
{
|
||||||
|
return Task.FromResult<object>(new object());
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ReturnString()
|
||||||
|
{
|
||||||
|
return "ReturnString";
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ReturnObject_StringValue()
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ReturnObject_ObjectValue()
|
||||||
|
{
|
||||||
|
return new object();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ReturnString_NullValue()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ReturnObject_NullValue()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
// 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.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace ConnegWebsite
|
||||||
|
{
|
||||||
|
[DisplayColumn("Name")]
|
||||||
|
public class User
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
[MinLength(4)]
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Address { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
// 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.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
|
using Microsoft.AspNet.Mvc;
|
||||||
|
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||||
|
|
||||||
|
namespace ConnegWebsite
|
||||||
|
{
|
||||||
|
public class PlainTextFormatter : OutputFormatter
|
||||||
|
{
|
||||||
|
public PlainTextFormatter()
|
||||||
|
{
|
||||||
|
SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/plain"));
|
||||||
|
SupportedEncodings.Add(Encoding.GetEncoding("utf-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanWriteResult(OutputFormatterContext context, MediaTypeHeaderValue contentType)
|
||||||
|
{
|
||||||
|
if (base.CanWriteResult(context, contentType))
|
||||||
|
{
|
||||||
|
var actionReturnString = context.Object as string;
|
||||||
|
if (actionReturnString != null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task WriteResponseBodyAsync(OutputFormatterContext context)
|
||||||
|
{
|
||||||
|
var response = context.ActionContext.HttpContext.Response;
|
||||||
|
response.ContentType = "text/plain;charset=utf-8";
|
||||||
|
await response.WriteAsync(context.Object as string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
// 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.Builder;
|
||||||
|
using Microsoft.AspNet.Routing;
|
||||||
|
using Microsoft.Framework.DependencyInjection;
|
||||||
|
|
||||||
|
namespace ConnegWebsite
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public void Configure(IBuilder app)
|
||||||
|
{
|
||||||
|
var configuration = app.GetTestConfiguration();
|
||||||
|
|
||||||
|
// Set up application services
|
||||||
|
app.UseServices(services =>
|
||||||
|
{
|
||||||
|
// Add MVC services to the services container
|
||||||
|
services.AddMvc(configuration);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add MVC to the request pipeline
|
||||||
|
app.UseMvc(routes =>
|
||||||
|
{
|
||||||
|
routes.MapRoute("ActionAsMethod", "{controller}/{action}",
|
||||||
|
defaults: new { controller = "Home", action = "Index" });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.AspNet.Mvc": "",
|
||||||
|
"Microsoft.AspNet.Server.IIS": "1.0.0-*",
|
||||||
|
"Microsoft.AspNet.Mvc.TestConfiguration": ""
|
||||||
|
},
|
||||||
|
"frameworks": {
|
||||||
|
"net45": { },
|
||||||
|
"k10": { }
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue