Skip to content

Commit

Permalink
README comment about fields values extraction posibility, when approp…
Browse files Browse the repository at this point in the history
…riate formatters are provided to error message string + minor refactor, chm regenerated and version up.
  • Loading branch information
jwaliszko committed Aug 28, 2015
1 parent 36dfc50 commit 695c6cf
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 33 deletions.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,14 @@ Here instead, we're saying "If condition is met, return some view. Otherwise, ad
RequiredIfAttribute(
string expression,
[bool AllowEmptyStrings],
[int Priority] ...) - Validation attribute which indicates that annotated
[int Priority]
[string ErrorMessage] ...) - Validation attribute which indicates that annotated
field is required when computed result of given logical
expression is true.
AssertThatAttribute(
string expression,
[int Priority] ...) - Validation attribute, executed for non-null annotated
[int Priority]
[string ErrorMessage] ...) - Validation attribute, executed for non-null annotated
field, which indicates that assertion given in logical
expression has to be satisfied, for such field to be
considered as valid.
Expand All @@ -141,6 +143,12 @@ Priority - Gets or sets the hint, available for any concerned external
indicating the order in which this attribute should be executed among
others of its kind, i.e. ExpressiveAttribute. Value is optional and not
set by default, which means that execution order is undefined.
ErrorMessage - Gets or sets an explicit error message string. A difference to default
behavior is awarness of new format specifiers, given in curly brackets,
used to extract values of specified fields, e.g. {field}, {field.field}
within current model context. Braces can be escaped by double-braces,
i.e. to output a { use {{ and to output a } use }}. The same logic works
for messages provided in resources.
```

Full API documentation *(probably not useful at all, since the note above covers almost exhaustively what is actually needed to work with EA)* generated with [Sandcastle](https://sandcastle.codeplex.com/) (with the support of [SHFB](http://shfb.codeplex.com/)), can be downloaded in the form of compiled HTML help file from [here](doc/api/api.chm?raw=true) (only C# API, no JavaScript there).
Expand Down
Binary file modified doc/api/api.chm
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.4.1.0")]
[assembly: AssemblyFileVersion("2.4.1.0")]
[assembly: AssemblyVersion("2.4.2.0")]
[assembly: AssemblyFileVersion("2.4.2.0")]
2 changes: 1 addition & 1 deletion src/ExpressiveAnnotations.Tests/AttribsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public void verify_default_error_messages_after_validation()
}

[TestMethod]
public void verify_values_extraction_for_error_messages_before_validation() // before validation custom formatters are not applied (and e.g. are sent in unchanged form to client)
public void verify_values_extraction_for_error_messages_before_validation() // before validation, custom format specifiers used to extract fields values are not interpreted (to be sent in unchanged form to client)
{
AssertErrorMessage(
"field: {0}, expr: {1} | Value1: {Value1}{Value1}, Internal.Internal.Value1: {Internal.Internal.Value1}, {Internal.Internal.Value1}",
Expand Down
19 changes: 10 additions & 9 deletions src/ExpressiveAnnotations/Attributes/ExpressiveAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ public void Compile(Type validationContextType, bool force = false)
/// <returns>
/// The localized message to present to the user.
/// </returns>
/// <remarks>
/// This method interprets custom format specifiers, provided to error message string, for which model fields values will be extracted. Specifiers should be
/// given in braces (curly brackets), e.g. {field}, {field.field}. Braces can be escaped by double-braces, i.e. to output a { use {{ and to output a } use }}.
/// </remarks>
public string FormatErrorMessage(string displayName, string expression)
{
var matches = Regex.Matches(ErrorMessageString, _fieldRegex);
Expand All @@ -184,10 +188,10 @@ public string FormatErrorMessage(string displayName, string expression)
substitutes[arg] = Guid.NewGuid().ToString();
}

// substitute custom formatters not to interfere with standard string.Format
// substitute custom format specifiers not to interfere with standard string.Format logic
message = substitutes.Aggregate(message, (current, kvp) => current.Replace(kvp.Key, kvp.Value));
message = string.Format(message, displayName, expression);
// give back custom formatters - standard string.Format is already done, so it will not fail
// give back custom format specifiers - standard string.Format is already done, so it will not fail
message = substitutes.Aggregate(message, (current, kvp) => current.Replace(kvp.Value, kvp.Key));

if (_messageValuesMap.Any())
Expand Down Expand Up @@ -269,13 +273,10 @@ private void ExtractValuesForMessage(ValidationContext validationContext)
throw new FormatException("Input string was not in a correct format.");

var length = leftBraces.Length;
var left = new StringBuilder();
var right = new StringBuilder();
for (var j = 0; j < length / 2; j++) // flatten each pair of braces (curly brackets) into single artifact,
{ // in order to escape them - to output a { use {{ and to output a } use }} (just like standard string.Format does)
left.Append("{");
right.Append("}");
}
// flatten each pair of braces (curly brackets) into single artifact
// in order to escape them - to output a { use {{ and to output a } use }} (just like standard string.Format does)
var left = new string('{', length/2);
var right = new string('}', length/2);

var param = arg.Substring(length, arg.Length - 2 * length);
if (length % 2 != 0) // substitute param with respective value (just like string.Format does)
Expand Down
4 changes: 2 additions & 2 deletions src/ExpressiveAnnotations/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.3.2.0")]
[assembly: AssemblyFileVersion("2.3.2.0")]
[assembly: AssemblyVersion("2.3.3.0")]
[assembly: AssemblyFileVersion("2.3.3.0")]
30 changes: 13 additions & 17 deletions src/expressive.annotations.validate.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* expressive.annotations.validate.js - v2.6.1
/* expressive.annotations.validate.js - v2.6.2
* Client-side component of ExpresiveAnnotations - annotation-based conditional validation library.
* https://github.com/JaroslawWaliszko/ExpressiveAnnotations
*
Expand Down Expand Up @@ -547,31 +547,27 @@ var
}
if (options.message) {
options.messages[adapter] = function(params, element) {
var matches, message, remaining;
var matches, message, remaining, arg, leftBraces, rightBraces, length, left, right, param;
message = remaining = options.message;
while ((matches = /({+)[a-zA-Z_]+(?:(?:\.[a-zA-Z_])?[a-zA-Z0-9_]*)*(}+)/g.exec(remaining)) !== null) { // search for custom string formatters, e.g. {field} {field.field}, for field values to be extracted
var arg = matches[0]; // braces can be escaped by double-braces, i.e. to output a { use {{ and to output a } use }}
var leftBraces = matches[1];
var rightBraces = matches[2];
while ((matches = /({+)[a-zA-Z_]+(?:(?:\.[a-zA-Z_])?[a-zA-Z0-9_]*)*(}+)/g.exec(remaining)) !== null) { // search for custom string format specifiers, e.g. {field} {field.field}, for field values to be extracted
arg = matches[0]; // braces can be escaped by double-braces, i.e. to output a { use {{ and to output a } use }}
leftBraces = matches[1];
rightBraces = matches[2];

if (leftBraces.length !== rightBraces.length)
throw 'Input string was not in a correct format.';

var length = leftBraces.length;
var left = '';
var right = '';
for (var j = 0; j < parseInt(length / 2); j++) // flatten each pair of braces (curly brackets) into single artifact, in order to escape them
{
left += '{';
right += '}';
}
length = leftBraces.length;
// flatten each pair of braces (curly brackets) into single artifact, in order to escape them
left = new Array(parseInt(length / 2) + 1).join('{');
right = new Array(parseInt(length / 2) + 1).join('}');

var param = arg.substr(length, arg.length - 2 * length);
param = arg.substr(length, arg.length - 2 * length);
if (length % 2 !== 0) // substitute param with respective value
param = modelHelper.extractValue(params.form, param, params.prefix, 'string', null);

remaining = remaining.replace(arg, '');

message = message.replace(arg, typeHelper.string.format("{0}{1}{2}", left, param, right));
remaining = remaining.replace(arg, '');
}
return message;
};
Expand Down

0 comments on commit 695c6cf

Please sign in to comment.