The difference between the boolean and Boolean types in flow is documented.
However, I failed to find a mention of the bool type that apparently is also accepted. The below typechecks fine with 0.35.0:
let b1: bool = true;
let b2: boolean = true;
b1 = !b2;
b2 = !b1;
I believe they are equivalent, and both are supported for legacy reasons (I don't know the full context here). However, boolean is recommended for consistency.
Related
I'm using following struct for data marshaling with PInvoke
[StructLayout(LayoutKind.Sequential)]
struct Data
{
int id;
IntPtr state;
object obj;
}
And all works fine on Windows, but on Linux I'm getting the error:
Cannot marshal field 'obj' of type 'Data': Invalid managed/unmanaged type combination (Marshaling to and from COM interface pointers isn't supported).
Why?
Is it possible to disable marshaling for the specific field ?
object obj; property is invalid
You can try with IntPtr obj;
What is the actual type of obj?
Digging the CLR sources I've found that the issue is really Linux specific, and tied to COM interop feature, which is windows-only.
So I've fixed the problem using IntPtr for obj (as #Simonare suggested) and GCHandle.
public class YourAnnotatedBean {
private Boolean activated;
#Valid
#NotNull
public Boolean isActivated() {
return activated;
}
public void setOn(Boolean activated) {
this.activated = activated;
}
}
Hibernate-validator seems to ignore #NotNull when it is on a Boolean getter called isActivated. If I rename it to getActivated, the constraint is enforced. I would just rename the getter, but this is coming from swagger-codegen.
My question is whether this is intentional or a bug? As far as I can tell, the JavaBeans spec doesn't mention Boolean wrapper objects. If this is not a bug, we'll need to update swagger-codegen to not use the "is" prefix for Booleans.
In the Java Bean convention, "is" is a valid prefix only for a primitive boolean.
Here you have a Boolean so it should really be getActivated(). That's why HV ignores it.
Any chance you could add the constraint to the property instead of the getter?
We have this long term project of allowing alternative property selectors but, for now, it's just a project (see https://hibernate.atlassian.net/browse/HV-1363).
I have my custom validator and I want to add some error messages for it.
So I have next code:
#Override
public boolean isValid(final String label,
final ConstraintValidatorContext constraintValidatorContext) {
constraintValidatorContext.disableDefaultConstraintViolation();
if(label.length() > MAX_LENGTH) {
constraintValidatorContext
.buildConstraintViolationWithTemplate("{error.maxLength}")
.addConstraintViolation();
return false;
}
...
}
My message looks like error.maxLength=You have exceeded max length of {0}, so it has parameter of maxLength.
It it possible to add it when building constraint violation?
Yes, you can.
You have to unwrap the ConstraintValidatorContext to an HibernateConstraintValidatorContext with:
HibernateConstraintValidatorContext hibernateConstraintValidatorContext = constraintValidatorContext.unwrap( HibernateConstraintValidatorContext.class );
Then, you can either use:
hibernateConstraintValidatorContext.addMessageParameter("name", value);
(and yours look like a message parameter ({variable}) so it's probably what you have to use - note you need HV 5.4.1.Final to have this method)
or
hibernateConstraintValidatorContext.addExpressionVariable("name", value);
if it's an expression variable (so using Expression Language and something like ${variable})
Here is what I have so far:
[Route("EndTest/{examId:int}/{userTestId:int}/{retrieve:boolean}")]
public async Task<IHttpActionResult> EndTest(int examId, int userTestId, bool retrieve)
Can someone validate if this is the correct way to do this, if it is even possible and if so then how could I pass the boolean with a Http call?
According to this Route Constraints you need to change boolean to bool.
//eg: GET /EndTest/1234/56789/true
[HttpGet]
[Route("EndTest/{examId:int}/{userTestId:int}/{retrieve:bool}")]
public async Task<IHttpActionResult> EndTest(int examId, int userTestId, bool retrieve) {...}
It is also good practice to indicate what HTTPMethod is allowed when adding route attributes that do not conform to the default convention used by the framework. I added HttpGetAttribute in my example.
Given the following class:
[DataContract]
public class Enumerables
{
[DataMember]
public IEnumerable<Byte> ByteMember { get; set; }
}
And an instance initialized as:
var bytes = new byte[] { ... };
var o = new Enumerables { ByteMember = bytes };
Serialization produces this:
{"ByteMember": "<<base-64-encoded-string>>"}
But this string cannot be deserialized. The error produced is:
Newtonsoft.Json.JsonSerializationException : Error converting value
"vbMBTToz9gyZj6gZuA59rE7ryu3fCfimjVMn8R6A0277Xs9u" to
type 'System.Collections.Generic.IEnumerable`1[System.Byte]'.
Path 'ByteMember', line 1, position 8084.
----> System.ArgumentException : Could not cast or convert from
System.String to System.Collections.Generic.IEnumerable`1[System.Byte].
I don't see this happening for byte[], List<byte> or Collection<byte> properties, which are correctly serialized to and from base-64 strings. And I don't see this happening for any IEnumerable<T> where T is not a byte -- for example, a property of type IEnumerable<int> deserializes to a List<double>, an effective implementation.
How an IEnumerable<byte> gets serialized depends on the concrete type that is assigned to it. If the concrete type is a byte[] then it will get serialized specially as a base-64 encoded string, whereas if it is some other concrete type like a List<byte>, it will be serialized as a normal array of numbers. The same is true of ICollection<byte> and IList<byte>. (DEMO)
On deserialization, Json.Net looks at the types of the member properties of the target class to determine what types of objects to create. When the member property is a concrete type, no problem; it creates an instance of that type and tries to populate it from the JSON. If the member type is an interface, then Json.Net has to make a guess, or throw an error. You could argue that Json.Net should be smart enough to guess that if the member variable is an IEnumerable<byte> and the JSON value is a base-64 encoded string, it should convert the string to a byte[]. But that is not how it is implemented. In fact, the special handling for base-64 encoded byte arrays is only triggered if the member property is byte[] specifically. With no special handling for IEnumerable<byte>, this results in an error because a string can't be assigned directly to an IEnumerable<byte>. Again, the same is true for ICollection<byte> or IList<byte>.
(DEMO)
If you want it to work the same for types implementing IEnumerable<byte> as it does for byte[], you can make a custom JsonConveter like this:
public class EnumerableByteConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(IEnumerable<byte>).IsAssignableFrom(objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
byte[] bytes = ((IEnumerable<byte>)value).ToArray();
writer.WriteValue(Convert.ToBase64String(bytes));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
byte[] bytes = Convert.FromBase64String(reader.Value.ToString());
if (objectType == typeof(byte[]))
{
return bytes;
}
return new List<byte>(bytes);
}
}
To use the converter, create an instance of JsonSerializerSettings and add an instance of the converter to the Converters collection. Then, pass the settings to SerializerObject() and DeserializeObject() methods. For example:
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Converters.Add(new EnumerableByteConverter());
string json = JsonConvert.SerializeObject(obj, settings);
Here is a working round-trip demo. Note, however, that this converter doesn't (and can't) handle every possible IEnumerable<byte> that might be out there. For example, it won't work with ISet<byte> as currently implemented. If you need support for this or other additional types, you will need to extend the ReadJson method to handle that. I leave this to you.