This error only occurs using Controls with Windows RichEdit library.
My fix needs to override SetPropValue of TAureliusDataset.
if not TrySetBlobRtf(aPropName, Obj, Value, procedure(aBlob: TBlob; aOpti: TRttiOptimization)
begin
Explorer.SetMemberValue(Obj, aOpti, TValue.From(aBlob));
end) then
inherited;
function TrySetBlobRtf(aPropName: string; aObj: TObject; aValue: ValueType; aOnSetValue: TProc<TBlob, TRttiOptimization>): Boolean;
var
hOpti: TRttiOptimization;
hMember: TRttiMember;
hBlob: TBlob;
begin
Result := False;
if VarIsNull(aValue) or VarIsEmpty(aValue) or not VarIsStr(aValue) then
Exit;
hOpti := Explorer.FindOptimization(aObj.ClassType, aPropName);
try
hMember := nil;
if Assigned(hOpti) then
hMember := hOpti.MemberRef;
if Assigned(hMember) and hMember.HasAttribute<DbTypeWideMemo> then
begin
hBlob.AsUnicodeString := Trim(VarToStr(aValue)); // VarToStr returns #13#10#0 instead of #13#10 from VarToStrDef... so we have to trim...
aOnSetValue(hBlob, hOpti);
Result := True;
end;
finally
hOpti.Free;
end;
end;
it should have clarified stuff, but looks like it failed...
in TCustomAureliusDataset.SetPropValue you are doing this:
if SubProp = '' then
begin
if O.RealType.IsInstance then
MemberValue := TValue.From<TObject>(VariantToObject(Value))
else
begin
if (O.IsNullable or O.IsAssignable) and VarIsNull(Value) then
MemberValue := TValue.Empty
else
if IsEnumeration(O.RealType.Handle) then
MemberValue := TValue.FromOrdinal(O.RealType.Handle, Value)
else
MemberValue := Explorer.VariantToValue(Value, O); // got trailing #0 in MemberValue
end;
Explorer.SetMemberValue(Obj, O, MemberValue);
end
...
taking a look into TMappingExplorer.VariantToValue:
...
if IsBlob(ATypInfo) then
begin
if VarIsNull(Value) or VarIsEmpty(Value) then
blob.IsNull := True
else
blob.AsBytes := TUtils.VariantToBytes(Value); // recieving TBytes with leading #0
Result := TValue.From<TBlob>(blob);
end
...
that's because string(V) is returning this wrong value in TUtils.VariantToBytes is returning
...
varUString: result := TEncoding.Unicode.GetBytes(string(V));
...
You would need a blob field in your entity with DbTypeWideMemo.
Open this in TAureliusDataset and
set fieldvalue using AsVariant := 'sometext' + #13#10#0;
You will see, that #0 will also appear in Bytestream...
That code is there for years. The TEncoding.GetBytes is simply that, get the bytes of a string.
If you are using this with something that is not exactly a string - but a RTF - you should not use ftWideMemo or [DBTypeWideMemo], but instead just using a raw TBlob type.