Validate on specified field and display specific error message

Hi,

I remember that we could do field validation in Litium BO by

  1. General, showing error message above the whole page.
  2. Doing validation on specified field and display message below it.

But how did you toggle if it should display the message on the field that did throw the error vs the whole page.

Tried to find it on;
https://github.com/LitiumAB/Education/tree/master/Developer%20Education/Tasks/Validation and https://docs.litium.com/documentation/architecture/validation to no avail.

Litium version: 7.2.3

The first parameter in the AddError method specifies where the error should be displayed, you pass the field id if you want it shown next to the field or you pass * if you want it shown at the top.

There’s an example here: https://github.com/LitiumAB/Education/blob/master/Developer%20Education/Tasks/Validation/Resources/ValidateBookAuthor.cs

if (!isAuthorTemplate)
{
	// Pass ID of a field as first parameter to display the error next to that field in backoffice-UI
	result.AddError("AuthorField", "Only Author-pages can be selected as author");

	// ...and/or pass "*" to display the validation error in the header.
	result.AddError("*", "Author page validation failed");
}
1 Like

Hm,

Then my code was right, is this feature available in 7.2.3?
Tried without the ToLower() but it always displays the message on top.

validationResult.AddError(“Id”.ToLower(), “already exists!”);
validationResult.AddError(“Id”, “already exists!”);

Tried also using “_name” but that also just appends the message to top and not on the actual field.

Update:
To be clear here, i’m using ValidationRuleBase<Page>
And validating page in Websites BO.

Could you try performing the validation on the DraftPage entity instead?

Changed ValidationRuleBase<DraftPage> though same issue.
Though _name is working now

And the original field id that you pass to AddError is correct?

I’m not able to reproduce the issue. In my testing, when saving or trying to publish my draft page the validation error is shown next to the field if a field with that id exists in the template. If not, I only see Validation error at the top.

Could you share your code?

Hi,

Correct we are using constants for everything.

// FieldDefinitionSetup

new FieldDefinition<WebsiteArea>(PageFieldNameConstants.CustomId, SystemFieldTypeConstants.LimitedText)
{
     MultiCulture = false 
},

// Template

new FieldTemplateFieldGroup()
{
    Id = "General",
    Collapsed = false,
    Fields =
    {
        SystemFieldDefinitionConstants.Name,
        SystemFieldDefinitionConstants.Url,
        PageFieldNameConstants.CustomId,
    }
},
....

// Validation

// Does not work
validationResult.AddError(PageFieldNameConstants.CustomId, "already exists");
validationResult.AddError(PageFieldNameConstants.CustomId.ToLower(), "already exists");

// Works
validationResult.AddError(SystemFieldDefinitionConstants.Name,"already exists");

I have a feeling the issue is that it’s using LimitedText
Tried on all other fields on the template and it works when using draftpage.

Update;
After testing multiple fields / values it seems to be an issue with multiculture vs non multiculture.

Created a field Text with multiculture = false via backoffice and tried to throw validation and it would just hoist it up with validation error.

Created a field Text with multiculture = true via backoffice and tried to throw validation and it would display as expected.

That’s strange. I tested now with a LimitedText field and MultiCulture set to false and it works as expected. Does it happen on a fresh page? So there’s no faulty data left from testing.

new FieldDefinition<WebsiteArea>("Custom", SystemFieldTypeConstants.LimitedText)
{
	 MultiCulture = false
},
public override ValidationResult Validate(DraftPage entity, ValidationMode validationMode)
{
	var result = new ValidationResult();
	var value = entity.Fields.GetValue<string>("Custom");
	if (value == "test")
	{
		result.AddError("Custom", "Can't be test");
	}

	return result;
}

image

Hm, I wonder if this is some kind of casing issue;
Tried to replicate this again and suddenly it started working on the new fields but not on the one i want it to work on.

Here is a testcase.
3 fields, Custom, CCustom, CCCustom.
Then i add 3 errors on all of them.
Look how it will display error only on the first 2

Constants

public const string CustomId = "CustomId";
public const string CCustomId = "CCustomId";
public const string CCCustomId = "CCCustomId";

Definition

new FieldDefinition<WebsiteArea>(PageFieldNameConstants.CustomId,SystemFieldTypeConstants.LimitedText){ MultiCulture = false},
new FieldDefinition<WebsiteArea>(PageFieldNameConstants.CCustomId,SystemFieldTypeConstants.LimitedText){ MultiCulture = false},
new FieldDefinition<WebsiteArea>(PageFieldNameConstants.CCCustomId,SystemFieldTypeConstants.LimitedText){ MultiCulture = false},

Validation

validationResult.AddError(PageFieldNameConstants.CustomId, $"error custom");
validationResult.AddError(PageFieldNameConstants.CCustomId, $"error custom");
validationResult.AddError(PageFieldNameConstants.CCCustomId, $"error custom");

See that the last one does not trigger.
Tried to change the order of AddError just to be sure and it seems that it’s some casing issue. Tried ToLower() on all then none of them will trigger, maybe thats why the Test did not work. But this seems to be reproducable consistently.

Result onsave

{
    "message": "The request is invalid.",
    "modelState": {
        "$type": "System.Web.Http.HttpError, System.Web.Http",
        "ccCustomId": {
            "$type": "System.String[], mscorlib",
            "$values": ["error custom"]
        },
        "cCustomId": {
            "$type": "System.String[], mscorlib",
            "$values": ["error custom"]
        },
        "customId": {
            "$type": "System.String[], mscorlib",
            "$values": ["error custom"]
        }
    }
}

Yeah, the field id returned is ccCustomId while the input field has the id cCCustomId. Same thing happens in 7.4.2. Can you please report a bug on Docs for that? Thanks!

Is your original use case working now or does it hit this issue?