private List <ValidationIssue> MapModelStateToIssueList( ModelStateDictionary modelState, Instance instance, Dictionary <string, Dictionary <string, string> > serviceText) { List <ValidationIssue> validationIssues = new List <ValidationIssue>(); foreach (string modelKey in modelState.Keys) { modelState.TryGetValue(modelKey, out ModelStateEntry entry); if (entry != null && entry.ValidationState == ModelValidationState.Invalid) { foreach (ModelError error in entry.Errors) { validationIssues.Add(new ValidationIssue() { InstanceId = instance.Id, Code = error.ErrorMessage, Severity = ValidationIssueSeverity.Error, Description = AppTextHelper.GetAppText(error.ErrorMessage, serviceText, null, "nb") }); } } } return(validationIssues); }
public async Task <IActionResult> ValidateData( [FromRoute] string org, [FromRoute] string app, [FromRoute] int instanceOwnerId, [FromRoute] Guid instanceId, [FromRoute] Guid dataGuid) { Instance instance = await _instanceService.GetInstance(app, org, instanceOwnerId, instanceId); if (instance == null) { return(NotFound()); } // Todo. Figure out where to get this from Dictionary <string, Dictionary <string, string> > serviceText = new Dictionary <string, Dictionary <string, string> >(); if (instance.Process?.CurrentTask?.ElementId == null) { throw new ValidationException("Unable to validate instance without a started process."); } List <ValidationIssue> messages = new List <ValidationIssue>(); DataElement element = instance.Data.FirstOrDefault(d => d.Id == dataGuid.ToString()); if (element == null) { throw new ValidationException("Unable to validate data element."); } Application application = _appResourceService.GetApplication(); DataType dataType = application.DataTypes.FirstOrDefault(et => et.Id == element.DataType); if (dataType == null) { throw new ValidationException("Unknown element type."); } messages.AddRange(await _validationService.ValidateDataElement(instance, dataType, element)); string taskId = instance.Process.CurrentTask.ElementId; if (!dataType.TaskId.Equals(taskId, StringComparison.OrdinalIgnoreCase)) { ValidationIssue message = new ValidationIssue { Code = ValidationIssueCodes.DataElementCodes.DataElementValidatedAtWrongTask, InstanceId = instance.Id, Severity = ValidationIssueSeverity.Warning, DataElementId = element.Id, Description = AppTextHelper.GetAppText( ValidationIssueCodes.DataElementCodes.DataElementValidatedAtWrongTask, serviceText, null, "nb") }; messages.Add(message); } return(Ok(messages)); }
public async Task <List <ValidationIssue> > ValidateAndUpdateProcess(Instance instance, string taskId) { // Todo. Figure out where to get this from Dictionary <string, Dictionary <string, string> > serviceText = new Dictionary <string, Dictionary <string, string> >(); _logger.LogInformation($"Validation of {instance.Id}"); List <ValidationIssue> messages = new List <ValidationIssue>(); ModelStateDictionary validationResults = new ModelStateDictionary(); await _altinnApp.RunTaskValidation(instance, taskId, validationResults); messages.AddRange(MapModelStateToIssueList(validationResults, instance, serviceText)); Application application = _appResourcesService.GetApplication(); foreach (DataType dataType in application.DataTypes.Where(et => et.TaskId == taskId)) { List <DataElement> elements = instance.Data.Where(d => d.DataType == dataType.Id).ToList(); if (dataType.MaxCount > 0 && dataType.MaxCount < elements.Count) { ValidationIssue message = new ValidationIssue { InstanceId = instance.Id, Code = ValidationIssueCodes.InstanceCodes.TooManyDataElementsOfType, Severity = ValidationIssueSeverity.Error, Description = AppTextHelper.GetAppText( ValidationIssueCodes.InstanceCodes.TooManyDataElementsOfType, serviceText, null, "nb"), Field = dataType.Id }; messages.Add(message); } if (dataType.MinCount > 0 && dataType.MinCount > elements.Count) { ValidationIssue message = new ValidationIssue { InstanceId = instance.Id, Code = ValidationIssueCodes.InstanceCodes.TooFewDataElementsOfType, Severity = ValidationIssueSeverity.Error, Description = AppTextHelper.GetAppText( ValidationIssueCodes.InstanceCodes.TooFewDataElementsOfType, null, null, "nb"), Field = dataType.Id }; messages.Add(message); } foreach (DataElement dataElement in elements) { messages.AddRange(await ValidateDataElement(instance, dataType, dataElement)); } } if (messages.Count == 0) { instance.Process.CurrentTask.Validated = new ValidationStatus { CanCompleteTask = true, Timestamp = DateTime.Now }; } else { instance.Process.CurrentTask.Validated = new ValidationStatus { CanCompleteTask = false, Timestamp = DateTime.Now }; } instance = await _instanceService.UpdateProcess(instance); return(messages); }
public async Task <List <ValidationIssue> > ValidateDataElement(Instance instance, DataType dataType, DataElement dataElement) { _logger.LogInformation($"Validation of data element {dataElement.Id} of instance {instance.Id}"); // Todo. Figure out where to get this from Dictionary <string, Dictionary <string, string> > serviceText = new Dictionary <string, Dictionary <string, string> >(); List <ValidationIssue> messages = new List <ValidationIssue>(); if (dataElement.ContentType == null) { ValidationIssue message = new ValidationIssue { InstanceId = instance.Id, Code = ValidationIssueCodes.DataElementCodes.MissingContentType, DataElementId = dataElement.Id, Severity = ValidationIssueSeverity.Error, Description = AppTextHelper.GetAppText( ValidationIssueCodes.DataElementCodes.MissingContentType, serviceText, null, "nb") }; messages.Add(message); } else { string contentTypeWithoutEncoding = dataElement.ContentType.Split(";")[0]; if (dataType.AllowedContentTypes != null && dataType.AllowedContentTypes.Count > 0 && dataType.AllowedContentTypes.All(ct => !ct.Equals(contentTypeWithoutEncoding, StringComparison.OrdinalIgnoreCase))) { ValidationIssue message = new ValidationIssue { InstanceId = instance.Id, DataElementId = dataElement.Id, Code = ValidationIssueCodes.DataElementCodes.ContentTypeNotAllowed, Severity = ValidationIssueSeverity.Error, Description = AppTextHelper.GetAppText( ValidationIssueCodes.DataElementCodes.ContentTypeNotAllowed, serviceText, null, "nb"), Field = dataType.Id }; messages.Add(message); } } if (dataType.MaxSize.HasValue && dataType.MaxSize > 0 && (long)dataType.MaxSize * 1024 * 1024 < dataElement.Size) { ValidationIssue message = new ValidationIssue { InstanceId = instance.Id, DataElementId = dataElement.Id, Code = ValidationIssueCodes.DataElementCodes.DataElementTooLarge, Severity = ValidationIssueSeverity.Error, Description = AppTextHelper.GetAppText( ValidationIssueCodes.DataElementCodes.DataElementTooLarge, serviceText, null, "nb"), Field = dataType.Id }; messages.Add(message); } if (dataType.AppLogic != null) { Type modelType = _altinnApp.GetAppModelType(dataType.AppLogic.ClassRef); Guid instanceGuid = Guid.Parse(instance.Id.Split("/")[1]); string app = instance.AppId.Split("/")[1]; int instanceOwnerPartyId = int.Parse(instance.InstanceOwner.PartyId); dynamic data = await _dataService.GetFormData(instanceGuid, modelType, instance.Org, app, instanceOwnerPartyId, Guid.Parse(dataElement.Id)); ModelStateDictionary validationResults = new ModelStateDictionary(); var actionContext = new ActionContext( _httpContextAccessor.HttpContext, new Microsoft.AspNetCore.Routing.RouteData(), new ActionDescriptor(), validationResults); ValidationStateDictionary validationState = new ValidationStateDictionary(); _objectModelValidator.Validate(actionContext, validationState, null, data); await _altinnApp.RunDataValidation(data, validationResults); if (!validationResults.IsValid) { messages.AddRange(MapModelStateToIssueList(actionContext.ModelState, instance, dataElement.Id, serviceText)); } } return(messages); }
public async Task <System.Collections.Generic.List <ValidationIssue> > ValidateAndUpdateInstance(Instance instance, string taskId) { string org = instance.Org; string app = instance.AppId.Split("/")[1]; _logger.LogInformation($"Validation of {instance.Id}"); Application application = _appResourcesService.GetApplication(); // Todo. Figure out where to get this from Dictionary <string, Dictionary <string, string> > serviceText = new Dictionary <string, Dictionary <string, string> >(); List <ValidationIssue> messages = new List <ValidationIssue>(); foreach (DataType dataType in application.DataTypes.Where(et => et.TaskId == taskId)) { List <DataElement> elements = instance.Data.Where(d => d.DataType == dataType.Id).ToList(); if (dataType.MaxCount > 0 && dataType.MaxCount < elements.Count) { ValidationIssue message = new ValidationIssue { InstanceId = instance.Id, Code = ValidationIssueCodes.InstanceCodes.TooManyDataElementsOfType, Severity = ValidationIssueSeverity.Error, Description = AppTextHelper.GetAppText( ValidationIssueCodes.InstanceCodes.TooManyDataElementsOfType, serviceText, null, "nb") }; messages.Add(message); } if (dataType.MinCount > 0 && dataType.MinCount > elements.Count) { ValidationIssue message = new ValidationIssue { InstanceId = instance.Id, Code = ValidationIssueCodes.InstanceCodes.TooFewDataElementsOfType, Severity = ValidationIssueSeverity.Error, Description = AppTextHelper.GetAppText( ValidationIssueCodes.InstanceCodes.TooFewDataElementsOfType, null, null, "nb") }; messages.Add(message); } foreach (DataElement dataElement in elements) { messages.AddRange(await ValidateDataElement(instance, dataType, dataElement)); } } if (messages.Count == 0) { instance.Process.CurrentTask.Validated = new ValidationStatus { CanCompleteTask = true, Timestamp = DateTime.Now }; } else { instance.Process.CurrentTask.Validated = new ValidationStatus { CanCompleteTask = false, Timestamp = DateTime.Now }; } return(messages); }