internal static bool ValidateObject(object o, List<ValidationResultInfo> validationErrors, HttpActionContext actionContext) { // create a model validation node for the object ModelMetadataProvider metadataProvider = actionContext.GetMetadataProvider(); string modelStateKey = String.Empty; ModelValidationNode validationNode = CreateModelValidationNode(o, metadataProvider, actionContext.ModelState, modelStateKey); validationNode.ValidateAllProperties = true; // add the node to model state ModelState modelState = new ModelState(); modelState.Value = new ValueProviderResult(o, String.Empty, CultureInfo.CurrentCulture); actionContext.ModelState.Add(modelStateKey, modelState); // invoke validation validationNode.Validate(actionContext); if (!actionContext.ModelState.IsValid) { foreach (var modelStateItem in actionContext.ModelState) { foreach (ModelError modelError in modelStateItem.Value.Errors) { validationErrors.Add(new ValidationResultInfo(modelError.ErrorMessage, new string[] { modelStateItem.Key })); } } } return actionContext.ModelState.IsValid; }
public void OnActionExecuting_HandlesModelStateSuccess() { // Arrange ModelState state = new ModelState(); _actionContext.ModelState.Add("m1", state); // Act _validater.OnActionExecuting(_actionContext); // Assert Assert.Null(_actionContext.Response); }
public async Task OnActionExecuting_HandlesModelStateErrors() { // Arrange ModelState state = new ModelState(); state.Errors.Add(new Exception("Model Error!")); _actionContext.ModelState.Add("m1", state); // Act _validater.OnActionExecuting(_actionContext); HttpError error = await _actionContext.Response.Content.ReadAsAsync<HttpError>(); // Assert Assert.NotNull(error); }
private static void CreateModelValidationNodeRecursive(object o, ModelValidationNode parentNode, ModelMetadataProvider metadataProvider, ModelMetadata metadata, ModelStateDictionary modelStateDictionary, string modelStateKey, HashSet<object> visited) { if (visited.Contains(o)) { return; } visited.Add(o); foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(o)) { // append the current property name to the model state path string propertyKey = modelStateKey; if (propertyKey.Length > 0) { propertyKey += "."; } propertyKey += property.Name; // create the node for this property and add to the parent node object propertyValue = property.GetValue(o); metadata = metadataProvider.GetMetadataForProperty(() => { return propertyValue; }, o.GetType(), property.Name); ModelValidationNode childNode = new ModelValidationNode(metadata, propertyKey); parentNode.ChildNodes.Add(childNode); // add the property node to model state ModelState modelState = new ModelState(); modelState.Value = new ValueProviderResult(propertyValue, null, CultureInfo.CurrentCulture); modelStateDictionary.Add(propertyKey, modelState); if (propertyValue != null) { CreateModelValidationNodeRecursive(propertyValue, childNode, metadataProvider, metadata, modelStateDictionary, propertyKey, visited); } } }
public void ExecuteAsync_ReturnsCorrectResponse_WhenContentNegotiationSucceedsAndIncludeErrorDetailIsFalse() { // Arrange ModelStateDictionary modelState = CreateModelState(); string expectedModelStateKey = "ModelStateKey"; string expectedModelStateErrorMessage = "ModelStateErrorMessage"; ModelState originalModelStateItem = new ModelState(); originalModelStateItem.Errors.Add(new ModelError(new InvalidOperationException(), expectedModelStateErrorMessage)); modelState.Add(expectedModelStateKey, originalModelStateItem); bool includeErrorDetail = false; MediaTypeFormatter expectedFormatter = CreateFormatter(); MediaTypeHeaderValue expectedMediaType = CreateMediaType(); ContentNegotiationResult negotiationResult = new ContentNegotiationResult(expectedFormatter, expectedMediaType); using (HttpRequestMessage expectedRequest = CreateRequest()) { IEnumerable<MediaTypeFormatter> expectedFormatters = CreateFormatters(); Mock<IContentNegotiator> spy = new Mock<IContentNegotiator>(); spy.Setup(n => n.Negotiate(typeof(HttpError), expectedRequest, expectedFormatters)).Returns( negotiationResult); IContentNegotiator contentNegotiator = spy.Object; IHttpActionResult result = CreateProductUnderTest(modelState, includeErrorDetail, contentNegotiator, expectedRequest, expectedFormatters); // Act Task<HttpResponseMessage> task = result.ExecuteAsync(CancellationToken.None); // Assert Assert.NotNull(task); task.WaitUntilCompleted(); using (HttpResponseMessage response = task.Result) { Assert.NotNull(response); Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); HttpContent content = response.Content; Assert.IsType<ObjectContent<HttpError>>(content); ObjectContent<HttpError> typedContent = (ObjectContent<HttpError>)content; HttpError error = (HttpError)typedContent.Value; Assert.NotNull(error); HttpError modelStateError = error.ModelState; Assert.NotNull(modelStateError); Assert.True(modelState.ContainsKey(expectedModelStateKey)); object modelStateValue = modelStateError[expectedModelStateKey]; Assert.IsType(typeof(string[]), modelStateValue); string[] typedModelStateValue = (string[])modelStateValue; Assert.Equal(1, typedModelStateValue.Length); Assert.Same(expectedModelStateErrorMessage, typedModelStateValue[0]); Assert.Same(expectedFormatter, typedContent.Formatter); Assert.NotNull(typedContent.Headers); Assert.Equal(expectedMediaType, typedContent.Headers.ContentType); Assert.Same(expectedRequest, response.RequestMessage); } } }
public void TranslateHttpResponseException_Unpacks_ModelState_Errors() { // Arrange HttpRequestMessage request = new HttpRequestMessage { RequestUri = new Uri("http://localhost"), Method = HttpMethod.Get }; ModelStateDictionary modelStateDictionary = new ModelStateDictionary(); ModelState modelState1 = new ModelState(); modelState1.Errors.Add("modelState1.Error1"); modelState1.Errors.Add("modelState1.Error2"); modelStateDictionary["key1"] = modelState1; ModelState modelState2 = new ModelState(); modelState2.Errors.Add("modelState2.Error1"); modelState2.Errors.Add("modelState2.Error2"); modelStateDictionary["key2"] = modelState2; HttpError httpError = new HttpError(modelStateDictionary, includeErrorDetail: true); HttpResponseMessage errorResponse = request.CreateResponse(HttpStatusCode.BadRequest); errorResponse.Content = new ObjectContent<HttpError>(httpError, new JsonMediaTypeFormatter()); TraceRecord traceRecord = new TraceRecord(request, "System.Web.Http.Request", TraceLevel.Error) { Exception = new HttpResponseException(errorResponse) }; // Act new SystemDiagnosticsTraceWriter().TranslateHttpResponseException(traceRecord); // Assert Assert.Equal(TraceLevel.Warn, traceRecord.Level); string message = ExtractModelStateErrorString(traceRecord.Message); AssertContainsExactly(message, new Dictionary<string, string>() { { "key1", "[modelState1.Error1, modelState1.Error2]" }, { "key2", "[modelState2.Error1, modelState2.Error2]" }, }); }