@@ -230,6 +230,34 @@ TResource = class
230
230
{ $ENDIF}
231
231
end ;
232
232
233
+ { $IFDEF SUPPORTS_GENERICS}
234
+ TMultiPartFormAttachment = class
235
+ private
236
+ FFileName: string;
237
+ FMimeType: string;
238
+ FContent: TStringStream;
239
+ public
240
+ constructor Create(MimeType, FileName: string); overload;
241
+ constructor Create(Source: TStream; MimeType, FileName: string); overload;
242
+ constructor Create(FilePath, MimeType, FileName: string); overload;
243
+ destructor Destroy; override;
244
+ property Content: TStringStream read FContent write FContent;
245
+ property MimeType: string read FMimeType write FMimeType;
246
+ property FileName: string read FFileName write FFileName;
247
+ end ;
248
+
249
+ TMultiPartFormData = class
250
+ private
251
+ FBoundary: string;
252
+ FContentType: string;
253
+ procedure AddFieldContent (Field: TRttiField; var Content: TStringList);
254
+ public
255
+ constructor Create;
256
+ function ContentAsString : string;
257
+ property ContentType: string read FContentType;
258
+ end ;
259
+ { $ENDIF}
260
+
233
261
implementation
234
262
235
263
uses StrUtils, Math,
@@ -896,21 +924,29 @@ procedure TResource.GetAsDataSet(ADataSet: TDataSet);
896
924
897
925
procedure TResource.SetContent (entity: TObject);
898
926
var
899
- vJson : string;
927
+ vRawContent : string;
900
928
vStream: TStringStream;
929
+ vMultipartFormData: TMultipartFormData;
901
930
begin
902
931
FContent.Clear;
903
- if Assigned(entity) then
932
+ if not Assigned(entity) then
933
+ Exit;
934
+
935
+ if entity is TMultipartFormData then
904
936
begin
905
- vJson := TJsonUtil.Marshal(Entity);
906
-
907
- vStream := TStringStream.Create(vJson);
908
- try
909
- vStream.Position := 0 ;
910
- FContent.CopyFrom(vStream, vStream.Size);
911
- finally
912
- vStream.Free;
913
- end ;
937
+ vMultipartFormData := TMultipartFormData(entity);
938
+ vRawContent := vMultipartFormData.ContentAsString;
939
+ ContentType(vMultipartFormData.ContentType);
940
+ end
941
+ else
942
+ vRawContent := TJsonUtil.Marshal(Entity);
943
+
944
+ vStream := TStringStream.Create(vRawContent);
945
+ try
946
+ vStream.Position := 0 ;
947
+ FContent.CopyFrom(vStream, vStream.Size);
948
+ finally
949
+ vStream.Free;
914
950
end ;
915
951
end ;
916
952
@@ -1016,4 +1052,94 @@ class function TJsonListAdapter.NewFrom(AList: TList; AItemClass: TClass): IJson
1016
1052
Result := TJsonListAdapter.Create(AList, AItemClass);
1017
1053
end ;
1018
1054
1055
+ { TMultiPartFormData }
1056
+
1057
+ { $IFDEF SUPPORTS_GENERICS}
1058
+ procedure TMultiPartFormData.AddFieldContent (Field: TRttiField; var Content: TStringList);
1059
+ const
1060
+ FmtTextContent = ' Content-Disposition: form-data; name="%s"' + sLineBreak+sLineBreak +' %s' ;
1061
+ FmtFileContent = ' Content-Disposition: form-data; name="%s"; filename="%s"' + sLineBreak +' Content-Type: %s' + sLineBreak+sLineBreak+ ' %s' ;
1062
+ var
1063
+ Attachment: TMultiPartFormAttachment;
1064
+ begin
1065
+ if Field.FieldType.TypeKind in [tkString, tkUString, tkWChar, tkLString, tkWString, tkInteger, tkChar, tkWChar] then
1066
+ begin
1067
+ Content.Add(Format(FmtTextContent, [Field.Name , Field.GetValue(Self).AsString]));
1068
+ Exit;
1069
+ end ;
1070
+
1071
+ if Field.FieldType.Name .Equals(TMultiPartFormAttachment.ClassName) then
1072
+ begin
1073
+ Attachment := Field.GetValue(Self).AsType<TMultiPartFormAttachment>;
1074
+ Content.Add(Format(FmtFileContent, [Field.Name , Attachment.FileName, Attachment.MimeType, Attachment.Content.DataString]));
1075
+ end ;
1076
+ end ;
1077
+
1078
+ function TMultiPartFormData.ContentAsString : string;
1079
+ var
1080
+ vField: TRttiField;
1081
+ vContent: TStringList;
1082
+ vBoundary: string;
1083
+ vRttiContext: TRttiContext;
1084
+ vRttiType: TRttiType;
1085
+ begin
1086
+ vBoundary := ' --' + FBoundary;
1087
+
1088
+ vContent := TStringList.Create;
1089
+ try
1090
+ vContent.Add(vBoundary);
1091
+
1092
+ vRttiContext := TRttiContext.Create;
1093
+ vRttiType := vRttiContext.GetType(Self.ClassType);
1094
+ for vField in vRttiType.GetDeclaredFields do
1095
+ begin
1096
+ AddFieldContent(vField, vContent);
1097
+ vContent.Add(vBoundary);
1098
+ end ;
1099
+
1100
+ vContent.Strings[Pred(vContent.Count)] := vBoundary + ' --' ;
1101
+ Result := vContent.Text;
1102
+ finally
1103
+ vContent.Free;
1104
+ end ;
1105
+ end ;
1106
+
1107
+ constructor TMultiPartFormData.Create;
1108
+ const
1109
+ FmtBoundary = ' boundary--%s' ;
1110
+ FmtContentType = ' multipart/form-data; boundary=%s' ;
1111
+ var
1112
+ vGUID: TGUID;
1113
+ begin
1114
+ CreateGUID(vGUID);
1115
+ FBoundary := Format(FmtBoundary, [GUIDToString(vGUID)]);
1116
+ FContentType := Format(FmtContentType, [FBoundary]);
1117
+ end ;
1118
+
1119
+ constructor TMultiPartFormAttachment.Create(Source: TStream; MimeType, FileName: string);
1120
+ begin
1121
+ Create(MimeType, FileName);
1122
+ FContent.LoadFromStream(Source);
1123
+ end ;
1124
+
1125
+ constructor TMultiPartFormAttachment.Create(FilePath, MimeType, FileName: string);
1126
+ begin
1127
+ Create(MimeType, FileName);
1128
+ FContent.LoadFromFile(FilePath);
1129
+ end ;
1130
+
1131
+ constructor TMultiPartFormAttachment.Create(MimeType, FileName: string);
1132
+ begin
1133
+ FContent := TStringStream.Create;
1134
+ FMimeType := MimeType;
1135
+ FFileName := FileName;
1136
+ end ;
1137
+
1138
+ destructor TMultiPartFormAttachment.Destroy;
1139
+ begin
1140
+ FContent.Free;
1141
+ inherited ;
1142
+ end ;
1143
+ { $ENDIF}
1144
+
1019
1145
end .
0 commit comments