diff --git a/src/Microsoft.AspNet.Mvc.Core/HttpHeadAttribute.cs b/src/Microsoft.AspNet.Mvc.Core/HttpHeadAttribute.cs
new file mode 100644
index 0000000000..9fb36c4f23
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Core/HttpHeadAttribute.cs
@@ -0,0 +1,33 @@
+// Copyright (c) .NET Foundation. 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 Microsoft.Framework.Internal;
+
+namespace Microsoft.AspNet.Mvc
+{
+ ///
+ /// Identifies an action that only supports the HTTP HEAD method.
+ ///
+ public class HttpHeadAttribute : HttpMethodAttribute
+ {
+ private static readonly IEnumerable _supportedMethods = new string[] { "HEAD" };
+
+ ///
+ /// Creates a new .
+ ///
+ public HttpHeadAttribute()
+ : base(_supportedMethods)
+ {
+ }
+
+ ///
+ /// Creates a new with the given route template.
+ ///
+ /// The route template. May not be null.
+ public HttpHeadAttribute([NotNull] string template)
+ : base(_supportedMethods, template)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/DefaultApplicationModelProviderTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/DefaultApplicationModelProviderTest.cs
index 06841ed324..3ba65dbdcf 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/DefaultApplicationModelProviderTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/ApplicationModel/DefaultApplicationModelProviderTest.cs
@@ -464,13 +464,13 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
// Assert
var action = Assert.Single(actions);
+ Assert.Contains("DELETE", action.HttpMethods);
+ Assert.Contains("HEAD", action.HttpMethods);
+
Assert.Equal("Delete", action.ActionName);
-
- var httpMethod = Assert.Single(action.HttpMethods);
- Assert.Equal("DELETE", httpMethod);
Assert.Null(action.AttributeRouteModel);
-
- Assert.IsType(Assert.Single(action.Attributes));
+ Assert.Single(action.Attributes.OfType());
+ Assert.Single(action.Attributes.OfType());
}
[Fact]
@@ -488,6 +488,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
var action = Assert.Single(actions);
Assert.Contains("GET", action.HttpMethods);
Assert.Contains("POST", action.HttpMethods);
+ Assert.Contains("HEAD", action.HttpMethods);
Assert.Equal("Details", action.ActionName);
Assert.Null(action.AttributeRouteModel);
}
@@ -529,12 +530,12 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
Assert.Equal("Edit", action.ActionName);
var httpMethod = Assert.Single(action.HttpMethods);
- Assert.Equal("POST", httpMethod);
+ Assert.Equal("HEAD", httpMethod);
Assert.NotNull(action.AttributeRouteModel);
Assert.Equal("Change", action.AttributeRouteModel.Template);
- Assert.IsType(Assert.Single(action.Attributes));
+ Assert.IsType(Assert.Single(action.Attributes));
}
[Fact]
@@ -1010,7 +1011,7 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
[HttpPost("List")]
public void Index() { }
- [HttpPost("Change")]
+ [HttpHead("Change")]
public void Edit() { }
public void Remove() { }
@@ -1089,11 +1090,13 @@ namespace Microsoft.AspNet.Mvc.ApplicationModels
[CustomHttpMethods("PUT", "PATCH")]
public void Update() { }
+ [HttpHead]
[HttpDelete]
public void Delete() { }
[HttpPost]
[HttpGet]
+ [HttpHead]
public void Details() { }
[HttpGet]
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultActionSelectorTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultActionSelectorTests.cs
index 67de732419..f847cb8a9e 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultActionSelectorTests.cs
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultActionSelectorTests.cs
@@ -530,6 +530,7 @@ namespace Microsoft.AspNet.Mvc
[InlineData("POST")]
[InlineData("DELETE")]
[InlineData("PATCH")]
+ [InlineData("HEAD")]
public async Task HttpMethodAttribute_ActionWithMultipleHttpMethodAttributes_ORsMultipleHttpMethods(string verb)
{
// Arrange
@@ -873,22 +874,6 @@ namespace Microsoft.AspNet.Mvc
}
}
- private class HttpMethodAttributeTests_DefaultMethodValidationController
- {
- public void Index()
- {
- }
-
- // Method with custom attribute.
- [HttpGet]
- public void Get()
- { }
-
- // InvalidMethod ( since its private)
- private void Post()
- { }
- }
-
private class ActionNameController
{
[ActionName("CustomActionName_Verb")]
@@ -914,6 +899,7 @@ namespace Microsoft.AspNet.Mvc
[HttpPost]
[HttpDelete]
[HttpPatch]
+ [HttpHead]
public void Put()
{
}
@@ -923,9 +909,5 @@ namespace Microsoft.AspNet.Mvc
{
}
}
-
- private class HttpMethodAttributeTests_DerivedController : HttpMethodAttributeTests_RestOnlyController
- {
- }
}
}
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/HttpMethodProviderAttributesTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/HttpMethodProviderAttributesTests.cs
index 18e2be50ba..b4d37f000d 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/HttpMethodProviderAttributesTests.cs
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/HttpMethodProviderAttributesTests.cs
@@ -28,6 +28,7 @@ namespace Microsoft.AspNet.Mvc
data.Add(new HttpPutAttribute(), new[] { "PUT" });
data.Add(new HttpPatchAttribute(), new[] { "PATCH" });
data.Add(new HttpDeleteAttribute(), new[] { "DELETE" });
+ data.Add(new HttpHeadAttribute(), new[] { "HEAD" });
data.Add(new AcceptVerbsAttribute("MERGE", "OPTIONS"), new[] { "MERGE", "OPTIONS" });
return data;
diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/RouteTemplateProviderAttributesTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/RouteTemplateProviderAttributesTest.cs
index 4ac62d7312..8f5c2cd666 100644
--- a/test/Microsoft.AspNet.Mvc.Core.Test/RouteTemplateProviderAttributesTest.cs
+++ b/test/Microsoft.AspNet.Mvc.Core.Test/RouteTemplateProviderAttributesTest.cs
@@ -26,6 +26,7 @@ namespace Microsoft.AspNet.Mvc
data.Add(new HttpPutAttribute());
data.Add(new HttpPatchAttribute());
data.Add(new HttpDeleteAttribute());
+ data.Add(new HttpHeadAttribute());
data.Add(new RouteAttribute(""));
return data;