Consume new strongly typed headers. Remove temp implementations.
This commit is contained in:
parent
8529ea2f0d
commit
91d7e382d1
|
|
@ -33,10 +33,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.Razor.
|
|||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.Test", "test\Microsoft.AspNet.Mvc.Test\Microsoft.AspNet.Mvc.Test.kproj", "{5F945B82-FE5F-425C-956C-8BC2F2020254}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.HeaderValueAbstractions", "src\Microsoft.AspNet.Mvc.HeaderValueAbstractions\Microsoft.AspNet.Mvc.HeaderValueAbstractions.kproj", "{98335B23-E4B9-4CAD-9749-0DED32A659A1}"
|
||||
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}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FAD65E9C-3CF3-4F68-9757-C7358604030B}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
global.json = global.json
|
||||
|
|
@ -178,26 +174,6 @@ Global
|
|||
{5F945B82-FE5F-425C-956C-8BC2F2020254}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{5F945B82-FE5F-425C-956C-8BC2F2020254}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{5F945B82-FE5F-425C-956C-8BC2F2020254}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E69FD235-2042-43A4-9970-59CB29955B4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E69FD235-2042-43A4-9970-59CB29955B4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E69FD235-2042-43A4-9970-59CB29955B4E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{E69FD235-2042-43A4-9970-59CB29955B4E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{E69FD235-2042-43A4-9970-59CB29955B4E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E69FD235-2042-43A4-9970-59CB29955B4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E69FD235-2042-43A4-9970-59CB29955B4E}.Release|Any CPU.Build.0 = 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|x86.ActiveCfg = Release|Any CPU
|
||||
{23D30B8C-04B1-4577-A604-ED27EA1E4A0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{23D30B8C-04B1-4577-A604-ED27EA1E4A0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{23D30B8C-04B1-4577-A604-ED27EA1E4A0E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
|
|
@ -247,8 +223,6 @@ Global
|
|||
{520B3AA4-363A-497C-8C15-80423C5AFC85} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
|
||||
{7C4F5973-0491-4028-B1DC-A9BA73FF9F77} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||
{5F945B82-FE5F-425C-956C-8BC2F2020254} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
|
||||
{E69FD235-2042-43A4-9970-59CB29955B4E} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||
{23D30B8C-04B1-4577-A604-ED27EA1E4A0E} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
|
||||
{5DE8E4D9-AACD-4B5F-819F-F091383FB996} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||
{680D75ED-601F-4D86-B01B-1072D0C31B8C} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||
|
|
|
|||
26
Mvc.sln
26
Mvc.sln
|
|
@ -53,10 +53,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "RazorWebSite", "test\WebSit
|
|||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "FormatterWebSite", "test\WebSites\FormatterWebSite\FormatterWebSite.kproj", "{62735776-46FF-4170-9392-02E128A69B89}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.HeaderValueAbstractions", "src\Microsoft.AspNet.Mvc.HeaderValueAbstractions\Microsoft.AspNet.Mvc.HeaderValueAbstractions.kproj", "{98335B23-E4B9-4CAD-9749-0DED32A659A1}"
|
||||
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}"
|
||||
EndProject
|
||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ModelBindingWebSite", "test\WebSites\ModelBindingWebSite\ModelBindingWebSite.kproj", "{EE1AB716-F102-4CA3-AD2C-214A44B459A0}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FAD65E9C-3CF3-4F68-9757-C7358604030B}"
|
||||
|
|
@ -340,26 +336,6 @@ Global
|
|||
{62735776-46FF-4170-9392-02E128A69B89}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{62735776-46FF-4170-9392-02E128A69B89}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{62735776-46FF-4170-9392-02E128A69B89}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E69FD235-2042-43A4-9970-59CB29955B4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E69FD235-2042-43A4-9970-59CB29955B4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E69FD235-2042-43A4-9970-59CB29955B4E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{E69FD235-2042-43A4-9970-59CB29955B4E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{E69FD235-2042-43A4-9970-59CB29955B4E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E69FD235-2042-43A4-9970-59CB29955B4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E69FD235-2042-43A4-9970-59CB29955B4E}.Release|Any CPU.Build.0 = 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|x86.ActiveCfg = Release|Any CPU
|
||||
{EE1AB716-F102-4CA3-AD2C-214A44B459A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EE1AB716-F102-4CA3-AD2C-214A44B459A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EE1AB716-F102-4CA3-AD2C-214A44B459A0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
|
|
@ -691,8 +667,6 @@ Global
|
|||
{5F945B82-FE5F-425C-956C-8BC2F2020254} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||
{B07CAF59-11ED-40E3-A5DB-E1178F84FA78} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
{62735776-46FF-4170-9392-02E128A69B89} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
{98335B23-E4B9-4CAD-9749-0DED32A659A1} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
|
||||
{E69FD235-2042-43A4-9970-59CB29955B4E} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||
{EE1AB716-F102-4CA3-AD2C-214A44B459A0} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
{C6E5AFFA-890A-448F-8DE3-878B1D3C9FC7} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
{A353B17E-A940-4CE8-8BF9-179E24A9041F} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
<ul>
|
||||
@foreach (var response in Model.SupportedResponseFormats)
|
||||
{
|
||||
<li>@response.MediaType.RawValue - @response.Formatter.GetType().Name</li>
|
||||
<li>@response.MediaType.ToString() - @response.Formatter.GetType().Name</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
|
|
@ -14,4 +14,9 @@
|
|||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties project_1json__JSONSchema="http://www.asp.net/media/4878834/project.json" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
|
|
@ -6,6 +6,7 @@ using System.Text;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
|
|
@ -54,11 +55,12 @@ namespace Microsoft.AspNet.Mvc
|
|||
// detached and stored in a separate file. If the receiving MUA writes
|
||||
// the entity to a file, the suggested filename should be used as a
|
||||
// basis for the actual filename, where possible.
|
||||
var headerValue = ContentDispositionUtil.GetHeaderValue(FileDownloadName);
|
||||
context.HttpContext.Response.Headers.Set("Content-Disposition", headerValue);
|
||||
var cd = new ContentDispositionHeaderValue("attachment");
|
||||
cd.SetHttpFileName(FileDownloadName);
|
||||
context.HttpContext.Response.Headers.Set(HeaderNames.ContentDisposition, cd.ToString());
|
||||
}
|
||||
|
||||
// We aren't flowing the cancellation token appropiately, see
|
||||
// We aren't flowing the cancellation token appropriately, see
|
||||
// https://github.com/aspnet/Mvc/issues/743 for details.
|
||||
return WriteFileAsync(response, CancellationToken.None);
|
||||
}
|
||||
|
|
@ -74,193 +76,5 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// A <see cref="Task"/> that will complete when the file has been written to the response.
|
||||
/// </returns>
|
||||
protected abstract Task WriteFileAsync(HttpResponse response, CancellationToken cancellation);
|
||||
|
||||
// This is a temporary implementation until we have the right abstractions in HttpAbstractions.
|
||||
internal static class ContentDispositionUtil
|
||||
{
|
||||
private const string HexDigits = "0123456789ABCDEF";
|
||||
|
||||
private static void AddByteToStringBuilder(byte b, StringBuilder builder)
|
||||
{
|
||||
builder.Append('%');
|
||||
|
||||
var i = b;
|
||||
AddHexDigitToStringBuilder(i >> 4, builder);
|
||||
AddHexDigitToStringBuilder(i % 16, builder);
|
||||
}
|
||||
|
||||
private static void AddHexDigitToStringBuilder(int digit, StringBuilder builder)
|
||||
{
|
||||
builder.Append(HexDigits[digit]);
|
||||
}
|
||||
|
||||
private static string CreateRfc2231HeaderValue(string filename)
|
||||
{
|
||||
var builder = new StringBuilder("attachment; filename*=UTF-8''");
|
||||
|
||||
var filenameBytes = Encoding.UTF8.GetBytes(filename);
|
||||
foreach (var b in filenameBytes)
|
||||
{
|
||||
if (IsByteValidHeaderValueCharacter(b))
|
||||
{
|
||||
builder.Append((char)b);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddByteToStringBuilder(b, builder);
|
||||
}
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
public static string GetHeaderValue(string fileName)
|
||||
{
|
||||
// If fileName contains any Unicode characters, encode according
|
||||
// to RFC 2231 (with clarifications from RFC 5987)
|
||||
foreach (var c in fileName)
|
||||
{
|
||||
if ((int)c > 127)
|
||||
{
|
||||
return CreateRfc2231HeaderValue(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
return CreateNonUnicodeCharactersHeaderValue(fileName);
|
||||
}
|
||||
|
||||
private static string CreateNonUnicodeCharactersHeaderValue(string fileName)
|
||||
{
|
||||
var escapedFileName = EscapeFileName(fileName);
|
||||
return string.Format("attachment; filename={0}", escapedFileName);
|
||||
}
|
||||
|
||||
private static string EscapeFileName(string fileName)
|
||||
{
|
||||
var hasToBeQuoted = false;
|
||||
|
||||
// We can't break the loop earlier because we need to check the
|
||||
// whole name for \n, in which case we need to provide a special
|
||||
// encoding.
|
||||
for (var i = 0; i < fileName.Length; i++)
|
||||
{
|
||||
if (fileName[i] == '\n')
|
||||
{
|
||||
// See RFC 2047 for more details
|
||||
return GetRfc2047Base64EncodedWord(fileName);
|
||||
}
|
||||
|
||||
// Control characters = (octets 0 - 31) and DEL (127)
|
||||
if (char.IsControl(fileName[i]))
|
||||
{
|
||||
hasToBeQuoted = true;
|
||||
}
|
||||
|
||||
switch (fileName[i])
|
||||
{
|
||||
case '(':
|
||||
case ')':
|
||||
case '<':
|
||||
case '>':
|
||||
case '@':
|
||||
case ',':
|
||||
case ';':
|
||||
case ':':
|
||||
case '\\':
|
||||
case '/':
|
||||
case '[':
|
||||
case ']':
|
||||
case '?':
|
||||
case '=':
|
||||
case '{':
|
||||
case '}':
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '"':
|
||||
hasToBeQuoted = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hasToBeQuoted ? QuoteFileName(fileName) : fileName;
|
||||
}
|
||||
|
||||
private static string QuoteFileName(string fileName)
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
builder.Append("\"");
|
||||
|
||||
for (var i = 0; i < fileName.Length; i++)
|
||||
{
|
||||
switch (fileName[i])
|
||||
{
|
||||
case '\\':
|
||||
// Escape \
|
||||
builder.Append("\\\\");
|
||||
break;
|
||||
case '"':
|
||||
// Escape "
|
||||
builder.Append("\\\"");
|
||||
break;
|
||||
default:
|
||||
builder.Append(fileName[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
builder.Append("\"");
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
private static string GetRfc2047Base64EncodedWord(string fileName)
|
||||
{
|
||||
// See RFC 2047 for details. Section 8 for examples.
|
||||
const string charset = "utf-8";
|
||||
// B means Base64
|
||||
const string encoding = "B";
|
||||
|
||||
var fileNameBytes = Encoding.UTF8.GetBytes(fileName);
|
||||
var base64EncodedFileName = Convert.ToBase64String(fileNameBytes);
|
||||
|
||||
// Encoded words are defined as "=?{charset}?{encoding}?{encpoded value}?="
|
||||
return string.Format("\"=?{0}?{1}?{2}?=\"", charset, encoding, base64EncodedFileName);
|
||||
}
|
||||
|
||||
// Application of RFC 2231 Encoding to Hypertext Transfer Protocol (HTTP) Header Fields, sec. 3.2
|
||||
// http://greenbytes.de/tech/webdav/draft-reschke-rfc2231-in-http-latest.html
|
||||
private static bool IsByteValidHeaderValueCharacter(byte b)
|
||||
{
|
||||
if ((byte)'0' <= b && b <= (byte)'9')
|
||||
{
|
||||
return true; // is digit
|
||||
}
|
||||
if ((byte)'a' <= b && b <= (byte)'z')
|
||||
{
|
||||
return true; // lowercase letter
|
||||
}
|
||||
if ((byte)'A' <= b && b <= (byte)'Z')
|
||||
{
|
||||
return true; // uppercase letter
|
||||
}
|
||||
|
||||
switch (b)
|
||||
{
|
||||
case (byte)'-':
|
||||
case (byte)'.':
|
||||
case (byte)'_':
|
||||
case (byte)'~':
|
||||
case (byte)':':
|
||||
case (byte)'!':
|
||||
case (byte)'$':
|
||||
case (byte)'&':
|
||||
case (byte)'+':
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,8 +4,8 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
|
|
@ -62,10 +63,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
public virtual IOutputFormatter SelectFormatter(OutputFormatterContext formatterContext,
|
||||
IEnumerable<IOutputFormatter> formatters)
|
||||
{
|
||||
var incomingAcceptHeader = HeaderParsingHelpers.GetAcceptHeaders(
|
||||
formatterContext.ActionContext.HttpContext.Request.Accept);
|
||||
var sortedAcceptHeaders = SortMediaTypeWithQualityHeaderValues(incomingAcceptHeader)
|
||||
.Where(header => header.Quality != HttpHeaderUtilitites.NoMatch)
|
||||
var incomingAcceptHeader = formatterContext.ActionContext.HttpContext.Request.GetTypedHeaders().Accept;
|
||||
var sortedAcceptHeaders = SortMediaTypeHeaderValues(incomingAcceptHeader)
|
||||
.Where(header => header.Quality != HeaderQuality.NoMatch)
|
||||
.ToArray();
|
||||
|
||||
IOutputFormatter selectedFormatter = null;
|
||||
|
|
@ -194,19 +194,19 @@ namespace Microsoft.AspNet.Mvc
|
|||
return selectedFormatter;
|
||||
}
|
||||
|
||||
private static MediaTypeWithQualityHeaderValue[] SortMediaTypeWithQualityHeaderValues
|
||||
(IEnumerable<MediaTypeWithQualityHeaderValue> headerValues)
|
||||
private static MediaTypeHeaderValue[] SortMediaTypeHeaderValues
|
||||
(IEnumerable<MediaTypeHeaderValue> headerValues)
|
||||
{
|
||||
if (headerValues == null)
|
||||
{
|
||||
return new MediaTypeWithQualityHeaderValue[] { };
|
||||
return new MediaTypeHeaderValue[] { };
|
||||
}
|
||||
|
||||
// Use OrderBy() instead of Array.Sort() as it performs fewer comparisons. In this case the comparisons
|
||||
// are quite expensive so OrderBy() performs better.
|
||||
return headerValues.OrderByDescending(headerValue =>
|
||||
headerValue,
|
||||
MediaTypeWithQualityHeaderValueComparer.QualityComparer)
|
||||
MediaTypeHeaderValueComparer.QualityComparer)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// 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.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Description
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.AspNet.Routing.Template;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Description
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Description
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNet.Mvc.Description;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ using System.Reflection;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.Core;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
|
|
|
|||
|
|
@ -1,103 +0,0 @@
|
|||
// 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>
|
||||
/// Implementation of <see cref="IComparer{T}"/> that can compare accept media type header fields
|
||||
/// based on their quality values (a.k.a q-values).
|
||||
/// </summary>
|
||||
public class MediaTypeWithQualityHeaderValueComparer : IComparer<MediaTypeWithQualityHeaderValue>
|
||||
{
|
||||
private static readonly MediaTypeWithQualityHeaderValueComparer _mediaTypeComparer =
|
||||
new MediaTypeWithQualityHeaderValueComparer();
|
||||
|
||||
private MediaTypeWithQualityHeaderValueComparer()
|
||||
{
|
||||
}
|
||||
|
||||
public static MediaTypeWithQualityHeaderValueComparer QualityComparer
|
||||
{
|
||||
get { return _mediaTypeComparer; }
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <remarks>
|
||||
/// Performs comparisons based on the arguments' quality values
|
||||
/// (aka their "q-value"). Values with identical q-values are considered equal (i.e. the result is 0)
|
||||
/// with the exception that subtype wildcards are considered less than specific media types and full
|
||||
/// wildcards are considered less than subtype wildcards. This allows callers to sort a sequence of
|
||||
/// <see cref="MediaTypeWithQualityHeaderValue"/> following their q-values in the order of specific
|
||||
/// media types, subtype wildcards, and last any full wildcards.
|
||||
/// </remarks>
|
||||
public int Compare(MediaTypeWithQualityHeaderValue mediaType1, MediaTypeWithQualityHeaderValue mediaType2)
|
||||
{
|
||||
if (object.ReferenceEquals(mediaType1, mediaType2))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var returnValue = CompareBasedOnQualityFactor(mediaType1, mediaType2);
|
||||
|
||||
if (returnValue == 0)
|
||||
{
|
||||
if (!mediaType1.MediaType.Equals(mediaType2.MediaType, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (mediaType1.MediaTypeRange == MediaTypeHeaderValueRange.AllMediaRange)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (mediaType2.MediaTypeRange == MediaTypeHeaderValueRange.AllMediaRange)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (mediaType1.MediaTypeRange == MediaTypeHeaderValueRange.SubtypeMediaRange &&
|
||||
mediaType2.MediaTypeRange != MediaTypeHeaderValueRange.SubtypeMediaRange)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (mediaType1.MediaTypeRange != MediaTypeHeaderValueRange.SubtypeMediaRange &&
|
||||
mediaType2.MediaTypeRange == MediaTypeHeaderValueRange.SubtypeMediaRange)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (!mediaType1.MediaSubType.Equals(mediaType2.MediaSubType, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (mediaType1.MediaTypeRange == MediaTypeHeaderValueRange.SubtypeMediaRange)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (mediaType2.MediaTypeRange == MediaTypeHeaderValueRange.SubtypeMediaRange)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private static int CompareBasedOnQualityFactor(MediaTypeWithQualityHeaderValue mediaType1,
|
||||
MediaTypeWithQualityHeaderValue mediaType2)
|
||||
{
|
||||
var mediaType1Quality = mediaType1.Quality ?? HttpHeaderUtilitites.Match;
|
||||
var mediaType2Quality = mediaType2.Quality ?? HttpHeaderUtilitites.Match;
|
||||
var qualityDifference = mediaType1Quality - mediaType2Quality;
|
||||
if (qualityDifference < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (qualityDifference > 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,8 +6,9 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.Core;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
|
|
@ -102,7 +103,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
public virtual Encoding SelectCharacterEncoding([NotNull] OutputFormatterContext context)
|
||||
{
|
||||
var request = context.ActionContext.HttpContext.Request;
|
||||
var encoding = MatchAcceptCharacterEncoding(request.AcceptCharset);
|
||||
var encoding = MatchAcceptCharacterEncoding(request.GetTypedHeaders().AcceptCharset);
|
||||
if (encoding == null)
|
||||
{
|
||||
// Match based on request acceptHeader.
|
||||
|
|
@ -190,7 +191,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
context.SelectedContentType = context.SelectedContentType ?? selectedMediaType;
|
||||
var response = context.ActionContext.HttpContext.Response;
|
||||
response.ContentType = selectedMediaType.RawValue;
|
||||
response.ContentType = selectedMediaType.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -200,16 +201,13 @@ namespace Microsoft.AspNet.Mvc
|
|||
/// <returns>A task which can write the response body.</returns>
|
||||
public abstract Task WriteResponseBodyAsync([NotNull] OutputFormatterContext context);
|
||||
|
||||
private Encoding MatchAcceptCharacterEncoding(string acceptCharsetHeader)
|
||||
private Encoding MatchAcceptCharacterEncoding(IList<StringWithQualityHeaderValue> acceptCharsetHeaders)
|
||||
{
|
||||
var acceptCharsetHeaders = HeaderParsingHelpers
|
||||
.GetAcceptCharsetHeaders(acceptCharsetHeader);
|
||||
|
||||
if (acceptCharsetHeaders != null && acceptCharsetHeaders.Count > 0)
|
||||
{
|
||||
var sortedAcceptCharsetHeaders = acceptCharsetHeaders
|
||||
.Where(acceptCharset =>
|
||||
acceptCharset.Quality != HttpHeaderUtilitites.NoMatch)
|
||||
acceptCharset.Quality != HeaderQuality.NoMatch)
|
||||
.OrderByDescending(
|
||||
m => m, StringWithQualityHeaderValueComparer.QualityComparer);
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Text;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,72 +0,0 @@
|
|||
// 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>
|
||||
/// Implementation of <see cref="IComparer{T}"/> that can compare content negotiation header fields
|
||||
/// based on their quality values (a.k.a q-values). This applies to values used in accept-charset,
|
||||
/// accept-encoding, accept-language and related header fields with similar syntax rules. See
|
||||
/// <see cref="MediaTypeWithQualityHeaderValueComparer"/> for a comparer for media type
|
||||
/// q-values.
|
||||
/// </summary>
|
||||
internal class StringWithQualityHeaderValueComparer : IComparer<StringWithQualityHeaderValue>
|
||||
{
|
||||
private static readonly StringWithQualityHeaderValueComparer _qualityComparer =
|
||||
new StringWithQualityHeaderValueComparer();
|
||||
|
||||
private StringWithQualityHeaderValueComparer()
|
||||
{
|
||||
}
|
||||
|
||||
public static StringWithQualityHeaderValueComparer QualityComparer
|
||||
{
|
||||
get { return _qualityComparer; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="StringWithQualityHeaderValue"/> based on their quality value
|
||||
/// (a.k.a their "q-value").
|
||||
/// Values with identical q-values are considered equal (i.e the result is 0) with the exception of wild-card
|
||||
/// values (i.e. a value of "*") which are considered less than non-wild-card values. This allows to sort
|
||||
/// a sequence of <see cref="StringWithQualityHeaderValue"/> following their q-values ending up with any
|
||||
/// wild-cards at the end.
|
||||
/// </summary>
|
||||
/// <param name="stringWithQuality1">The first value to compare.</param>
|
||||
/// <param name="stringWithQuality2">The second value to compare</param>
|
||||
/// <returns>The result of the comparison.</returns>
|
||||
public int Compare([NotNull] StringWithQualityHeaderValue stringWithQuality1,
|
||||
[NotNull] StringWithQualityHeaderValue stringWithQuality2)
|
||||
{
|
||||
var quality1 = stringWithQuality1.Quality ?? HttpHeaderUtilitites.Match;
|
||||
var quality2 = stringWithQuality2.Quality ?? HttpHeaderUtilitites.Match;
|
||||
var qualityDifference = quality1 - quality2;
|
||||
if (qualityDifference < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (qualityDifference > 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!String.Equals(stringWithQuality1.Value, stringWithQuality2.Value, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (String.Equals(stringWithQuality1.Value, "*", StringComparison.Ordinal))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (String.Equals(stringWithQuality2.Value, "*", StringComparison.Ordinal))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ using System.Runtime.Serialization;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
|
|
@ -14,4 +14,9 @@
|
|||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties project_1json__JSONSchema="http://www.asp.net/media/4878834/project.json" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
"dependencies": {
|
||||
"Microsoft.AspNet.FileSystems": "1.0.0-*",
|
||||
"Microsoft.AspNet.Hosting": "1.0.0-*",
|
||||
"Microsoft.AspNet.Mvc.HeaderValueAbstractions": "1.0.0-*",
|
||||
"Microsoft.AspNet.Http.Extensions": "1.0.0-*",
|
||||
"Microsoft.AspNet.Mvc.Common": { "version": "6.0.0-*", "type": "build" },
|
||||
"Microsoft.AspNet.Mvc.ModelBinding": "6.0.0-*",
|
||||
"Microsoft.AspNet.Routing": "1.0.0-*",
|
||||
|
|
|
|||
|
|
@ -1,56 +0,0 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
||||
{
|
||||
public static class HeaderParsingHelpers
|
||||
{
|
||||
public static IList<MediaTypeWithQualityHeaderValue> GetAcceptHeaders(string acceptHeader)
|
||||
{
|
||||
if (string.IsNullOrEmpty(acceptHeader))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var acceptHeaderCollection = new List<MediaTypeWithQualityHeaderValue>();
|
||||
foreach (var item in acceptHeader.Split(','))
|
||||
{
|
||||
MediaTypeWithQualityHeaderValue parsedAcceptHeader;
|
||||
// If we are unable to parse any of the Accept Headers, we ignore them completely.
|
||||
if (!MediaTypeWithQualityHeaderValue.TryParse(item, out parsedAcceptHeader))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
acceptHeaderCollection.Add(parsedAcceptHeader);
|
||||
}
|
||||
|
||||
return acceptHeaderCollection;
|
||||
}
|
||||
|
||||
public static IList<StringWithQualityHeaderValue> GetAcceptCharsetHeaders(string acceptCharsetHeader)
|
||||
{
|
||||
if (string.IsNullOrEmpty(acceptCharsetHeader))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var acceptCharsetHeaderCollection = new List<StringWithQualityHeaderValue>();
|
||||
foreach (var item in acceptCharsetHeader.Split(','))
|
||||
{
|
||||
StringWithQualityHeaderValue parsedAcceptCharsetHeader;
|
||||
// If we are unable to parse any of the Accept-Charset Headers, we ignore them completely.
|
||||
if (!StringWithQualityHeaderValue.TryParse(item, out parsedAcceptCharsetHeader))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
acceptCharsetHeaderCollection.Add(parsedAcceptCharsetHeader);
|
||||
}
|
||||
|
||||
return acceptCharsetHeaderCollection;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
||||
{
|
||||
public static class HttpHeaderUtilitites
|
||||
{
|
||||
/// <summary>
|
||||
/// Quality factor to indicate a perfect match.
|
||||
/// </summary>
|
||||
public const double Match = 1.0;
|
||||
|
||||
/// <summary>
|
||||
/// Quality factor to indicate no match.
|
||||
/// </summary>
|
||||
public const double NoMatch = 0.0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,197 +0,0 @@
|
|||
// 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.Text;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
||||
{
|
||||
public class MediaTypeHeaderValue
|
||||
{
|
||||
public string Charset { get; set; }
|
||||
|
||||
public string MediaType { get; set; }
|
||||
|
||||
public string MediaSubType { get; set; }
|
||||
|
||||
public MediaTypeHeaderValueRange MediaTypeRange { get; set; }
|
||||
|
||||
public string RawValue
|
||||
{
|
||||
get
|
||||
{
|
||||
var stringBuilder = new StringBuilder();
|
||||
stringBuilder.Append(MediaType);
|
||||
stringBuilder.Append('/');
|
||||
stringBuilder.Append(MediaSubType);
|
||||
if (!string.IsNullOrEmpty(Charset))
|
||||
{
|
||||
stringBuilder.Append(";charset=");
|
||||
stringBuilder.Append(Charset);
|
||||
}
|
||||
|
||||
foreach (var parameter in Parameters)
|
||||
{
|
||||
if (string.Equals(parameter.Key, "charset", System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
stringBuilder.Append(";");
|
||||
stringBuilder.Append(parameter.Key);
|
||||
stringBuilder.Append("=");
|
||||
stringBuilder.Append(parameter.Value);
|
||||
}
|
||||
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public IDictionary<string, string> Parameters { get; set; }
|
||||
|
||||
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))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var inputArray = input.Split(new[] { ';' }, 2);
|
||||
var mediaTypeParts = inputArray[0].Split('/');
|
||||
if (mediaTypeParts.Length != 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var mediaType = mediaTypeParts[0].Trim();
|
||||
var mediaSubType = mediaTypeParts[1].Trim();
|
||||
var mediaTypeRange = MediaTypeHeaderValueRange.None;
|
||||
if (mediaType == "*" && mediaSubType == "*")
|
||||
{
|
||||
mediaTypeRange = MediaTypeHeaderValueRange.AllMediaRange;
|
||||
}
|
||||
else if (mediaSubType == "*")
|
||||
{
|
||||
mediaTypeRange = MediaTypeHeaderValueRange.SubtypeMediaRange;
|
||||
}
|
||||
|
||||
Dictionary<string, string> parameters = null;
|
||||
string charset = null;
|
||||
if (inputArray.Length == 2)
|
||||
{
|
||||
parameters = ParseParameters(inputArray[1]);
|
||||
parameters.TryGetValue("charset", out charset);
|
||||
}
|
||||
|
||||
headerValue = new MediaTypeHeaderValue()
|
||||
{
|
||||
MediaType = mediaType,
|
||||
MediaSubType = mediaSubType,
|
||||
MediaTypeRange = mediaTypeRange,
|
||||
Charset = charset,
|
||||
Parameters = parameters ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase),
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static Dictionary<string, string> ParseParameters(string inputString)
|
||||
{
|
||||
var acceptParameters = inputString.Split(';');
|
||||
var parameterNameValue = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var parameter in acceptParameters)
|
||||
{
|
||||
var index = parameter.Split('=');
|
||||
if (index.Length == 2)
|
||||
{
|
||||
parameterNameValue.Add(index[0].Trim(), index[1].Trim());
|
||||
}
|
||||
}
|
||||
|
||||
return parameterNameValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this instance is a subset of passed <see cref="MediaTypeHeaderValue"/>.
|
||||
/// If the media type and media type parameters of this media type are all present
|
||||
/// and match those of <paramref name="otherMediaType"/> then it is a match even though
|
||||
/// <paramref name="otherMediaType"/> may have additional parameters.
|
||||
/// </summary>
|
||||
/// <param name="mediaType">The first media type.</param>
|
||||
/// <param name="otherMediaType">The second media type.</param>
|
||||
/// <returns><c>true</c> if this is a subset of <paramref name="otherMediaType"/>; false otherwise.</returns>
|
||||
public bool IsSubsetOf(MediaTypeHeaderValue otherMediaType)
|
||||
{
|
||||
if (otherMediaType == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!MediaType.Equals(otherMediaType.MediaType, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (otherMediaType.MediaTypeRange != MediaTypeHeaderValueRange.AllMediaRange)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!MediaSubType.Equals(otherMediaType.MediaSubType, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (otherMediaType.MediaTypeRange != MediaTypeHeaderValueRange.SubtypeMediaRange)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (Parameters != null)
|
||||
{
|
||||
if (Parameters.Count != 0 &&
|
||||
(otherMediaType.Parameters == null || otherMediaType.Parameters.Count == 0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// So far we either have a full match or a subset match. Now check that all of
|
||||
// mediaType1's parameters are present and equal in mediatype2
|
||||
if (!MatchParameters(Parameters, otherMediaType.Parameters))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool MatchParameters(IDictionary<string, string> parameters1,
|
||||
IDictionary<string, string> parameters2)
|
||||
{
|
||||
foreach (var parameterKey in parameters1.Keys)
|
||||
{
|
||||
string parameterValue2 = null;
|
||||
if (!parameters2.TryGetValue(parameterKey, out parameterValue2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!string.Equals(parameterValue2, parameters1[parameterKey], StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
// 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.
|
||||
|
||||
namespace Microsoft.AspNet.Mvc
|
||||
{
|
||||
public enum MediaTypeHeaderValueRange
|
||||
{
|
||||
/// <summary>
|
||||
/// Not a media type range
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// A subtype media range, e.g. "application/*".
|
||||
/// </summary>
|
||||
SubtypeMediaRange,
|
||||
|
||||
/// <summary>
|
||||
/// An all media range, e.g. "*/*".
|
||||
/// </summary>
|
||||
AllMediaRange,
|
||||
}
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
// 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.Globalization;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
||||
{
|
||||
public class MediaTypeWithQualityHeaderValue : MediaTypeHeaderValue
|
||||
{
|
||||
public double? Quality { get; private set; }
|
||||
|
||||
public static bool TryParse(string input, out MediaTypeWithQualityHeaderValue headerValue)
|
||||
{
|
||||
MediaTypeHeaderValue mediaTypeHeaderValue;
|
||||
if (!MediaTypeHeaderValue.TryParse(input, out mediaTypeHeaderValue))
|
||||
{
|
||||
headerValue = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
var quality = HttpHeaderUtilitites.Match;
|
||||
string qualityStringValue;
|
||||
if (mediaTypeHeaderValue.Parameters.TryGetValue("q", out qualityStringValue))
|
||||
{
|
||||
if (!double.TryParse(
|
||||
qualityStringValue,
|
||||
NumberStyles.AllowLeadingWhite | NumberStyles.AllowDecimalPoint |
|
||||
NumberStyles.AllowTrailingWhite,
|
||||
NumberFormatInfo.InvariantInfo,
|
||||
out quality))
|
||||
{
|
||||
headerValue = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
headerValue = new MediaTypeWithQualityHeaderValue()
|
||||
{
|
||||
MediaType = mediaTypeHeaderValue.MediaType,
|
||||
MediaSubType = mediaTypeHeaderValue.MediaSubType,
|
||||
MediaTypeRange = mediaTypeHeaderValue.MediaTypeRange,
|
||||
Charset = mediaTypeHeaderValue.Charset,
|
||||
Parameters = mediaTypeHeaderValue.Parameters,
|
||||
Quality = quality,
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static new MediaTypeWithQualityHeaderValue Parse(string input)
|
||||
{
|
||||
MediaTypeWithQualityHeaderValue headerValue = null;
|
||||
if (!MediaTypeWithQualityHeaderValue.TryParse(input, out headerValue))
|
||||
{
|
||||
throw new ArgumentException(Resources.FormatInvalidAcceptHeader(input));
|
||||
}
|
||||
|
||||
return headerValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.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>98335b23-e4b9-4cad-9749-0ded32a659a1</ProjectGuid>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
// <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. Accept Charset '{0}' could not be parsed.
|
||||
/// </summary>
|
||||
internal static string InvalidAcceptCharset
|
||||
{
|
||||
get { return GetString("InvalidAcceptCharset"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invalid Argument. Accept Charset '{0}' could not be parsed.
|
||||
/// </summary>
|
||||
internal static string FormatInvalidAcceptCharset(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("InvalidAcceptCharset"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invalid Argument. Accept Header '{0}' could not be parsed.
|
||||
/// </summary>
|
||||
internal static string InvalidAcceptHeader
|
||||
{
|
||||
get { return GetString("InvalidAcceptHeader"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invalid Argument. Accept Header '{0}' could not be parsed.
|
||||
/// </summary>
|
||||
internal static string FormatInvalidAcceptHeader(object p0)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, GetString("InvalidAcceptHeader"), p0);
|
||||
}
|
||||
|
||||
/// <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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,129 +0,0 @@
|
|||
<?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="InvalidAcceptCharset" xml:space="preserve">
|
||||
<value>Invalid Argument. Accept Charset '{0}' could not be parsed.</value>
|
||||
</data>
|
||||
<data name="InvalidAcceptHeader" xml:space="preserve">
|
||||
<value>Invalid Argument. Accept Header '{0}' could not be parsed.</value>
|
||||
</data>
|
||||
<data name="InvalidContentType" xml:space="preserve">
|
||||
<value>Invalid Argument. Content type '{0}' could not be parsed.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
// 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.Globalization;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
||||
{
|
||||
public class StringWithQualityHeaderValue
|
||||
{
|
||||
public double? Quality { get; set; }
|
||||
|
||||
public string RawValue { get; set; }
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
public static bool TryParse(string input, out StringWithQualityHeaderValue headerValue)
|
||||
{
|
||||
var inputArray = input.Split(new[] { ';' }, 2);
|
||||
var value = inputArray[0].Trim();
|
||||
|
||||
// Unspecified q factor value is equal to a match.
|
||||
var quality = HttpHeaderUtilitites.Match;
|
||||
if (inputArray.Length > 1)
|
||||
{
|
||||
var parameter = inputArray[1].Trim();
|
||||
var nameValuePair = parameter.Split(new[] { '=' }, 2);
|
||||
if (nameValuePair.Length > 1 && nameValuePair[0].Trim().Equals("q"))
|
||||
{
|
||||
if (!double.TryParse(
|
||||
nameValuePair[1],
|
||||
NumberStyles.AllowLeadingWhite | NumberStyles.AllowDecimalPoint |
|
||||
NumberStyles.AllowTrailingWhite,
|
||||
NumberFormatInfo.InvariantInfo,
|
||||
out quality))
|
||||
{
|
||||
headerValue = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var stringWithQualityHeader = new StringWithQualityHeaderValue()
|
||||
{
|
||||
Quality = quality,
|
||||
Value = value,
|
||||
RawValue = input
|
||||
};
|
||||
|
||||
headerValue = stringWithQualityHeader;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static StringWithQualityHeaderValue Parse(string input)
|
||||
{
|
||||
StringWithQualityHeaderValue headerValue;
|
||||
if (!TryParse(input, out headerValue))
|
||||
{
|
||||
throw new ArgumentException(Resources.FormatInvalidAcceptCharset(input));
|
||||
}
|
||||
|
||||
return headerValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"description": "Temporary abstractions for working with header values in ASP.NET MVC. These abstractions will be replaced by core HTTP abstractions in ASP.NET in a future release.",
|
||||
"version": "1.0.0-*",
|
||||
"dependencies": { },
|
||||
"frameworks": {
|
||||
"aspnet50": { },
|
||||
"aspnetcore50": {
|
||||
"dependencies": {
|
||||
"System.Collections": "4.0.10-beta-*",
|
||||
"System.Diagnostics.Debug": "4.0.10-beta-*",
|
||||
"System.Resources.ResourceManager": "4.0.0-beta-*",
|
||||
"System.Runtime.Extensions": "4.0.10-beta-*"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
|
|
@ -14,4 +14,9 @@
|
|||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties project_1json__JSONSchema="http://www.asp.net/media/4878834/project.json" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.ModelBinding
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
"dependencies": {
|
||||
"Microsoft.AspNet.Http": "1.0.0-*",
|
||||
"Microsoft.AspNet.Mvc.Common": { "version": "6.0.0-*", "type": "build" },
|
||||
"Microsoft.AspNet.Mvc.HeaderValueAbstractions": "1.0.0-*",
|
||||
"Microsoft.Framework.DependencyInjection": "1.0.0-*",
|
||||
"Microsoft.Net.Http.Headers": "1.0.0-*",
|
||||
"Newtonsoft.Json": "6.0.6"
|
||||
},
|
||||
"frameworks": {
|
||||
|
|
|
|||
|
|
@ -319,27 +319,11 @@ namespace System.Net.Http.Formatting
|
|||
for (var i = 0; i < supportedMediaTypes.Count; i++)
|
||||
{
|
||||
var supportedMediaType = supportedMediaTypes[i];
|
||||
MediaTypeHeaderValueRange range;
|
||||
MediaTypeFormatterMatchRanking ranking;
|
||||
if (supportedMediaType != null &&
|
||||
acceptMediaTypeValue.Quality != FormattingUtilities.NoMatch &&
|
||||
supportedMediaType.IsSubsetOf(acceptMediaTypeValue, out range))
|
||||
supportedMediaType.IsSubsetOf(acceptMediaTypeValue, out ranking))
|
||||
{
|
||||
MediaTypeFormatterMatchRanking ranking;
|
||||
switch (range)
|
||||
{
|
||||
case MediaTypeHeaderValueRange.AllMediaRange:
|
||||
ranking = MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderAllMediaRange;
|
||||
break;
|
||||
|
||||
case MediaTypeHeaderValueRange.SubtypeMediaRange:
|
||||
ranking = MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderSubtypeMediaRange;
|
||||
break;
|
||||
|
||||
default:
|
||||
ranking = MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderLiteral;
|
||||
break;
|
||||
}
|
||||
|
||||
return new MediaTypeFormatterMatch(
|
||||
formatter,
|
||||
supportedMediaType,
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ namespace System.Net.Http.Formatting
|
|||
/// <returns><c>true</c> if this is a subset of <paramref name="mediaType2"/>; false otherwise.</returns>
|
||||
public static bool IsSubsetOf(this MediaTypeHeaderValue mediaType1, MediaTypeHeaderValue mediaType2)
|
||||
{
|
||||
MediaTypeHeaderValueRange mediaType2Range;
|
||||
MediaTypeFormatterMatchRanking mediaType2Range;
|
||||
return IsSubsetOf(mediaType1, mediaType2, out mediaType2Range);
|
||||
}
|
||||
|
||||
|
|
@ -52,37 +52,41 @@ namespace System.Net.Http.Formatting
|
|||
public static bool IsSubsetOf(
|
||||
this MediaTypeHeaderValue mediaType1,
|
||||
MediaTypeHeaderValue mediaType2,
|
||||
out MediaTypeHeaderValueRange mediaType2Range)
|
||||
out MediaTypeFormatterMatchRanking mediaType2Range)
|
||||
{
|
||||
// Performance-sensitive
|
||||
Debug.Assert(mediaType1 != null);
|
||||
|
||||
if (mediaType2 == null)
|
||||
{
|
||||
mediaType2Range = MediaTypeHeaderValueRange.None;
|
||||
mediaType2Range = MediaTypeFormatterMatchRanking.None;
|
||||
return false;
|
||||
}
|
||||
|
||||
var parsedMediaType1 = new ParsedMediaTypeHeaderValue(mediaType1);
|
||||
var parsedMediaType2 = new ParsedMediaTypeHeaderValue(mediaType2);
|
||||
mediaType2Range = parsedMediaType2.IsAllMediaRange ? MediaTypeHeaderValueRange.AllMediaRange :
|
||||
parsedMediaType2.IsSubtypeMediaRange ? MediaTypeHeaderValueRange.SubtypeMediaRange :
|
||||
MediaTypeHeaderValueRange.None;
|
||||
mediaType2Range = parsedMediaType2.IsAllMediaRange ? MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderAllMediaRange :
|
||||
parsedMediaType2.IsSubtypeMediaRange ? MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderSubtypeMediaRange :
|
||||
MediaTypeFormatterMatchRanking.None;
|
||||
|
||||
if (!parsedMediaType1.TypesEqual(ref parsedMediaType2))
|
||||
{
|
||||
if (mediaType2Range != MediaTypeHeaderValueRange.AllMediaRange)
|
||||
if (mediaType2Range != MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderAllMediaRange)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!parsedMediaType1.SubTypesEqual(ref parsedMediaType2))
|
||||
{
|
||||
if (mediaType2Range != MediaTypeHeaderValueRange.SubtypeMediaRange)
|
||||
if (mediaType2Range != MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderSubtypeMediaRange)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mediaType2Range = MediaTypeFormatterMatchRanking.MatchOnRequestAcceptHeaderLiteral;
|
||||
}
|
||||
|
||||
// So far we either have a full match or a subset match. Now check that all of
|
||||
// mediaType1's parameters are present and equal in mediatype2
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using System.Linq;
|
|||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.HttpFeature;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.WebApiCompatShim
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
|
|
@ -14,4 +14,9 @@
|
|||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties project_1json__JSONSchema="http://www.asp.net/media/4878834/project.json" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
|
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.PipelineCore.Collections;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.AspNet.Testing;
|
||||
|
|
@ -21,8 +22,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// Arrange
|
||||
var expectedUrl = "testAction";
|
||||
var response = GetMockedHttpResponseObject();
|
||||
var httpContext = GetHttpContext(response);
|
||||
var httpContext = GetHttpContext();
|
||||
var actionContext = GetActionContext(httpContext);
|
||||
var urlHelper = GetMockUrlHelper(expectedUrl);
|
||||
|
||||
|
|
@ -37,16 +37,15 @@ namespace Microsoft.AspNet.Mvc
|
|||
await result.ExecuteResultAsync(actionContext);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(201, response.StatusCode);
|
||||
Assert.Equal(expectedUrl, response.Headers["Location"]);
|
||||
Assert.Equal(201, httpContext.Response.StatusCode);
|
||||
Assert.Equal(expectedUrl, httpContext.Response.Headers["Location"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreatedAtActionResult_ThrowsOnNullUrl()
|
||||
{
|
||||
// Arrange
|
||||
var response = GetMockedHttpResponseObject();
|
||||
var httpContext = GetHttpContext(response);
|
||||
var httpContext = GetHttpContext();
|
||||
var actionContext = GetActionContext(httpContext);
|
||||
var urlHelper = GetMockUrlHelper(returnValue: null);
|
||||
|
||||
|
|
@ -60,7 +59,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
// Act & Assert
|
||||
await ExceptionAssert.ThrowsAsync<InvalidOperationException>(
|
||||
async () => await result.ExecuteResultAsync(actionContext),
|
||||
async () => await result.ExecuteResultAsync(actionContext),
|
||||
"No route matches the supplied values.");
|
||||
}
|
||||
|
||||
|
|
@ -85,18 +84,15 @@ namespace Microsoft.AspNet.Mvc
|
|||
new ActionDescriptor());
|
||||
}
|
||||
|
||||
private static HttpContext GetHttpContext(HttpResponse response)
|
||||
private static HttpContext GetHttpContext()
|
||||
{
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
|
||||
httpContext.Setup(o => o.Response)
|
||||
.Returns(response);
|
||||
httpContext.Setup(o => o.RequestServices.GetService(typeof(IOutputFormattersProvider)))
|
||||
.Returns(new TestOutputFormatterProvider());
|
||||
httpContext.Setup(o => o.Request.PathBase)
|
||||
.Returns(new PathString(""));
|
||||
|
||||
return httpContext.Object;
|
||||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.Request.PathBase = new PathString("");
|
||||
httpContext.Response.Body = new MemoryStream();
|
||||
var services = new Mock<IServiceProvider>();
|
||||
services.Setup(p => p.GetService(typeof(IOutputFormattersProvider))).Returns(new TestOutputFormatterProvider());
|
||||
httpContext.RequestServices = services.Object;
|
||||
return httpContext;
|
||||
}
|
||||
|
||||
private static IUrlHelper GetMockUrlHelper(string returnValue)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.PipelineCore.Collections;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.AspNet.Testing;
|
||||
using Moq;
|
||||
|
|
@ -41,8 +41,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// Arrange
|
||||
var expectedUrl = "testAction";
|
||||
var response = GetMockedHttpResponseObject();
|
||||
var httpContext = GetHttpContext(response);
|
||||
var httpContext = GetHttpContext();
|
||||
var actionContext = GetActionContext(httpContext);
|
||||
var urlHelper = GetMockUrlHelper(expectedUrl);
|
||||
|
||||
|
|
@ -52,16 +51,15 @@ namespace Microsoft.AspNet.Mvc
|
|||
await result.ExecuteResultAsync(actionContext);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(201, response.StatusCode);
|
||||
Assert.Equal(expectedUrl, response.Headers["Location"]);
|
||||
Assert.Equal(201, httpContext.Response.StatusCode);
|
||||
Assert.Equal(expectedUrl, httpContext.Response.Headers["Location"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreatedAtRouteResult_ThrowsOnNullUrl()
|
||||
{
|
||||
// Arrange
|
||||
var response = GetMockedHttpResponseObject();
|
||||
var httpContext = GetHttpContext(response);
|
||||
var httpContext = GetHttpContext();
|
||||
var actionContext = GetActionContext(httpContext);
|
||||
var urlHelper = GetMockUrlHelper(returnValue: null);
|
||||
|
||||
|
|
@ -78,17 +76,6 @@ namespace Microsoft.AspNet.Mvc
|
|||
"No route matches the supplied values.");
|
||||
}
|
||||
|
||||
private static HttpResponse GetMockedHttpResponseObject()
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
var httpResponse = new Mock<HttpResponse>();
|
||||
httpResponse.SetupProperty(o => o.StatusCode);
|
||||
httpResponse.Setup(o => o.Headers).Returns(
|
||||
new HeaderDictionary(new Dictionary<string, string[]>()));
|
||||
httpResponse.SetupGet(o => o.Body).Returns(stream);
|
||||
return httpResponse.Object;
|
||||
}
|
||||
|
||||
private static ActionContext GetActionContext(HttpContext httpContext)
|
||||
{
|
||||
var routeData = new RouteData();
|
||||
|
|
@ -99,16 +86,21 @@ namespace Microsoft.AspNet.Mvc
|
|||
new ActionDescriptor());
|
||||
}
|
||||
|
||||
private static HttpContext GetHttpContext(HttpResponse response)
|
||||
private static HttpContext GetHttpContext()
|
||||
{
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
var realContext = new DefaultHttpContext();
|
||||
var request = realContext.Request;
|
||||
request.PathBase = new PathString("");
|
||||
var response = realContext.Response;
|
||||
response.Body = new MemoryStream();
|
||||
|
||||
httpContext.Setup(o => o.Request)
|
||||
.Returns(request);
|
||||
httpContext.Setup(o => o.Response)
|
||||
.Returns(response);
|
||||
httpContext.Setup(o => o.RequestServices.GetService(typeof(IOutputFormattersProvider)))
|
||||
.Returns(new TestOutputFormatterProvider());
|
||||
httpContext.Setup(o => o.Request.PathBase)
|
||||
.Returns(new PathString(""));
|
||||
|
||||
return httpContext.Object;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.PipelineCore.Collections;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
|
@ -32,8 +32,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
// Arrange
|
||||
var location = "/test/";
|
||||
var response = GetMockedHttpResponseObject();
|
||||
var httpContext = GetHttpContext(response);
|
||||
var httpContext = GetHttpContext();
|
||||
var actionContext = GetActionContext(httpContext);
|
||||
var result = new CreatedResult(location, "testInput");
|
||||
|
||||
|
|
@ -41,19 +40,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
await result.ExecuteResultAsync(actionContext);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(201, response.StatusCode);
|
||||
Assert.Equal(location, response.Headers["Location"]);
|
||||
}
|
||||
|
||||
private static HttpResponse GetMockedHttpResponseObject()
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
var httpResponse = new Mock<HttpResponse>();
|
||||
httpResponse.SetupProperty(o => o.StatusCode);
|
||||
httpResponse.Setup(o => o.Headers).Returns(
|
||||
new HeaderDictionary(new Dictionary<string, string[]>()));
|
||||
httpResponse.SetupGet(o => o.Body).Returns(stream);
|
||||
return httpResponse.Object;
|
||||
Assert.Equal(201, httpContext.Response.StatusCode);
|
||||
Assert.Equal(location, httpContext.Response.Headers["Location"]);
|
||||
}
|
||||
|
||||
private static ActionContext GetActionContext(HttpContext httpContext)
|
||||
|
|
@ -66,16 +54,21 @@ namespace Microsoft.AspNet.Mvc
|
|||
new ActionDescriptor());
|
||||
}
|
||||
|
||||
private static HttpContext GetHttpContext(HttpResponse response)
|
||||
private static HttpContext GetHttpContext()
|
||||
{
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
var realContext = new DefaultHttpContext();
|
||||
var request = realContext.Request;
|
||||
request.PathBase = new PathString("");
|
||||
var response = realContext.Response;
|
||||
response.Body = new MemoryStream();
|
||||
|
||||
httpContext.Setup(o => o.Request)
|
||||
.Returns(request);
|
||||
httpContext.Setup(o => o.Response)
|
||||
.Returns(response);
|
||||
httpContext.Setup(o => o.RequestServices.GetService(typeof(IOutputFormattersProvider)))
|
||||
.Returns(new TestOutputFormatterProvider());
|
||||
httpContext.Setup(o => o.Request.PathBase)
|
||||
.Returns(new PathString(""));
|
||||
|
||||
return httpContext.Object;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ using System.Net.Mime;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -30,13 +32,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
// See comment in FileResult.cs detailing how the FileDownloadName should be encoded.
|
||||
|
||||
// Arrange
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
httpContext.SetupSet(c => c.Response.ContentType = "application/my-type").Verifiable();
|
||||
httpContext
|
||||
.Setup(c => c.Response.Headers.Set("Content-Disposition", @"attachment; filename=""some\\file"""))
|
||||
.Verifiable();
|
||||
|
||||
var actionContext = CreateActionContext(httpContext.Object);
|
||||
var httpContext = new DefaultHttpContext();
|
||||
var actionContext = CreateActionContext(httpContext);
|
||||
|
||||
var result = new EmptyFileResult("application/my-type")
|
||||
{
|
||||
|
|
@ -48,22 +45,17 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
// Assert
|
||||
Assert.True(result.WasWriteFileCalled);
|
||||
httpContext.Verify();
|
||||
|
||||
Assert.Equal("application/my-type", httpContext.Response.Headers["Content-Type"]);
|
||||
Assert.Equal(@"attachment; filename=""some\\file""; filename*=UTF-8''some%5Cfile", httpContext.Response.Headers["Content-Disposition"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ContentDispositionHeader_IsEncodedCorrectly_ForUnicodeCharacters()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
httpContext.SetupSet(c => c.Response.ContentType = "application/my-type").Verifiable();
|
||||
httpContext
|
||||
.Setup(c => c.Response.Headers.Set(
|
||||
"Content-Disposition",
|
||||
@"attachment; filename*=UTF-8''ABCXYZabcxyz012789!%40%23$%25%5E&%2A%28%29-%3D_+.:~%CE%94"))
|
||||
.Verifiable();
|
||||
|
||||
var actionContext = CreateActionContext(httpContext.Object);
|
||||
var httpContext = new DefaultHttpContext();
|
||||
var actionContext = CreateActionContext(httpContext);
|
||||
|
||||
var result = new EmptyFileResult("application/my-type")
|
||||
{
|
||||
|
|
@ -75,7 +67,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
// Assert
|
||||
Assert.True(result.WasWriteFileCalled);
|
||||
httpContext.Verify();
|
||||
Assert.Equal("application/my-type", httpContext.Response.Headers["Content-Type"]);
|
||||
Assert.Equal(@"attachment; filename=""ABCXYZabcxyz012789!@#$%^&*()-=_+.:~_""; filename*=UTF-8''ABCXYZabcxyz012789!%40#$%25^&%2A%28%29-%3D_+.%3A~%CE%94",
|
||||
httpContext.Response.Headers["Content-Disposition"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -102,13 +96,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
public async Task ExecuteResultAsync_SetsContentDisposition_IfSpecified()
|
||||
{
|
||||
// Arrange
|
||||
var httpContext = new Mock<HttpContext>(MockBehavior.Strict);
|
||||
httpContext.SetupSet(c => c.Response.ContentType = "application/my-type").Verifiable();
|
||||
httpContext
|
||||
.Setup(c => c.Response.Headers.Set("Content-Disposition", "attachment; filename=filename.ext"))
|
||||
.Verifiable();
|
||||
|
||||
var actionContext = CreateActionContext(httpContext.Object);
|
||||
var httpContext = new DefaultHttpContext();
|
||||
var actionContext = CreateActionContext(httpContext);
|
||||
|
||||
var result = new EmptyFileResult("application/my-type")
|
||||
{
|
||||
|
|
@ -120,7 +109,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
// Assert
|
||||
Assert.True(result.WasWriteFileCalled);
|
||||
httpContext.Verify();
|
||||
Assert.Equal("application/my-type", httpContext.Response.ContentType);
|
||||
Assert.Equal("attachment; filename=filename.ext; filename*=UTF-8''filename.ext", httpContext.Response.Headers["Content-Disposition"]);
|
||||
}
|
||||
|
||||
public static TheoryData<string, string> ContentDispositionData
|
||||
|
|
@ -130,49 +120,54 @@ namespace Microsoft.AspNet.Mvc
|
|||
return new TheoryData<string, string>
|
||||
{
|
||||
// Non quoted values
|
||||
{ "09aAzZ", "attachment; filename=09aAzZ" },
|
||||
{ "a.b", "attachment; filename=a.b" },
|
||||
{ "#", "attachment; filename=#" },
|
||||
{ "-", "attachment; filename=-" },
|
||||
{ "_", "attachment; filename=_" },
|
||||
{ "09aAzZ", "attachment; filename=09aAzZ; filename*=UTF-8''09aAzZ" },
|
||||
{ "a.b", "attachment; filename=a.b; filename*=UTF-8''a.b" },
|
||||
{ "#", "attachment; filename=#; filename*=UTF-8''#" },
|
||||
{ "-", "attachment; filename=-; filename*=UTF-8''-" },
|
||||
{ "_", "attachment; filename=_; filename*=UTF-8''_" },
|
||||
{ "~", "attachment; filename=~; filename*=UTF-8''~" },
|
||||
{ "$", "attachment; filename=$; filename*=UTF-8''$" },
|
||||
{ "&", "attachment; filename=&; filename*=UTF-8''&" },
|
||||
{ "+", "attachment; filename=+; filename*=UTF-8''+" },
|
||||
{ "!", "attachment; filename=!; filename*=UTF-8''!" },
|
||||
{ "#", "attachment; filename=#; filename*=UTF-8''#" },
|
||||
{ "^", "attachment; filename=^; filename*=UTF-8''^" },
|
||||
{ "`", "attachment; filename=`; filename*=UTF-8''`" },
|
||||
{ "|", "attachment; filename=|; filename*=UTF-8''|" },
|
||||
|
||||
// Values that need to be quoted
|
||||
{ ": :", "attachment; filename=\": :\"" },
|
||||
{ "~", "attachment; filename=~" },
|
||||
{ "$", "attachment; filename=$" },
|
||||
{ "&", "attachment; filename=&" },
|
||||
{ "+", "attachment; filename=+" },
|
||||
{ "(", "attachment; filename=\"(\"" },
|
||||
{ ")", "attachment; filename=\")\"" },
|
||||
{ "<", "attachment; filename=\"<\"" },
|
||||
{ ">", "attachment; filename=\">\"" },
|
||||
{ "@", "attachment; filename=\"@\"" },
|
||||
{ ",", "attachment; filename=\",\"" },
|
||||
{ ";", "attachment; filename=\";\"" },
|
||||
{ ":", "attachment; filename=\":\"" },
|
||||
{ "/", "attachment; filename=\"/\"" },
|
||||
{ "[", "attachment; filename=\"[\"" },
|
||||
{ "]", "attachment; filename=\"]\"" },
|
||||
{ "?", "attachment; filename=\"?\"" },
|
||||
{ "=", "attachment; filename=\"=\"" },
|
||||
{ "{", "attachment; filename=\"{\"" },
|
||||
{ "}", "attachment; filename=\"}\"" },
|
||||
{ " ", "attachment; filename=\" \"" },
|
||||
{ "a\tb", "attachment; filename=\"a\tb\"" },
|
||||
{ "a b", "attachment; filename=\"a b\"" },
|
||||
{ ": :", "attachment; filename=\": :\"; filename*=UTF-8''%3A%20%3A" },
|
||||
{ "(", "attachment; filename=\"(\"; filename*=UTF-8''%28" },
|
||||
{ ")", "attachment; filename=\")\"; filename*=UTF-8''%29" },
|
||||
{ "<", "attachment; filename=\"<\"; filename*=UTF-8''%3C" },
|
||||
{ ">", "attachment; filename=\">\"; filename*=UTF-8''%3E" },
|
||||
{ "@", "attachment; filename=\"@\"; filename*=UTF-8''%40" },
|
||||
{ ",", "attachment; filename=\",\"; filename*=UTF-8''%2C" },
|
||||
{ ";", "attachment; filename=\";\"; filename*=UTF-8''%3B" },
|
||||
{ ":", "attachment; filename=\":\"; filename*=UTF-8''%3A" },
|
||||
{ "/", "attachment; filename=\"/\"; filename*=UTF-8''%2F" },
|
||||
{ "[", "attachment; filename=\"[\"; filename*=UTF-8''%5B" },
|
||||
{ "]", "attachment; filename=\"]\"; filename*=UTF-8''%5D" },
|
||||
{ "?", "attachment; filename=\"?\"; filename*=UTF-8''%3F" },
|
||||
{ "=", "attachment; filename=\"=\"; filename*=UTF-8''%3D" },
|
||||
{ "{", "attachment; filename=\"{\"; filename*=UTF-8''%7B" },
|
||||
{ "}", "attachment; filename=\"}\"; filename*=UTF-8''%7D" },
|
||||
{ " ", "attachment; filename=\" \"; filename*=UTF-8''%20" },
|
||||
{ "a\tb", "attachment; filename=\"a\tb\"; filename*=UTF-8''a%09b" },
|
||||
{ "a b", "attachment; filename=\"a b\"; filename*=UTF-8''a%20b" },
|
||||
|
||||
// Values that need to be escaped
|
||||
{ "\"", "attachment; filename=\"\\\"\"" },
|
||||
{ "\\", "attachment; filename=\"\\\\\"" },
|
||||
{ "\"", "attachment; filename=\"\\\"\"; filename*=UTF-8''%22" },
|
||||
{ "\\", "attachment; filename=\"\\\\\"; filename*=UTF-8''%5C" },
|
||||
|
||||
// Values that need to be specially encoded (Base64, see rfc2047)
|
||||
{ "a\nb", "attachment; filename=\"=?utf-8?B?YQpi?=\"" },
|
||||
{ "a\nb", "attachment; filename=\"a\nb\"; filename*=UTF-8''a%0Ab" },
|
||||
|
||||
// Values with non unicode characters
|
||||
{ "résumé.txt", "attachment; filename*=UTF-8''r%C3%A9sum%C3%A9.txt" },
|
||||
{ "Δ", "attachment; filename*=UTF-8''%CE%94" },
|
||||
{ "Δ\t", "attachment; filename*=UTF-8''%CE%94%09" },
|
||||
{ "ABCXYZabcxyz012789!@#$%^&*()-=_+.:~Δ", @"attachment; filename*=UTF-8''ABCXYZabcxyz012789!%40%23$%25%5E&%2A%28%29-%3D_+.:~%CE%94" },
|
||||
{ "résumé.txt", "attachment; filename=r_sum_.txt; filename*=UTF-8''r%C3%A9sum%C3%A9.txt" },
|
||||
{ "Δ", "attachment; filename=_; filename*=UTF-8''%CE%94" },
|
||||
{ "Δ\t", "attachment; filename=\"_\t\"; filename*=UTF-8''%CE%94%09" },
|
||||
{ "ABCXYZabcxyz012789!@#$%^&*()-=_+.:~Δ", @"attachment; filename=""ABCXYZabcxyz012789!@#$%^&*()-=_+.:~_""; filename*=UTF-8''ABCXYZabcxyz012789!%40#$%25^&%2A%28%29-%3D_+.%3A~%CE%94" },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -190,10 +185,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
continue;
|
||||
}
|
||||
|
||||
data.Add(char.ConvertFromUtf32(i), "attachment; filename=\"" + char.ConvertFromUtf32(i) + "\"");
|
||||
data.Add(char.ConvertFromUtf32(i), "attachment; filename=\"" + char.ConvertFromUtf32(i) + "\"; filename*=UTF-8''%" + i.ToString("X2"));
|
||||
}
|
||||
|
||||
data.Add(char.ConvertFromUtf32(127), "attachment; filename=\"" + char.ConvertFromUtf32(127) + "\"");
|
||||
data.Add(char.ConvertFromUtf32(127), "attachment; filename=\"" + char.ConvertFromUtf32(127) + "\"; filename*=UTF-8''%7F");
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
@ -205,7 +200,9 @@ namespace Microsoft.AspNet.Mvc
|
|||
public void GetHeaderValue_Produces_Correct_ContentDisposition(string input, string expectedOutput)
|
||||
{
|
||||
// Arrange & Act
|
||||
var actual = FileResult.ContentDispositionUtil.GetHeaderValue(input);
|
||||
var cd = new ContentDispositionHeaderValue("attachment");
|
||||
cd.SetHttpFileName(input);
|
||||
var actual = cd.ToString();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedOutput, actual);
|
||||
|
|
|
|||
|
|
@ -8,11 +8,12 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.DependencyInjection.Fallback;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -32,25 +33,25 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
};
|
||||
|
||||
// Empty accept header, should select based on contentTypes.
|
||||
yield return new object[] { contentTypes, "", "application/json;charset=utf-8" };
|
||||
yield return new object[] { contentTypes, "", "application/json; charset=utf-8" };
|
||||
|
||||
// null accept header, should select based on contentTypes.
|
||||
yield return new object[] { contentTypes, null, "application/json;charset=utf-8" };
|
||||
yield return new object[] { contentTypes, null, "application/json; charset=utf-8" };
|
||||
|
||||
// No accept Header match with given contentype collection.
|
||||
// Should select based on if any formatter supported any content type.
|
||||
yield return new object[] { contentTypes, "text/custom", "application/json;charset=utf-8" };
|
||||
yield return new object[] { contentTypes, "text/custom", "application/json; charset=utf-8" };
|
||||
|
||||
// Accept Header matches but no formatter supports the accept header.
|
||||
// Should select based on if any formatter supported any user provided content type.
|
||||
yield return new object[] { contentTypes, "text/xml", "application/json;charset=utf-8" };
|
||||
yield return new object[] { contentTypes, "text/xml", "application/json; charset=utf-8" };
|
||||
|
||||
// Filtets out Accept headers with 0 quality and selects the one with highest quality.
|
||||
yield return new object[]
|
||||
{
|
||||
contentTypes,
|
||||
"text/plain;q=0.3, text/json;q=0, text/cusotm;q=0.0, application/json;q=0.4",
|
||||
"application/json;charset=utf-8"
|
||||
"application/json; charset=utf-8"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -107,12 +108,13 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
public async Task ObjectResult_WithSingleContentType_TheGivenContentTypeIsSelected()
|
||||
{
|
||||
// Arrange
|
||||
var expectedContentType = "application/json;charset=utf-8";
|
||||
var expectedContentType = "application/json; charset=utf-8";
|
||||
|
||||
// non string value.
|
||||
var input = 123;
|
||||
var httpResponse = GetMockHttpResponse();
|
||||
var actionContext = CreateMockActionContext(httpResponse.Object);
|
||||
var httpResponse = new DefaultHttpContext().Response;
|
||||
httpResponse.Body = new MemoryStream();
|
||||
var actionContext = CreateMockActionContext(httpResponse);
|
||||
|
||||
// Set the content type property explicitly to a single value.
|
||||
var result = new ObjectResult(input);
|
||||
|
|
@ -123,7 +125,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
await result.ExecuteResultAsync(actionContext);
|
||||
|
||||
// Assert
|
||||
httpResponse.VerifySet(r => r.ContentType = expectedContentType);
|
||||
Assert.Equal(expectedContentType, httpResponse.ContentType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -131,7 +133,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
{
|
||||
// Arrange
|
||||
var contentType = "application/json;charset=utf-8";
|
||||
var expectedContentType = "text/plain;charset=utf-8";
|
||||
var expectedContentType = "text/plain; charset=utf-8";
|
||||
|
||||
// string value.
|
||||
var input = "1234";
|
||||
|
|
@ -154,7 +156,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
public async Task ObjectResult_MultipleContentTypes_PicksFirstFormatterWhichSupportsAnyOfTheContentTypes()
|
||||
{
|
||||
// Arrange
|
||||
var expectedContentType = "application/json;charset=utf-8";
|
||||
var expectedContentType = "application/json; charset=utf-8";
|
||||
var input = "testInput";
|
||||
var httpResponse = GetMockHttpResponse();
|
||||
var actionContext = CreateMockActionContext(httpResponse.Object, requestAcceptHeader: null);
|
||||
|
|
@ -217,7 +219,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
public async Task ObjectResult_NoContentTypeSetWithAcceptHeaders_PicksFormatterOnAcceptHeaders()
|
||||
{
|
||||
// Arrange
|
||||
var expectedContentType = "application/json;charset=utf-8";
|
||||
var expectedContentType = "application/json; charset=utf-8";
|
||||
var input = "testInput";
|
||||
var stream = new MemoryStream();
|
||||
|
||||
|
|
@ -248,7 +250,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
{
|
||||
// Arrange
|
||||
var stream = new MemoryStream();
|
||||
var expectedContentType = "application/json;charset=utf-8";
|
||||
var expectedContentType = "application/json; charset=utf-8";
|
||||
var httpResponse = new Mock<HttpResponse>();
|
||||
httpResponse.SetupProperty<string>(o => o.ContentType);
|
||||
httpResponse.SetupGet(r => r.Body).Returns(stream);
|
||||
|
|
@ -287,10 +289,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
// For each additional accept header, it is called once.
|
||||
// Arrange
|
||||
var acceptHeaderCollection = string.IsNullOrEmpty(acceptHeader) ?
|
||||
null :
|
||||
acceptHeader?.Split(',')
|
||||
.Select(header => MediaTypeWithQualityHeaderValue.Parse(header))
|
||||
.ToArray();
|
||||
null : MediaTypeHeaderValue.ParseList(new[] { acceptHeader }).ToArray();
|
||||
var stream = new MemoryStream();
|
||||
var httpResponse = new Mock<HttpResponse>();
|
||||
httpResponse.SetupProperty<string>(o => o.ContentType);
|
||||
|
|
@ -349,7 +348,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
{
|
||||
// Arrange
|
||||
var stream = new MemoryStream();
|
||||
var expectedContentType = "application/json;charset=utf-8";
|
||||
var expectedContentType = "application/json; charset=utf-8";
|
||||
var httpResponse = new Mock<HttpResponse>();
|
||||
httpResponse.SetupProperty<string>(o => o.ContentType);
|
||||
httpResponse.SetupGet(r => r.Body).Returns(stream);
|
||||
|
|
@ -406,7 +405,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
public async Task ObjectResult_Execute_CallsContentResult_SetsContent()
|
||||
{
|
||||
// Arrange
|
||||
var expectedContentType = "text/plain;charset=utf-8";
|
||||
var expectedContentType = "text/plain; charset=utf-8";
|
||||
var input = "testInput";
|
||||
var stream = new MemoryStream();
|
||||
|
||||
|
|
@ -433,7 +432,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
public async Task ObjectResult_Execute_CallsJsonResult_SetsContent()
|
||||
{
|
||||
// Arrange
|
||||
var expectedContentType = "application/json;charset=utf-8";
|
||||
var expectedContentType = "application/json; charset=utf-8";
|
||||
var nonStringValue = new { x1 = 10, y1 = "Hello" };
|
||||
var httpResponse = Mock.Of<HttpResponse>();
|
||||
httpResponse.Body = new MemoryStream();
|
||||
|
|
@ -444,8 +443,8 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
|
||||
tempHttpResponse.SetupGet(o => o.Body).Returns(tempStream);
|
||||
tempHttpResponse.SetupProperty<string>(o => o.ContentType);
|
||||
tempHttpContext.SetupGet(o => o.Request).Returns(new DefaultHttpContext().Request);
|
||||
tempHttpContext.SetupGet(o => o.Response).Returns(tempHttpResponse.Object);
|
||||
tempHttpContext.SetupGet(o => o.Request.AcceptCharset).Returns(string.Empty);
|
||||
var tempActionContext = new ActionContext(tempHttpContext.Object,
|
||||
new RouteData(),
|
||||
new ActionDescriptor());
|
||||
|
|
@ -482,13 +481,13 @@ namespace Microsoft.AspNet.Mvc.Core.Test.ActionResults
|
|||
var content = "{name: 'Person Name', Age: 'not-an-age'}";
|
||||
var contentBytes = Encoding.UTF8.GetBytes(content);
|
||||
|
||||
var request = new Mock<HttpRequest>();
|
||||
request.SetupGet(r => r.AcceptCharset).Returns(requestAcceptCharsetHeader);
|
||||
request.SetupGet(r => r.Accept).Returns(requestAcceptHeader);
|
||||
request.SetupGet(r => r.ContentType).Returns(requestContentType);
|
||||
request.SetupGet(f => f.Body).Returns(new MemoryStream(contentBytes));
|
||||
var request = new DefaultHttpContext().Request;
|
||||
request.Headers["Accept-Charset"] = requestAcceptCharsetHeader;
|
||||
request.Headers["Accept"] = requestAcceptHeader;
|
||||
request.ContentType = requestContentType;
|
||||
request.Body = new MemoryStream(contentBytes);
|
||||
|
||||
httpContext.Setup(o => o.Request).Returns(request.Object);
|
||||
httpContext.Setup(o => o.Request).Returns(request);
|
||||
httpContext.Setup(o => o.RequestServices).Returns(GetServiceProvider());
|
||||
httpContext.Setup(o => o.RequestServices.GetService(typeof(IOutputFormattersProvider)))
|
||||
.Returns(new TestOutputFormatterProvider());
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using System.Reflection;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.AspNet.Testing;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
|
@ -1941,7 +1942,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
}
|
||||
|
||||
var httpContext = new Mock<HttpContext>(MockBehavior.Loose);
|
||||
var httpResponse = new Mock<HttpResponse>(MockBehavior.Loose);
|
||||
var httpRequest = new DefaultHttpContext().Request;
|
||||
var httpResponse = new DefaultHttpContext().Response;
|
||||
var mockFormattersProvider = new Mock<IOutputFormattersProvider>();
|
||||
mockFormattersProvider.SetupGet(o => o.OutputFormatters)
|
||||
.Returns(
|
||||
|
|
@ -1949,12 +1951,11 @@ namespace Microsoft.AspNet.Mvc
|
|||
{
|
||||
new JsonOutputFormatter()
|
||||
});
|
||||
httpContext.SetupGet(o => o.Request.Accept)
|
||||
.Returns("");
|
||||
httpContext.SetupGet(c => c.Response).Returns(httpResponse.Object);
|
||||
httpContext.SetupGet(c => c.Request).Returns(httpRequest);
|
||||
httpContext.SetupGet(c => c.Response).Returns(httpResponse);
|
||||
httpContext.Setup(o => o.RequestServices.GetService(typeof(IOutputFormattersProvider)))
|
||||
.Returns(mockFormattersProvider.Object);
|
||||
httpResponse.SetupGet(r => r.Body).Returns(new MemoryStream());
|
||||
httpResponse.Body = new MemoryStream();
|
||||
|
||||
var actionContext = new ActionContext(
|
||||
httpContext: httpContext.Object,
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Mvc.Routing;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.AspNet.Routing.Constraints;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -522,10 +522,10 @@ namespace Microsoft.AspNet.Mvc.Description
|
|||
Assert.Equal(4, description.SupportedResponseFormats.Count);
|
||||
|
||||
var formats = description.SupportedResponseFormats;
|
||||
Assert.Single(formats, f => f.MediaType.RawValue == "text/json");
|
||||
Assert.Single(formats, f => f.MediaType.RawValue == "application/json");
|
||||
Assert.Single(formats, f => f.MediaType.RawValue == "text/xml");
|
||||
Assert.Single(formats, f => f.MediaType.RawValue == "application/xml");
|
||||
Assert.Single(formats, f => f.MediaType.ToString() == "text/json");
|
||||
Assert.Single(formats, f => f.MediaType.ToString() == "application/json");
|
||||
Assert.Single(formats, f => f.MediaType.ToString() == "text/xml");
|
||||
Assert.Single(formats, f => f.MediaType.ToString() == "application/xml");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -545,8 +545,8 @@ namespace Microsoft.AspNet.Mvc.Description
|
|||
Assert.Equal(2, description.SupportedResponseFormats.Count);
|
||||
|
||||
var formats = description.SupportedResponseFormats;
|
||||
Assert.Single(formats, f => f.MediaType.RawValue == "text/json");
|
||||
Assert.Single(formats, f => f.MediaType.RawValue == "text/xml");
|
||||
Assert.Single(formats, f => f.MediaType.ToString() == "text/json");
|
||||
Assert.Single(formats, f => f.MediaType.ToString() == "text/xml");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -580,7 +580,7 @@ namespace Microsoft.AspNet.Mvc.Description
|
|||
Assert.NotNull(description.ResponseModelMetadata);
|
||||
|
||||
var formats = description.SupportedResponseFormats;
|
||||
Assert.Single(formats, f => f.MediaType.RawValue == "text/json");
|
||||
Assert.Single(formats, f => f.MediaType.ToString() == "text/json");
|
||||
Assert.Same(formatters[0], formats[0].Formatter);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Test
|
||||
|
|
@ -40,22 +40,23 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
public void ProducesAttribute_InvalidContentType_Throws(string content)
|
||||
{
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<ArgumentException>(
|
||||
var ex = Assert.Throws<FormatException>(
|
||||
() => new ProducesAttribute(content));
|
||||
Assert.Equal("Invalid Argument. Content type '" + content + "' could not be parsed.",
|
||||
Assert.Equal("Invalid value '" + (content ?? "<null>") + "'.",
|
||||
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.SubType, actualMediaType.SubType);
|
||||
Assert.Equal(expectedMediaType.Charset, actualMediaType.Charset);
|
||||
Assert.Equal(expectedMediaType.MediaTypeRange, actualMediaType.MediaTypeRange);
|
||||
Assert.Equal(expectedMediaType.MatchesAllTypes, actualMediaType.MatchesAllTypes);
|
||||
Assert.Equal(expectedMediaType.MatchesAllSubTypes, actualMediaType.MatchesAllSubTypes);
|
||||
Assert.Equal(expectedMediaType.Parameters.Count, actualMediaType.Parameters.Count);
|
||||
foreach (var item in expectedMediaType.Parameters)
|
||||
{
|
||||
Assert.Equal(item.Value, actualMediaType.Parameters[item.Key]);
|
||||
Assert.Equal(item.Value, NameValueHeaderValue.Find(actualMediaType.Parameters, item.Name).Value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
var mediaType = formatter.SupportedMediaTypes[0];
|
||||
|
||||
// Assert
|
||||
Assert.Equal("application/json", mediaType.RawValue);
|
||||
Assert.Equal("application/json", mediaType.ToString());
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> JsonFormatterReadSimpleTypesData
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ using System.IO;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.AspNet.PipelineCore.Collections;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
|
@ -103,10 +104,10 @@ namespace Microsoft.AspNet.Mvc.Core.Test.Formatters
|
|||
private static ActionContext GetActionContext(MediaTypeHeaderValue contentType)
|
||||
{
|
||||
var request = new Mock<HttpRequest>();
|
||||
var headers = new Mock<IHeaderDictionary>();
|
||||
request.Setup(r => r.ContentType).Returns(contentType.RawValue);
|
||||
request.SetupGet(r => r.Headers).Returns(headers.Object);
|
||||
request.SetupGet(f => f.AcceptCharset).Returns(contentType.Charset);
|
||||
var headers = new HeaderDictionary();
|
||||
request.Setup(r => r.ContentType).Returns(contentType.ToString());
|
||||
request.SetupGet(r => r.Headers).Returns(headers);
|
||||
headers[HeaderNames.AcceptCharset] = contentType.Charset;
|
||||
var response = new Mock<HttpResponse>();
|
||||
response.SetupGet(f => f.Body).Returns(new MemoryStream());
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Test
|
||||
|
|
|
|||
|
|
@ -6,8 +6,9 @@ using System.Collections.Generic;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -48,10 +49,10 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
{
|
||||
// Arrange
|
||||
var mockHttpContext = new Mock<HttpContext>();
|
||||
mockHttpContext.SetupGet(o => o.Request.AcceptCharset)
|
||||
.Returns(acceptCharsetHeaders);
|
||||
mockHttpContext.SetupGet(o => o.Request.ContentType)
|
||||
.Returns("application/acceptCharset;charset=" + requestEncoding);
|
||||
var httpRequest = new DefaultHttpContext().Request;
|
||||
httpRequest.Headers["Accept-Charset"] = acceptCharsetHeaders;
|
||||
httpRequest.ContentType = "application/acceptCharset;charset=" + requestEncoding;
|
||||
mockHttpContext.SetupGet(o => o.Request).Returns(httpRequest);
|
||||
var actionContext = new ActionContext(mockHttpContext.Object, new RouteData(), new ActionDescriptor());
|
||||
var formatter = new TestOutputFormatter();
|
||||
foreach (string supportedEncoding in supportedEncodings)
|
||||
|
|
@ -81,8 +82,8 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
var testContentType = MediaTypeHeaderValue.Parse("text/invalid");
|
||||
var formatterContext = new OutputFormatterContext();
|
||||
var mockHttpContext = new Mock<HttpContext>();
|
||||
mockHttpContext.SetupGet(o => o.Request.AcceptCharset)
|
||||
.Returns(string.Empty);
|
||||
var httpRequest = new DefaultHttpContext().Request;
|
||||
mockHttpContext.SetupGet(o => o.Request).Returns(httpRequest);
|
||||
var actionContext = new ActionContext(mockHttpContext.Object, new RouteData(), new ActionDescriptor());
|
||||
formatterContext.ActionContext = actionContext;
|
||||
|
||||
|
|
@ -103,8 +104,8 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
var testContentType = MediaTypeHeaderValue.Parse("application/doesNotSetContext");
|
||||
var formatterContext = new OutputFormatterContext();
|
||||
var mockHttpContext = new Mock<HttpContext>();
|
||||
mockHttpContext.SetupGet(o => o.Request.AcceptCharset)
|
||||
.Returns(string.Empty);
|
||||
var httpRequest = new DefaultHttpContext().Request;
|
||||
mockHttpContext.SetupGet(o => o.Request).Returns(httpRequest);
|
||||
mockHttpContext.SetupProperty(o => o.Response.ContentType);
|
||||
var actionContext = new ActionContext(mockHttpContext.Object, new RouteData(), new ActionDescriptor());
|
||||
formatterContext.ActionContext = actionContext;
|
||||
|
|
@ -115,8 +116,8 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
// Assert
|
||||
Assert.Equal(Encodings.UTF16EncodingLittleEndian.WebName, formatterContext.SelectedEncoding.WebName);
|
||||
Assert.Equal(Encodings.UTF16EncodingLittleEndian, formatterContext.SelectedEncoding);
|
||||
Assert.Equal("application/doesNotSetContext;charset=" + Encodings.UTF16EncodingLittleEndian.WebName,
|
||||
formatterContext.SelectedContentType.RawValue);
|
||||
Assert.Equal("application/doesNotSetContext; charset=" + Encodings.UTF16EncodingLittleEndian.WebName,
|
||||
formatterContext.SelectedContentType.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -131,7 +132,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
|
||||
// Assert
|
||||
Assert.True(result);
|
||||
Assert.Equal(formatter.SupportedMediaTypes[0].RawValue, context.SelectedContentType.RawValue);
|
||||
Assert.Equal(formatter.SupportedMediaTypes[0].ToString(), context.SelectedContentType.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -190,8 +191,8 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
|
||||
// Assert
|
||||
Assert.Equal(2, contentTypes.Count);
|
||||
Assert.Single(contentTypes, ct => ct.RawValue == "application/json");
|
||||
Assert.Single(contentTypes, ct => ct.RawValue == "application/xml");
|
||||
Assert.Single(contentTypes, ct => ct.ToString() == "application/json");
|
||||
Assert.Single(contentTypes, ct => ct.ToString() == "application/xml");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -212,7 +213,7 @@ namespace Microsoft.AspNet.Mvc.Test
|
|||
|
||||
// Assert
|
||||
var contentType = Assert.Single(contentTypes);
|
||||
Assert.Equal("application/json", contentType.RawValue);
|
||||
Assert.Equal("application/json", contentType.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -80,10 +80,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
// Assert
|
||||
Assert.True(formatter.SupportedMediaTypes
|
||||
.Select(content => content.RawValue)
|
||||
.Select(content => content.ToString())
|
||||
.Contains("application/xml"));
|
||||
Assert.True(formatter.SupportedMediaTypes
|
||||
.Select(content => content.RawValue)
|
||||
.Select(content => content.ToString())
|
||||
.Contains("text/xml"));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ using System.Runtime.Serialization;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.AspNet.PipelineCore.Collections;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -297,7 +298,7 @@ namespace Microsoft.AspNet.Mvc.Core
|
|||
// Assert
|
||||
if (expectedOutput != null)
|
||||
{
|
||||
Assert.Equal(expectedOutput, Assert.Single(result).RawValue);
|
||||
Assert.Equal(expectedOutput, Assert.Single(result).ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -319,10 +320,10 @@ namespace Microsoft.AspNet.Mvc.Core
|
|||
private static ActionContext GetActionContext(string contentType)
|
||||
{
|
||||
var request = new Mock<HttpRequest>();
|
||||
var headers = new Mock<IHeaderDictionary>();
|
||||
var headers = new HeaderDictionary(new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase));
|
||||
headers["Accept-Charset"] = MediaTypeHeaderValue.Parse(contentType).Charset;
|
||||
request.Setup(r => r.ContentType).Returns(contentType);
|
||||
request.SetupGet(r => r.Headers).Returns(headers.Object);
|
||||
request.SetupGet(f => f.AcceptCharset).Returns(contentType.Split('=')[1]);
|
||||
request.SetupGet(r => r.Headers).Returns(headers);
|
||||
var response = new Mock<HttpResponse>();
|
||||
response.SetupGet(f => f.Body).Returns(new MemoryStream());
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
|
|
|
|||
|
|
@ -71,10 +71,10 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
// Assert
|
||||
Assert.True(formatter.SupportedMediaTypes
|
||||
.Select(content => content.RawValue)
|
||||
.Select(content => content.ToString())
|
||||
.Contains("application/xml"));
|
||||
Assert.True(formatter.SupportedMediaTypes
|
||||
.Select(content => content.RawValue)
|
||||
.Select(content => content.ToString())
|
||||
.Contains("text/xml"));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ using System.IO;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.AspNet.PipelineCore.Collections;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -281,7 +282,7 @@ namespace Microsoft.AspNet.Mvc.Core
|
|||
// Assert
|
||||
if (expectedOutput != null)
|
||||
{
|
||||
Assert.Equal(expectedOutput, Assert.Single(result).RawValue);
|
||||
Assert.Equal(expectedOutput, Assert.Single(result).ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -303,10 +304,10 @@ namespace Microsoft.AspNet.Mvc.Core
|
|||
private static ActionContext GetActionContext(string contentType)
|
||||
{
|
||||
var request = new Mock<HttpRequest>();
|
||||
var headers = new Mock<IHeaderDictionary>();
|
||||
var headers = new HeaderDictionary(new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase));
|
||||
headers["Accept-Charset"] = MediaTypeHeaderValue.Parse(contentType).Charset;
|
||||
request.Setup(r => r.ContentType).Returns(contentType);
|
||||
request.SetupGet(r => r.Headers).Returns(headers.Object);
|
||||
request.SetupGet(f => f.AcceptCharset).Returns(contentType.Split('=')[1]);
|
||||
request.SetupGet(r => r.Headers).Returns(headers);
|
||||
var response = new Mock<HttpResponse>();
|
||||
response.SetupGet(f => f.Body).Returns(new MemoryStream());
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.AspNet.PipelineCore;
|
||||
using Microsoft.AspNet.Routing;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
// Assert
|
||||
Assert.Equal(expected, written);
|
||||
Assert.Equal("application/json;charset=utf-8", context.Response.ContentType);
|
||||
Assert.Equal("application/json; charset=utf-8", context.Response.ContentType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -70,7 +70,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
// Assert
|
||||
Assert.Equal(expected, written);
|
||||
Assert.Equal("application/json;charset=utf-8", context.Response.ContentType);
|
||||
Assert.Equal("application/json; charset=utf-8", context.Response.ContentType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -86,7 +86,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
};
|
||||
|
||||
var context = GetHttpContext(optionsFormatters);
|
||||
context.Request.Accept = "text/json";
|
||||
context.Request.Headers["Accept"] = "text/json";
|
||||
|
||||
var actionContext = new ActionContext(context, new RouteData(), new ActionDescriptor());
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
// Assert
|
||||
Assert.Equal(expected, written);
|
||||
Assert.Equal("text/json;charset=utf-8", context.Response.ContentType);
|
||||
Assert.Equal("text/json; charset=utf-8", context.Response.ContentType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -124,7 +124,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
// Assert
|
||||
Assert.Equal(expected, written);
|
||||
Assert.Equal("application/json;charset=utf-8", context.Response.ContentType);
|
||||
Assert.Equal("application/json; charset=utf-8", context.Response.ContentType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -148,7 +148,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
// Assert
|
||||
Assert.Equal(expected, written);
|
||||
Assert.Equal("application/hal+json;charset=utf-8", context.Response.ContentType);
|
||||
Assert.Equal("application/hal+json; charset=utf-8", context.Response.ContentType);
|
||||
}
|
||||
|
||||
// If no formatter in options can match the given content-types, then use the one registered
|
||||
|
|
@ -170,7 +170,7 @@ namespace Microsoft.AspNet.Mvc
|
|||
|
||||
// Assert
|
||||
Assert.Equal(expected, written);
|
||||
Assert.Equal("application/json;charset=utf-8", context.Response.ContentType);
|
||||
Assert.Equal("application/json; charset=utf-8", context.Response.ContentType);
|
||||
}
|
||||
|
||||
private HttpContext GetHttpContext(
|
||||
|
|
|
|||
|
|
@ -1,81 +0,0 @@
|
|||
// 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.Linq;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Core.Test
|
||||
{
|
||||
public class MediaTypeWithQualityHeaderValueTests
|
||||
{
|
||||
public static IEnumerable<object[]> SortValues
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new object[] {
|
||||
new string[]
|
||||
{
|
||||
"application/*",
|
||||
"text/plain",
|
||||
"text/plain;q=1.0",
|
||||
"text/plain",
|
||||
"text/plain;q=0",
|
||||
"*/*;q=0.8",
|
||||
"*/*;q=1",
|
||||
"text/*;q=1",
|
||||
"text/plain;q=0.8",
|
||||
"text/*;q=0.8",
|
||||
"text/*;q=0.6",
|
||||
"text/*;q=1.0",
|
||||
"*/*;q=0.4",
|
||||
"text/plain;q=0.6",
|
||||
"text/xml",
|
||||
},
|
||||
new string[]
|
||||
{
|
||||
"text/plain",
|
||||
"text/plain;q=1.0",
|
||||
"text/plain",
|
||||
"text/xml",
|
||||
"application/*",
|
||||
"text/*;q=1",
|
||||
"text/*;q=1.0",
|
||||
"*/*;q=1",
|
||||
"text/plain;q=0.8",
|
||||
"text/*;q=0.8",
|
||||
"*/*;q=0.8",
|
||||
"text/plain;q=0.6",
|
||||
"text/*;q=0.6",
|
||||
"*/*;q=0.4",
|
||||
"text/plain;q=0",
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(SortValues))]
|
||||
public void SortMediaTypeWithQualityHeaderValuesByQFactor_SortsCorrectly(IEnumerable<string> unsorted, IEnumerable<string> expectedSorted)
|
||||
{
|
||||
// Arrange
|
||||
var unsortedValues =
|
||||
new List<MediaTypeWithQualityHeaderValue>(
|
||||
unsorted.Select(u => MediaTypeWithQualityHeaderValue.Parse(u)));
|
||||
|
||||
var expectedSortedValues =
|
||||
new List<MediaTypeWithQualityHeaderValue>(
|
||||
expectedSorted.Select(u => MediaTypeWithQualityHeaderValue.Parse(u)));
|
||||
|
||||
// Act
|
||||
var actualSorted = unsortedValues.OrderByDescending(m => m, MediaTypeWithQualityHeaderValueComparer.QualityComparer).ToArray();
|
||||
|
||||
// Assert
|
||||
for (int i = 0; i < expectedSortedValues.Count; i++)
|
||||
{
|
||||
Assert.True(MediaTypeWithQualityHeaderValueComparer.QualityComparer.Compare(expectedSortedValues[i], actualSorted[i]) == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||
|
|
@ -14,4 +14,9 @@
|
|||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<UserProperties project_1json__JSONSchema="http://www.asp.net/media/4878834/project.json" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Microsoft.AspNet.Mvc.OptionDescriptors;
|
||||
using Microsoft.AspNet.Testing;
|
||||
using Xunit;
|
||||
|
|
|
|||
|
|
@ -105,8 +105,8 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("ContactInfoUsingV3Format", "text/vcard; charset=utf-8; version=v3.0", "BEGIN:VCARD#FN:John Williams#END:VCARD#")]
|
||||
[InlineData("ContactInfoUsingV4Format", "text/vcard; charset=utf-8; version=v4.0", "BEGIN:VCARD#FN:John Williams#GENDER:M#END:VCARD#")]
|
||||
[InlineData("ContactInfoUsingV3Format", "text/vcard; version=v3.0; charset=utf-8", "BEGIN:VCARD#FN:John Williams#END:VCARD#")]
|
||||
[InlineData("ContactInfoUsingV4Format", "text/vcard; version=v4.0; charset=utf-8", "BEGIN:VCARD#FN:John Williams#GENDER:M#END:VCARD#")]
|
||||
public async Task ProducesAttribute_WithMediaTypeHavingParameters_IsCaseInsensitiveMatch(
|
||||
string action,
|
||||
string expectedMediaType,
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
|
||||
var contentDisposition = response.Content.Headers.ContentDisposition.ToString();
|
||||
Assert.NotNull(contentDisposition);
|
||||
Assert.Equal("attachment; filename=downloadName.txt", contentDisposition);
|
||||
Assert.Equal("attachment; filename=downloadName.txt; filename*=UTF-8''downloadName.txt", contentDisposition);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -104,7 +104,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
|
||||
var contentDisposition = response.Content.Headers.ContentDisposition.ToString();
|
||||
Assert.NotNull(contentDisposition);
|
||||
Assert.Equal("attachment; filename=downloadName.txt", contentDisposition);
|
||||
Assert.Equal("attachment; filename=downloadName.txt; filename*=UTF-8''downloadName.txt", contentDisposition);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -150,7 +150,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|||
|
||||
var contentDisposition = response.Content.Headers.ContentDisposition.ToString();
|
||||
Assert.NotNull(contentDisposition);
|
||||
Assert.Equal("attachment; filename=downloadName.txt", contentDisposition);
|
||||
Assert.Equal("attachment; filename=downloadName.txt; filename*=UTF-8''downloadName.txt", contentDisposition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
// 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 Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
||||
{
|
||||
public class HeaderParsingHelpersTests
|
||||
{
|
||||
//Accept Headers
|
||||
[Fact]
|
||||
public void GetAcceptHeaders_ReturnsParsedHeaders()
|
||||
{
|
||||
// Arrange & Act
|
||||
var headers = HeaderParsingHelpers.GetAcceptHeaders("application/xml;q=0.4, application/xhtml;q=0.9");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(2, headers.Count);
|
||||
Assert.Equal("application", headers[0].MediaType);
|
||||
Assert.Equal("xml", headers[0].MediaSubType);
|
||||
Assert.Equal(0.4, headers[0].Quality);
|
||||
Assert.Equal("application", headers[1].MediaType);
|
||||
Assert.Equal("xhtml", headers[1].MediaSubType);
|
||||
Assert.Equal(0.9, headers[1].Quality);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> CasesWhereGetAcceptHeadersReturnsNull
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new object[] { "" };
|
||||
yield return new object[] { "application/xml;q=0.4, application/xhtml;q=0,9" };
|
||||
yield return new object[] { "application/xml;q=0.4, application/xhtml;q=-0.4" };
|
||||
yield return new object[] { "application/xml;q=0 4" };
|
||||
yield return new object[] { "application/xml;q=0*4" };
|
||||
yield return new object[] { "application/xml;q=1^4" };
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(CasesWhereGetAcceptHeadersReturnsNull))]
|
||||
public void GetAcceptHeaders_ReturnsNull(string acceptHeader)
|
||||
{
|
||||
// Arrange & Act
|
||||
var headers = HeaderParsingHelpers.GetAcceptHeaders(acceptHeader);
|
||||
|
||||
// Assert
|
||||
Assert.Null(headers);
|
||||
}
|
||||
|
||||
// Charset Headers
|
||||
[Fact]
|
||||
public void GetAcceptCharsetHeaders_ReturnsParsedHeaders()
|
||||
{
|
||||
// Arrange & Act
|
||||
var headers = HeaderParsingHelpers.GetAcceptCharsetHeaders("utf-8;q=0.7,gzip;q=0.3");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(2, headers.Count);
|
||||
Assert.Equal("utf-8", headers[0].Value);
|
||||
Assert.Equal(0.7, headers[0].Quality);
|
||||
Assert.Equal("gzip", headers[1].Value);
|
||||
Assert.Equal(0.3, headers[1].Quality);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> CasesWhereGetCharsetHeadersReturnsNull
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new object[] { "" };
|
||||
yield return new object[] { "utf-8;q=0,7,gzip;q=-1" };
|
||||
yield return new object[] { "utf-8;q=0*7,gzip;q=1.0" };
|
||||
yield return new object[] { "utf-8;q=0 7" };
|
||||
yield return new object[] { "utf-8;q=0^7" };
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(CasesWhereGetCharsetHeadersReturnsNull))]
|
||||
public void GetAcceptCharsetHeaders_ReturnsNull_IfAcceptHeaderIsEmpty(string charsetHeader)
|
||||
{
|
||||
// Arrange & Act
|
||||
var headers = HeaderParsingHelpers.GetAcceptCharsetHeaders(charsetHeader);
|
||||
|
||||
// Assert
|
||||
Assert.Null(headers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,170 +0,0 @@
|
|||
// 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 Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
||||
{
|
||||
public class MediaTypeHeaderValueParsingTests
|
||||
{
|
||||
public static IEnumerable<object[]> GetValidMediaTypeWithQualityHeaderValues
|
||||
{
|
||||
get
|
||||
{
|
||||
yield return new object[]
|
||||
{
|
||||
"*",
|
||||
"*",
|
||||
null,
|
||||
MediaTypeHeaderValueRange.AllMediaRange,
|
||||
new Dictionary<string, string>(),
|
||||
HttpHeaderUtilitites.Match,
|
||||
"*/*"
|
||||
};
|
||||
|
||||
yield return new object[]
|
||||
{
|
||||
"text",
|
||||
"*",
|
||||
"utf-8",
|
||||
MediaTypeHeaderValueRange.SubtypeMediaRange,
|
||||
new Dictionary<string, string>() { { "charset", "utf-8" }, { "foo", "bar" } },
|
||||
HttpHeaderUtilitites.Match,
|
||||
"text/*;charset=utf-8;foo=bar",
|
||||
};
|
||||
|
||||
yield return new object[]
|
||||
{
|
||||
"text",
|
||||
"plain",
|
||||
"utf-8",
|
||||
MediaTypeHeaderValueRange.None,
|
||||
new Dictionary<string, string>() { { "charset", "utf-8" }, { "foo", "bar" }, { "q", "0.0" } },
|
||||
HttpHeaderUtilitites.NoMatch,
|
||||
"text/plain;charset=utf-8;foo=bar;q=0.0",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(GetValidMediaTypeWithQualityHeaderValues))]
|
||||
public void MediaTypeWithQualityHeaderValue_ParseSuccessfully(string mediaType,
|
||||
string mediaSubType,
|
||||
string charset,
|
||||
MediaTypeHeaderValueRange range,
|
||||
IDictionary<string, string> parameters,
|
||||
double quality,
|
||||
string rawValue)
|
||||
{
|
||||
// Arrange
|
||||
var parsedValue = MediaTypeWithQualityHeaderValue.Parse(rawValue);
|
||||
// Act and Assert
|
||||
Assert.Equal(rawValue, parsedValue.RawValue);
|
||||
Assert.Equal(mediaType, parsedValue.MediaType);
|
||||
Assert.Equal(mediaSubType, parsedValue.MediaSubType);
|
||||
Assert.Equal(charset, parsedValue.Charset);
|
||||
Assert.Equal(range, parsedValue.MediaTypeRange);
|
||||
Assert.Equal(quality, parsedValue.Quality);
|
||||
ValidateParametes(parameters, parsedValue.Parameters);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, "text", "plain", null, "text /plain;q=1,9")]
|
||||
[InlineData(true, "text", "plain", 0.9, "text/plain;q=0.9")]
|
||||
public void MediaTypeWithQualityHeaderValue_TryParse_ReturnsApproperiateResults(
|
||||
bool result,
|
||||
string mediaType,
|
||||
string mediaSubType,
|
||||
double quality,
|
||||
string rawValue)
|
||||
{
|
||||
// Arrange
|
||||
MediaTypeWithQualityHeaderValue parsedValue;
|
||||
var isValid = MediaTypeWithQualityHeaderValue.TryParse(rawValue, out parsedValue);
|
||||
|
||||
// Act and Assert
|
||||
Assert.Equal(result, isValid);
|
||||
if(result)
|
||||
{
|
||||
Assert.Equal(rawValue, parsedValue.RawValue);
|
||||
Assert.Equal(mediaType, parsedValue.MediaType);
|
||||
Assert.Equal(mediaSubType, parsedValue.MediaSubType);
|
||||
Assert.Equal(quality, parsedValue.Quality);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("*/*;", "*/*", true)]
|
||||
[InlineData("text/*;", "text/*", true)]
|
||||
[InlineData("text/plain;", "text/plain", true)]
|
||||
[InlineData("*/*;", "*/*;charset=utf-8;", true)]
|
||||
[InlineData("text/*;", "*/*;charset=utf-8;", true)]
|
||||
[InlineData("text/plain;", "*/*;charset=utf-8;", true)]
|
||||
[InlineData("text/plain;", "text/*;charset=utf-8;", true)]
|
||||
[InlineData("text/plain;", "text/plain;charset=utf-8;", true)]
|
||||
[InlineData("text/plain;version=v1", "text/plain;version=", false)]
|
||||
[InlineData("text/plain;version=v1", "Text/plain;Version=v1", true)]
|
||||
[InlineData("text/plain;version=v1", "tExT/plain;version=V1", true)]
|
||||
[InlineData("text/plain;version=v1", "TEXT/PLAIN;VERSION=V1", true)]
|
||||
[InlineData("text/plain;charset=utf-8;foo=bar;q=0.0", "text/plain;charset=utf-8;foo=bar;q=0.0", true)]
|
||||
[InlineData("text/plain;charset=utf-8;foo=bar;q=0.0", "text/plain;foo=bar;q=0.0;charset=utf-8", true)] // different order of parameters
|
||||
[InlineData("text/plain;charset=utf-8;foo=bar;q=0.0", "text/*;charset=utf-8;foo=bar;q=0.0", true)]
|
||||
[InlineData("text/plain;charset=utf-8;foo=bar;q=0.0", "*/*;charset=utf-8;foo=bar;q=0.0", true)]
|
||||
[InlineData("*/*;", "text/plain;charset=utf-8;foo=bar;q=0.0", false)]
|
||||
[InlineData("text/*;", "text/plain;charset=utf-8;foo=bar;q=0.0", false)]
|
||||
[InlineData("text/plain;missingparam=4;", "text/plain;charset=utf-8;foo=bar;q=0.0", false)]
|
||||
[InlineData("text/plain;missingparam=4;", "text/*;charset=utf-8;foo=bar;q=0.0", false)]
|
||||
[InlineData("text/plain;missingparam=4;", "*/*;charset=utf-8;foo=bar;q=0.0", false)]
|
||||
public void MediaTypeHeaderValue_IsSubTypeTests(string mediaType1, // Example: Formatter's supported media type
|
||||
string mediaType2, // Example: Accept header media type
|
||||
bool isMediaType1Subset)
|
||||
{
|
||||
// Arrange
|
||||
var parsedMediaType1 = MediaTypeWithQualityHeaderValue.Parse(mediaType1);
|
||||
var parsedMediaType2 = MediaTypeWithQualityHeaderValue.Parse(mediaType2);
|
||||
|
||||
// Act
|
||||
var isSubset = parsedMediaType1.IsSubsetOf(parsedMediaType2);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(isMediaType1Subset, isSubset);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("text/plain;charset=utf-16;foo=bar", "text/plain;charset=utf-8;foo=bar")]
|
||||
[InlineData("text/plain;charset=utf-16;foo=bar", "text/plain;charset=utf-16;foo=bar1")]
|
||||
[InlineData("text/plain;charset=utf-16;foo=bar", "text/json;charset=utf-16;foo=bar")]
|
||||
[InlineData("text/plain;charset=utf-16;foo=bar", "application/plain;charset=utf-16;foo=bar")]
|
||||
[InlineData("text/plain;charset=utf-16;foo=bar", "application/json;charset=utf-8;foo=bar1")]
|
||||
[InlineData("text/plain; charset=utf-16; foo=bar", "application/json;charset=utf-8;foo=bar1")]
|
||||
[InlineData("text/plain;charset = utf-16;foo = bar", "application/json;charset=utf-8;foo=bar1")]
|
||||
public void MediaTypeHeaderValue_UpdateValue_RawValueGetsUpdated(string mediaTypeValue,
|
||||
string expectedRawValue)
|
||||
{
|
||||
// Arrange
|
||||
var parsedOldValue = MediaTypeHeaderValue.Parse(mediaTypeValue);
|
||||
var parsedNewValue = MediaTypeHeaderValue.Parse(expectedRawValue);
|
||||
|
||||
// Act
|
||||
parsedOldValue.Charset = parsedNewValue.Charset;
|
||||
parsedOldValue.Parameters = parsedNewValue.Parameters;
|
||||
parsedOldValue.MediaType = parsedNewValue.MediaType;
|
||||
parsedOldValue.MediaSubType = parsedNewValue.MediaSubType;
|
||||
parsedOldValue.MediaTypeRange = parsedNewValue.MediaTypeRange;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedRawValue, parsedOldValue.RawValue);
|
||||
}
|
||||
|
||||
private static void ValidateParametes(IDictionary<string, string> expectedParameters,
|
||||
IDictionary<string, string> actualParameters)
|
||||
{
|
||||
Assert.Equal(expectedParameters.Count, actualParameters.Count);
|
||||
foreach (var key in expectedParameters.Keys)
|
||||
{
|
||||
Assert.Equal(expectedParameters[key], actualParameters[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.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>e69fd235-2042-43a4-9970-59cb29955b4e</ProjectGuid>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
// 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 Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.HeaderValueAbstractions
|
||||
{
|
||||
public class StringWithQualityHeaderValueParsingTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("*", HttpHeaderUtilitites.Match, "*")]
|
||||
[InlineData("*", 0.7, "*;q=.7")]
|
||||
[InlineData("iso-8859-5", HttpHeaderUtilitites.Match, "iso-8859-5")]
|
||||
[InlineData("unicode-1-1", 0.8, "unicode-1-1;q=0.8")]
|
||||
[InlineData("unicode-1-1", 0.8, "unicode-1-1;q =0.8")]
|
||||
[InlineData("unicode-1-1", 0.8, "unicode-1-1;q = 0.8")]
|
||||
[InlineData("unicode-1-1", 1.0, "unicode-1-1;quxx = 0.8")] // quxx gets ignored.
|
||||
public void StringWithQualityHeaderValue_ParseSuccessfully(string value,
|
||||
double quality,
|
||||
string rawValue)
|
||||
{
|
||||
// Arrange
|
||||
var parsedValue = StringWithQualityHeaderValue.Parse(rawValue);
|
||||
|
||||
// Act and Assert
|
||||
Assert.Equal(rawValue, parsedValue.RawValue);
|
||||
Assert.Equal(value, parsedValue.Value);
|
||||
Assert.Equal(quality, parsedValue.Quality);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("*", true, 0.7, "*;q=.7")]
|
||||
[InlineData("iso-8859-5", true, HttpHeaderUtilitites.Match, "iso-8859-5")]
|
||||
[InlineData("unicode-1-1", true, 0.8, "unicode-1-1;q=0.8")]
|
||||
[InlineData("unicode-1-1", false, 0.8, "unicode-1-1;q=-")]
|
||||
public void StringWithQualityHeaderValue_TryParse_ReturnsApproperiateResults(
|
||||
string value,
|
||||
bool result,
|
||||
double quality,
|
||||
string rawValue)
|
||||
{
|
||||
// Arrange
|
||||
StringWithQualityHeaderValue parsedValue;
|
||||
var isValid = StringWithQualityHeaderValue.TryParse(rawValue, out parsedValue);
|
||||
|
||||
// Act and Assert
|
||||
Assert.Equal(result, isValid);
|
||||
if(result == true)
|
||||
{
|
||||
Assert.Equal(rawValue, parsedValue.RawValue);
|
||||
Assert.Equal(value, parsedValue.Value);
|
||||
Assert.Equal(quality, parsedValue.Quality);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"Microsoft.AspNet.Mvc.HeaderValueAbstractions": "1.0.0-*",
|
||||
"Microsoft.AspNet.Testing": "1.0.0-*",
|
||||
"xunit.runner.kre": "1.0.0-*"
|
||||
},
|
||||
"commands": {
|
||||
"test": "xunit.runner.kre"
|
||||
},
|
||||
"frameworks": {
|
||||
"aspnet50": { },
|
||||
"aspnetcore50": { }
|
||||
}
|
||||
}
|
||||
|
|
@ -68,7 +68,7 @@ namespace ApiExplorerWebSite
|
|||
var responseData = new ApiExplorerResponseData()
|
||||
{
|
||||
FormatterType = response.Formatter.GetType().FullName,
|
||||
MediaType = response.MediaType.RawValue,
|
||||
MediaType = response.MediaType.ToString(),
|
||||
};
|
||||
|
||||
data.SupportedResponseFormats.Add(responseData);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.Description;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace ApiExplorerWebSite
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace BasicWebSite.Controllers
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace ConnegWebSite
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace ConnegWebSite
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace ConnegWebSite
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using ConnegWebSite.Models;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace ConnegWebSite
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using ConnegWebSite.Models;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.HeaderValueAbstractions;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace ConnegWebSite
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue