Skip to content

Commit

Permalink
Clientside messages shouldn't be generated for cross-property version…
Browse files Browse the repository at this point in the history
… of LessThanOrEqual/GreaterThanOrEqual (#1721)
  • Loading branch information
JeremySkinner committed Apr 28, 2021
1 parent 5c43678 commit ebe0d60
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 2 deletions.
5 changes: 5 additions & 0 deletions Changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
10.1.0 - 28 April 2021
Allow default severity level to be set globally (#1715)
Extend use of variance into the internal API to resolve invalid cast exceptions in some scenarios (#1711)
Fix clientside metadata being incorrectly generated for cross-property LessThanOrEqual/GreaterThanOrEqual (#1721)

10.0.4 - 17 April 2021
Fix a bug where async conditions were sometimes run synchronously.

Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<VersionPrefix>10.0.4</VersionPrefix>
<VersionPrefix>10.1.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
<!-- Use CI build number as version suffix (if defined) -->
<!--<VersionSuffix Condition="'$(GITHUB_RUN_NUMBER)'!=''">ci-$(GITHUB_RUN_NUMBER)</VersionSuffix>-->
Expand Down
17 changes: 17 additions & 0 deletions src/FluentValidation.Tests.AspNetCore/ClientsideMessageTester.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#endregion

namespace FluentValidation.Tests.AspNetCore {
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;
Expand Down Expand Up @@ -204,6 +205,22 @@ public class ClientsideMessageTester : IClassFixture<WebAppFixture> {
var results = await _client.GetClientsideMessages();
ClientsideModelValidator.TimesInstantiated.ShouldEqual(1);
}

[Fact]
public async Task Shouldnt_generate_clientside_message_for_LessThanOrEqual_GreaterThanOrEqual_cross_property() {
// https://github.com/FluentValidation/FluentValidation/issues/1721
// A call to LessThanOrEqual(x => x.SomeOtherProperty) shouldn't generate clientside metadata.
var document = await _client.GetClientsideMessages();

var lessThan = document.Root.Elements("input")
.SingleOrDefault(x => x.Attribute("name").Value == "LessThanOrEqualProperty");

var greaterThan = document.Root.Elements("input")
.SingleOrDefault(x => x.Attribute("name").Value == "GreaterThanOrEqualProperty");

lessThan.Attribute("data-val-range").ShouldBeNull();
greaterThan.Attribute("data-val-range").ShouldBeNull();
}
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
namespace FluentValidation.Tests.AspNetCore {
using System;
using Controllers;
using Microsoft.Extensions.Localization;

Expand All @@ -17,8 +18,11 @@ public class ClientsideModel {
public string ExactLength { get; set; }
public int GreaterThan { get; set; }
public int GreaterThanOrEqual { get; set; }
public DateTime GreaterThanOrEqualProperty { get; set; }
public int LessThan { get; set; }
public int LessThanOrEqual { get; set; }
public DateTime LessThanOrEqualProperty { get; set; }
public DateTime DateTimeComparison { get; set; }
public string LengthWithMessage { get; set; }
public string CustomPlaceholder { get; set; }
public string LengthCustomPlaceholders { get; set; }
Expand Down Expand Up @@ -75,6 +79,8 @@ public class ClientsideModelValidator : AbstractValidator<ClientsideModel> {
RuleFor(x => x.LessThanOrEqual).LessThanOrEqualTo(10);
RuleFor(x => x.GreaterThan).GreaterThan(1);
RuleFor(x => x.GreaterThanOrEqual).GreaterThanOrEqualTo(1);
RuleFor(x => x.LessThanOrEqualProperty).LessThanOrEqualTo(x => x.DateTimeComparison);
RuleFor(x => x.GreaterThanOrEqualProperty).GreaterThanOrEqualTo(x => x.DateTimeComparison);

RuleFor(x => x.LengthWithMessage).Length(1, 10).WithMessage("Foo");
RuleFor(x => x.CustomPlaceholder).NotNull().WithMessage("{PropertyName} is null.");
Expand All @@ -86,6 +92,7 @@ public class ClientsideModelValidator : AbstractValidator<ClientsideModel> {
RuleFor(x => x.MessageWithContext).NotNull().WithMessage(x => $"Foo {x.Required}");
RuleFor(x => x.LocalizedMessage).NotNull().WithMessage(x => localizer["from localizer"]);


TimesInstantiated++;

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
<input asp-for="LessThan"/>
<input asp-for="GreaterThan" />
<input asp-for="GreaterThanOrEqual" />
<input asp-for="GreaterThanOrEqualProperty"/>
<input asp-for="LessThanOrEqual" />
<input asp-for="LessThanOrEqualProperty" />
<input asp-for="LengthWithMessage"/>
<input asp-for="CustomPlaceholder" />
<input asp-for="LengthCustomPlaceholders"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,12 @@ public abstract class AbstractComparisonValidator<T, TProperty> : PropertyValida
/// <summary>
/// Comparison value as non-generic for metadata.
/// </summary>
object IComparisonValidator.ValueToCompare => ValueToCompare;
object IComparisonValidator.ValueToCompare =>
// For clientside validation to work, we must return null if MemberToCompare is set.
// We can't rely on ValueToCompare being null itself as it's generic, and will be initialized
// as default(TProperty) which for non-nullable value types will emit the
// default value for the type rather than null. See https://github.com/FluentValidation/FluentValidation/issues/1721
MemberToCompare != null ? null : ValueToCompare;
}

/// <summary>
Expand Down

0 comments on commit ebe0d60

Please sign in to comment.