Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

257 lines
7.3 KiB
C#

// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.Controllers;
using System.Web.Http.ValueProviders;
using Xunit;
namespace System.Web.Http.ModelBinding
{
public class ModelBindingController : ApiController
{
public string GetString(string value)
{
return value;
}
public string GetStringFromRoute(string controller, string action)
{
return controller + ":" + action;
}
public int GetInt(int value)
{
return value;
}
public int GetIntWithDefault(int value = -1)
{
return value;
}
public int GetIntFromUri([FromUri] int value)
{
return value;
}
public int GetIntPrefixed([FromUri(Name = "somePrefix")] int value)
{
return value;
}
public int GetIntCustom([ValueProvider(typeof(RequestHeadersValueProviderFactory))] int value)
{
return value;
}
public Task<int> GetIntAsync(int value, CancellationToken token)
{
Assert.NotNull(token);
TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
tcs.TrySetResult(value);
return tcs.Task;
}
public bool GetBool(bool value)
{
return value;
}
public ModelBindOrder GetComplexType(ModelBindOrder item)
{
return item;
}
public ModelBindOrder GetComplexTypeFromUri([FromUri] ModelBindOrder item)
{
return item;
}
public string PostString(string value)
{
return value;
}
public int PostInt(int value)
{
return value;
}
public HttpResponseMessage PostComplexWithValidation(CustomerNameMax6 customer)
{
string errors = String.Empty;
foreach (var kv in this.ModelState)
{
int errorCount = kv.Value.Errors.Count;
if (errorCount > 0)
{
errors += String.Format("Failed to bind {0}. The errors are:\n", kv.Key);
for (int i = 0; i < errorCount; i++)
{
ModelError error = kv.Value.Errors[i];
errors += "ErrorMessage: " + error.ErrorMessage + "\n";
if (error.Exception != null)
{
errors += "Exception" + error.Exception + "\n";
}
}
}
}
if (errors != String.Empty)
{
// Has validation failure
// TODO, 334736, support HttpResponseException which takes ModelState
// throw new HttpResponseException(this.ModelState);
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.BadRequest);
response.Content = new StringContent(errors);
throw new HttpResponseException(response);
}
else
{
// happy path
return Request.CreateResponse<int>(HttpStatusCode.OK, customer.Id);
}
}
public int PostIntFromUri([FromUri] int value)
{
return value;
}
public int PostIntFromBody([FromBody] int value)
{
return value;
}
public int PostIntUriPrefixed([FromUri(Name = "somePrefix")] int value)
{
return value;
}
public bool PostBool(bool value)
{
return value;
}
public int PostIntArray([FromUri] int[] value)
{
return value.Sum();
}
public ModelBindOrder PostComplexType(ModelBindOrder item)
{
return item;
}
public ModelBindOrder PostComplexTypeFromUri([FromUri] ModelBindOrder item)
{
return item;
}
public ModelBindOrder PostComplexTypeFromBody([FromBody] ModelBindOrder item)
{
return item;
}
// check if HttpRequestMessage prevents binding other parameters
public int PostComplexTypeHttpRequestMessage(HttpRequestMessage request, ModelBindOrder order)
{
return Int32.Parse(order.ItemName) + order.Quantity;
}
}
public class CustomerNameMax6
{
[Required]
[StringLength(6)]
public string Name { get; set; }
public int Id { get; set; }
[Required]
public int RequiredValue { get; set; }
}
public class ModelBindCustomer
{
public string Name { get; set; }
}
public class ModelBindOrder
{
public string ItemName { get; set; }
public int Quantity { get; set; }
public ModelBindCustomer Customer { get; set; }
}
public class ModelBindOrderEqualityComparer : IEqualityComparer<ModelBindOrder>
{
public bool Equals(ModelBindOrder x, ModelBindOrder y)
{
Assert.True(x != null, "Expected ModelBindOrder cannot be null.");
Assert.True(y != null, "Actual ModelBindOrder was null.");
Assert.Equal<string>(x.ItemName, y.ItemName);
Assert.Equal<int>(x.Quantity, y.Quantity);
if (x.Customer != null)
{
Assert.True(y.Customer != null, "Actual Customer was null but expected was " + x.Customer.Name);
}
else if (x.Customer == null)
{
Assert.True(y.Customer == null, "Actual Customer was not null but should have been.");
}
else
{
Assert.True(String.Equals(x.Customer.Name, y.Customer.Name, StringComparison.Ordinal), String.Format("Expected Customer.Name '{0}' but actual was '{1}'", x.Customer.Name, y.Customer.Name));
}
return true;
}
public int GetHashCode(ModelBindOrder obj)
{
return obj.GetHashCode();
}
}
public class RequestHeadersValueProviderFactory : ValueProviderFactory
{
public override IValueProvider GetValueProvider(HttpActionContext actionContext)
{
return new RequestHeaderValueProvider(actionContext);
}
}
public class RequestHeaderValueProvider : IValueProvider
{
HttpActionContext _actionContext;
public RequestHeaderValueProvider(HttpActionContext actionContext)
{
_actionContext = actionContext;
}
public bool ContainsPrefix(string prefix)
{
return _actionContext.ControllerContext.Request.Headers.Contains(prefix);
}
public ValueProviderResult GetValue(string key)
{
string result = _actionContext.ControllerContext.Request.Headers.GetValues(key).FirstOrDefault();
return result == null
? null
: new ValueProviderResult(result, result, CultureInfo.CurrentCulture);
}
}
}