[Codeplex #2162]: Nullable Enum support in Web API
This fix is to allow nullable enums as function paramters.
This commit is contained in:
Родитель
8aee6c29e6
Коммит
9d9c57193b
|
@ -120,8 +120,13 @@ namespace System.Web.OData.Formatter
|
|||
valueString = values[1];
|
||||
}
|
||||
|
||||
if (type.IsNullable() && String.Equals(valueString, "null", StringComparison.Ordinal))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Type enumType = TypeHelper.GetUnderlyingTypeOrSelf(type);
|
||||
object[] parameters = new[] { valueString, Enum.ToObject(type, 0) };
|
||||
object[] parameters = new[] { valueString, Enum.ToObject(enumType, 0) };
|
||||
bool isSuccessful = (bool)enumTryParseMethod.MakeGenericMethod(enumType).Invoke(null, parameters);
|
||||
|
||||
if (!isSuccessful)
|
||||
|
|
|
@ -8,6 +8,7 @@ using System.Web.OData.Extensions;
|
|||
using System.Web.OData.Formatter;
|
||||
using System.Web.OData.Formatter.Deserialization;
|
||||
using System.Web.OData.Formatter.Serialization;
|
||||
using System.Web.OData.Routing;
|
||||
using Microsoft.OData.Core;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Library;
|
||||
|
@ -114,6 +115,52 @@ namespace System.Web.OData
|
|||
JsonAssert.Equal(Resources.EnumComplexType, content.ReadAsStringAsync().Result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullableEnumParameter_Works_WithNotNullEnumValue()
|
||||
{
|
||||
// Arrange
|
||||
const string expect =
|
||||
"{\r\n" +
|
||||
" \"@odata.context\":\"http://localhost/odata/$metadata#Edm.Boolean\",\"value\":true\r\n" +
|
||||
"}";
|
||||
|
||||
HttpConfiguration config = new[] { typeof(NullableEnumValueController) }.GetHttpConfiguration();
|
||||
config.MapODataServiceRoute("odata", "odata", GetSampleModel());
|
||||
HttpClient client = new HttpClient(new HttpServer(config));
|
||||
|
||||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get,
|
||||
"http://localhost/odata/NullableEnumFunction(ColorParameter=System.Web.OData.Builder.TestModels.Color'Red')");
|
||||
|
||||
// Act
|
||||
HttpResponseMessage respone = client.SendAsync(request).Result;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expect, respone.Content.ReadAsStringAsync().Result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NullableEnumParameter_Works_WithNullEnumValue()
|
||||
{
|
||||
// Arrange
|
||||
const string expect =
|
||||
"{\r\n" +
|
||||
" \"@odata.context\":\"http://localhost/odata/$metadata#Edm.Boolean\",\"value\":false\r\n" +
|
||||
"}";
|
||||
|
||||
HttpConfiguration config = new[] { typeof(NullableEnumValueController) }.GetHttpConfiguration();
|
||||
config.MapODataServiceRoute("odata", "odata", GetSampleModel());
|
||||
HttpClient client = new HttpClient(new HttpServer(config));
|
||||
|
||||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get,
|
||||
"http://localhost/odata/NullableEnumFunction(ColorParameter=null)");
|
||||
|
||||
// Act
|
||||
HttpResponseMessage respone = client.SendAsync(request).Result;
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expect, respone.Content.ReadAsStringAsync().Result);
|
||||
}
|
||||
|
||||
private static ODataMediaTypeFormatter GetFormatter()
|
||||
{
|
||||
var formatter = new ODataMediaTypeFormatter(new ODataPayloadKind[] { ODataPayloadKind.Property })
|
||||
|
@ -140,6 +187,10 @@ namespace System.Web.OData
|
|||
{
|
||||
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
|
||||
builder.ComplexType<EnumComplex>();
|
||||
|
||||
FunctionConfiguration function = builder.Function("NullableEnumFunction").Returns<bool>();
|
||||
function.Parameter<Color?>("ColorParameter");
|
||||
|
||||
return builder.GetEdmModel();
|
||||
}
|
||||
|
||||
|
@ -150,4 +201,21 @@ namespace System.Web.OData
|
|||
public Color UndefinedColor { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class NullableEnumValueController : ODataController
|
||||
{
|
||||
[HttpGet]
|
||||
[ODataRoute("NullableEnumFunction(ColorParameter={colorParameter})")]
|
||||
[EnableQuery]
|
||||
public bool NullableEnumFunction([FromODataUri]Color? colorParameter)
|
||||
{
|
||||
if (colorParameter != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Assert.True(ModelState.IsValid);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -242,6 +242,36 @@ namespace System.Web.OData.Formatter
|
|||
response.Content.ReadAsAsync(value.GetType(), configuration.Formatters).Result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null, false)]
|
||||
[InlineData(FlagsEnum.One, true)]
|
||||
public void ODataModelBinderProvider_Works_ForNullableEnum(object value, bool expect)
|
||||
{
|
||||
// Arrange
|
||||
HttpConfiguration configuration = new HttpConfiguration();
|
||||
configuration.Services.Replace(typeof(ModelBinderProvider), new ODataModelBinderProvider());
|
||||
configuration.MapODataServiceRoute("odata", "", GetEdmModel());
|
||||
|
||||
var controllers = new[] { typeof(ODataModelBinderProviderTestODataController) };
|
||||
TestAssemblyResolver resolver = new TestAssemblyResolver(new MockAssembly(controllers));
|
||||
configuration.Services.Replace(typeof(IAssembliesResolver), resolver);
|
||||
|
||||
HttpServer server = new HttpServer(configuration);
|
||||
HttpClient client = new HttpClient(server);
|
||||
|
||||
// Act
|
||||
string url = String.Format(
|
||||
"http://localhost/GetNullableFlagsEnum(flagsEnum={0})",
|
||||
value == null ? "null" : Uri.EscapeDataString(ConventionsHelpers.GetUriRepresentationForValue(value)));
|
||||
HttpResponseMessage response = client.GetAsync(url).Result;
|
||||
|
||||
// Assert
|
||||
response.EnsureSuccessStatusCode();
|
||||
Assert.Equal(
|
||||
expect,
|
||||
response.Content.ReadAsAsync(typeof(bool), configuration.Formatters).Result);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("abc", "GetEnum", "simpleEnum")]
|
||||
public void ResourceIsNotFound_IfContainsInvalidEnum(object value, string action, string parameterName)
|
||||
|
@ -282,6 +312,9 @@ namespace System.Web.OData.Formatter
|
|||
getFlagsEnum.Parameter<FlagsEnum>("flagsEnum");
|
||||
getFlagsEnum.Returns<FlagsEnum>();
|
||||
|
||||
FunctionConfiguration function = builder.Function("GetNullableFlagsEnum").Returns<bool>();
|
||||
function.Parameter<FlagsEnum?>("flagsEnum");
|
||||
|
||||
return builder.GetEdmModel();
|
||||
}
|
||||
}
|
||||
|
@ -488,5 +521,17 @@ namespace System.Web.OData.Formatter
|
|||
return flagsEnum;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[ODataRoute("GetNullableFlagsEnum(flagsEnum={flagsEnum})")]
|
||||
public bool GetNullableFlagsEnum(FlagsEnum? flagsEnum)
|
||||
{
|
||||
if (flagsEnum != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Assert.True(ModelState.IsValid);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче