DelphiMVCFramework 3.5 RC7 zieht in den Project Manager von Delphi ein und spricht mit KI-Agenten
🇬🇧 English • 🇮🇹 Italiano • 🇪🇸 Español • 🇧🇷 Português • 🇫🇷 Français

Was hat sich in DelphiMVCFramework seit der RC6 getan? Die Arbeit an 3.5 drehte sich darum, wie du ein Projekt anlegst und wachsen lässt, in der Delphi-IDE und zusammen mit KI-Agenten. Diesmal zeige ich es dir mit Screenshots.
DelphiMVCFramework 3.5.0-silicon RC7 ist ein Release Candidate, nicht die fertige 3.5.0: die Funktionen sind die, die du hier siehst, und das stabile Tag kommt, wenn der RC auf anderen Maschinen als meiner gelaufen ist.
Die RC6 ist vom 23. August, und im Post dazu ging es um Hosts, Minimal API und den Streaming-Serializer. Die RC7 kam am 22. September. Danach sind auf master zwei Neuerungen für die tägliche Arbeit an einem Projekt dazugekommen. Ein DMVCFramework-Menü im Project Manager von Delphi legt Controller, Routengruppen und Views an und registriert sie im Projekt. Die Dateien für KI-Agenten geben deinem Assistenten die Regeln und die Quellen des Frameworks, damit er die API nicht aus dem Gedächtnis schreibt. Dann gibt es noch den Rest: Swagger UI mit OpenAPI 3, die generierten Webseiten, QUERY, ProblemDetails.
Hier unten folgt ein kurzer Rundgang, fast nur in Bildern. Jedes Thema hat sein eigenes Kapitel im offiziellen Handbuch, 2. Auflage, mit dem vollständigen Code und den Erklärungen, die ich in diesem Post überspringe.
Was wo liegt
Alles, was du hier siehst, gehört zur RC7: das ist die Version, die der Wizard in die generierten Projekte schreibt (3.5.0-silicon-rc7, du findest sie auch in den Screenshots). Ein Teil davon ist aber noch nicht im Zip des Tags:
- In der RC7 (Tag v3.5.0-silicon-rc7): die HTTP-Methode
QUERY, das Sicherheits-Review mit seinen neuen Standardwerten, die Limits des WebSocket-Servers, die Korrekturen für HTTP.sys, SQL Server und Delphi 13.2. - Auf master, nach der RC7: alles andere. Das Menü im Project Manager, die Dateien für KI-Agenten, der Wizard mit OpenAPI 3, die generierten Webseiten, das Sample mit den Formularen, ProblemDetails. Um sie zu bekommen, klonst du master.
Die Screenshots unten stammen von master.
Ein DMVCFramework-Menü im Project Manager
In Delphi 12 und 13 machst du im Project Manager einen Rechtsklick auf ein DelphiMVCFramework-Projekt, und da ist ein Untermenü DMVCFramework:

Du wählst New REST Controller…, gibst den Namen ein, und der Rest füllt sich von selbst: das URL-Segment und die Modellklasse, an die der Body der Requests gebunden wird.

Du drückst OK, und das Menü legt Controllers.OrdersU.pas an, fügt die Unit dem Projekt hinzu und registriert sie in EngineConfigU.pas: die Unit in der uses und AEngine.AddController(TOrdersController) neben den anderen Controllern. Die Änderungen laufen über den Editor-Puffer, ein Strg+Z macht sie also rückgängig.

Das ist der generierte Controller, so wie er aus dem Menü kommt, in einem Projekt mit aktiver OpenAPI-Dokumentation:
type
TOrder = class
private
fID: Integer;
fName: string;
public
property ID: Integer read fID write fID;
[MVCRequired]
property Name: string read fName write fName;
end;
[MVCPath('/api/orders')]
[MVCSWAGDefaultModel(TOrder, 'Order', 'Orders')]
[MVCSWAGDefaultSummaryTags('Orders')]
TOrdersController = class(TMVCController)
public
[MVCPath]
[MVCHTTPMethod([httpGET])]
[MVCSwagSummary(TSwaggerConst.USE_DEFAULT_SUMMARY_TAGS, 'List orders', 'getOrders')]
// last argument: OkResponse renders the body as {"data": ...}
[MVCSwagResponses(200, 'Success', SWAGUseDefaultControllerModel, True, True)]
function GetAll: IMVCResponse;
[MVCPath('/($ID:int)')]
[MVCHTTPMethod([httpGET])]
[MVCSwagSummary(TSwaggerConst.USE_DEFAULT_SUMMARY_TAGS, 'Get one', 'getOrder')]
[MVCSwagResponses(200, 'Success', SWAGUseDefaultControllerModel, False, True)]
[MVCSwagResponses(404, 'Not found')]
function GetByID(ID: Integer): IMVCResponse;
// the body is bound to Item and validated (422 on failure); the framework frees it
[MVCPath]
[MVCHTTPMethod([httpPOST])]
[MVCSwagSummary(TSwaggerConst.USE_DEFAULT_SUMMARY_TAGS, 'Create', 'createOrder')]
[MVCSwagParam(plBody, 'Item', 'The item to create', SWAGUseDefaultControllerModel)]
[MVCSwagResponses(201, 'Created')]
[MVCSwagResponses(422, 'Validation failed')]
function CreateItem([MVCFromBody] Item: TOrder): IMVCResponse;
...
Der Body kommt schon deserialisiert in Item an und ist schon validiert: ohne name erreicht der Request die Action gar nicht, und der Client bekommt ein 422. Das Schema der Antworten kommt aus der Modellklasse: mit dem letzten Argument von MVCSwagResponses beschreibt das Dokument auch die Hülle {"data": ...}, die OkResponse hinzufügt. Die MVCSwag*-Attribute gibt es nur, wenn das Projekt ein OpenAPI-Dokument veröffentlicht, und deshalb erscheinen Orders und sein Modell in Swagger UI, ohne dass ich eine Zeile geschrieben habe: das siehst du weiter unten.
Das Menü zeigt nur, was das Projekt aufnehmen kann. In einem Minimal-API-Projekt ergäbe ein Controller keinen Sinn, und dort steht entsprechend ein anderer Eintrag:

New Minimal API Route Group… legt OrdersRoutesU.pas mit einer Prozedur MapOrdersRoutes an (Bodys per Typ gebunden, mit MapPost<TOrder> und MapPut<Integer, TOrder>) und hängt den Aufruf ans Ende von ConfigureRoutes. Die beiden anderen Einträge sind New Web Controller and View… und New TemplatePro View…, und sie erscheinen nur, wenn das Projekt einen Views-Ordner hat. In Delphi-Versionen vor 12 gibt es das Menü nicht.
Ein Projekt, das mit den richtigen Skills startet
Wenn du Code mit Claude Code, Codex, Cursor oder Gemini schreibst, erfindet ein Agent, der DelphiMVCFramework nicht kennt, plausible Methodennamen, oder er nimmt die einer alten Version, und der Compiler sagt es dir erst hinterher.
Mit der RC7 ist jedes neue DelphiMVCFramework-Projekt von Anfang an für den Agenten vorbereitet: der Wizard legt die Skills dazu, die zu diesem Projekttyp passen, aus derselben Framework-Linie, die du verwendest. Das sind Best Practices, geschrieben für alle, die mit DelphiMVCFramework entwickeln, nach Themen aufgeteilt:
- Delphi: die Sprache und die RTL, die Unterschiede zwischen den Versionen, die Speicherverwaltung, Strings, Generics, Threads; dazu eine Code-Review-Skill zu Warnings, statischer Analyse und Memory Leaks.
- DelphiMVCFramework: Controller, ActiveRecord, Validierung, Dependency Injection, Middleware, die drei Hosts,
.env. - Sicherheit: die Regeln für jeden Endpoint, der Eingaben vom Client bekommt.
- Tests: Integrationstests mit DUnitX.
- Minimal API, Web-Anwendung, Oberfläche, JSON-RPC: wenn das Projekt sie verwendet.
- HTMX: die offizielle Dokumentation, für den Agenten aufbereitet.
Den Vorteil siehst du ab der ersten Anfrage. Ohne Skills und ohne AGENTS.md beginnt jede Sitzung mit dem Agenten damit, dass du ihm das Projekt und das Framework erklärst, und geht damit weiter, dass du den Code korrigierst, den er aus dem Gedächtnis geschrieben hat: eine Methode, die es nicht gibt, ein Pattern aus einer alten Version, ein Objekt, das zweimal freigegeben wird. Mit dem Projekt aus dem Wizard weiß der Agent schon, wie das Projekt aufgebaut ist, wo die Quellen des Frameworks liegen und wie man in DelphiMVCFramework 3.5 einen Controller, eine ActiveRecord-Entity oder eine HTMX-Seite schreibt. Diese Zeit sparst du in jeder Sitzung.
Dazu kommt die Sicherheit. Unter den Skills, die in jedem Projekt installiert werden, ist dmvcframework-security, mit den Regeln für jeden Endpoint, der Eingaben vom Client bekommt: Zugriffskontrolle, Mass Assignment, SQL Injection, XSS, CSRF, Path Traversal und Uploads, JWT, Secrets und Fehlermeldungen, dazu eine Checkliste, die man durchgeht, bevor ein Endpoint in Produktion geht. Der Agent liest sie, bevor er einen Endpoint schreibt, deshalb ist der Code, den du bekommst, in der Regel sicherer als der, den er von Grund auf schreiben würde.
Die Skills liegen in einem eigenen Repository, mit einem Branch pro Framework-Linie, und sie werden unabhängig von den Releases aktualisiert: wenn eine neue Version einer Skill erscheint, holt update_ai_skills.bat im Projektordner sie ins Projekt.
Die Option steht auf der Seite Project Options, AI coding agent files and skills, und ist in allen Presets standardmäßig aktiv. Die Skills werden heruntergeladen, während der Wizard das Projekt anlegt, mit einem Fortschrittsbalken, den du abbrechen kannst; wenn du sie nicht brauchst, nimm den Haken raus.

Mit aktiver Option schreibt der Wizard in den Projektordner eine AGENTS.md mit den Fakten zum Projekt, dazu CLAUDE.md und GEMINI.md, die sie importieren. Dann lädt er die zum Projekttyp passenden delphi-ai-skills nach .claude\skills herunter, aus dem Branch, der zur Framework-Version gehört (für diese Version dmvc-3.5). Das ist die AGENTS.md eines RESTful-API-Projekts, generiert von der Testsuite des Wizards, die es TestProject nennt:
# TestProject
DelphiMVCFramework 3.5.0-silicon-rc7 project, generated by the DMVCFramework IDE wizard.
- `TestProject.dproj` builds the executable into `bin\`, next to `bin\.env` (configuration and secrets: never commit real values).
- Build from the command line: `rsvars.bat`, then `msbuild TestProject.dproj /p:Config=Debug /p:Platform=Win32`.
## Skills
Before writing Delphi or DelphiMVCFramework code, read the skill for the task. They target DelphiMVCFramework 3.5.x; `update_ai_skills.bat` downloads or refreshes them.
- `.claude/skills/delphi/SKILL.md` - the language and the RTL: version gating, lifetime, strings, generics, threading
- `.claude/skills/delphi-code-smells/SKILL.md` - code review: compiler warnings, static analysis, memory leaks
- `.claude/skills/dmvcframework/SKILL.md` - controllers, ActiveRecord, validation, DI, middleware, servers, dotEnv
- `.claude/skills/dmvcframework-security/SKILL.md` - REQUIRED for any endpoint taking client input
- `.claude/skills/dmvcframework-testing/SKILL.md` - DUnitX integration tests
Do not write Delphi or DelphiMVCFramework code from memory: the API names in these files are authoritative.
<!-- delphi-local-sources -->
DelphiMVCFramework checkout: C:\DEV\dmvcframework (sources/ + samples/)
Delphi RTL/VCL source: C:\Program Files (x86)\Embarcadero\Studio\37.0\source (CompilerVersion 37.0)
<!-- /delphi-local-sources -->
Der letzte Block sagt dem Agenten, wo auf deiner Platte die Quellen des Frameworks und der RTL liegen: wenn er sich bei einem Namen nicht sicher ist, liest er den echten Code.
Welche Skills installiert werden, hängt vom Projekt ab. delphi, delphi-code-smells, dmvcframework, dmvcframework-security und dmvcframework-testing sind immer dabei; ein Minimal-API-Projekt bekommt zusätzlich dmvcframework-minimal-api, eine Web-Anwendung dmvcframework-webapp und dmvcframework-ui, mit HTMX auch htmx-skill, ein JSON-RPC-Service dmvcframework-jsonrpc. Klappt der Download beim Anlegen nicht, wird das Projekt trotzdem angelegt, mit einer Warnung, und update_ai_skills.bat erledigt die Installation, sobald du online bist.
Der Wizard: API-Dokumentation und JWT-Schlüssel
Auf der Seite Features des Custom-Presets gibt es eine neue Option, API documentation (OpenAPI 3). In den anderen Presets siehst du sie nicht, weil sie dort schon entschieden ist: aktiv für RESTful API, Minimal API RESTful und Full-Stack.

Mit aktiver Option lädt der Wizard beim Anlegen des Projekts das offizielle Release von Swagger UI (5.33.0, per SHA-256 geprüft) nach bin\www\swagger herunter. Bist du offline, wird das Projekt trotzdem angelegt, und in diesem Ordner liegt eine README mit den Schritten, um es von Hand herunterzuladen. Das Dokument wird nur veröffentlicht, wenn die .env dmvc.openapi.enabled=true enthält: die generierte .env enthält es, die für die Produktion nicht, und in der Produktion geht die Dokumentation nicht raus.
Projekte mit JWT haben jetzt in der .env ein eigenes JWT_SECRET, 384 Bit aus dem kryptografischen Zufallsgenerator des Systems, bei jeder Generierung anders. Die generierte .gitignore schließt die .env schon aus.
Swagger UI mit OpenAPI 3
Das ist das mit dem Preset RESTful API generierte Projekt, dem ich mit dem Menü von eben den Controller Orders hinzugefügt habe. Du startest es, öffnest http://localhost:8080/swagger und findest das hier:

Die Swagger-Middleware, die du seit Jahren verwendest, erzeugt jetzt auch OpenAPI 3. Das Dokument baut SwagDoc, die im Framework enthaltene Bibliothek, und die OpenAPI-3-Unterstützung in SwagDoc hat Marcelo Jaloto geschrieben (PR #916): danke, Marcelo! Das Format wählst du mit einem neuen letzten Parameter, ASpecVersion, der standardmäßig bei Swagger 2.0 bleibt; wer aktualisiert, sieht also keine Änderung. Das generierte Projekt registriert sie so:
AEngine.AddMiddleware(TMVCSwaggerMiddleware.Create(AEngine, LSwaggerInfo, '/openapi.json',
JWT_DEFAULT_DESCRIPTION, False, '', '', '', [psHTTP], False, ssvOpenAPI3));
AEngine.AddMiddleware(TMVCStaticFilesMiddleware.Create('/swagger',
TPath.Combine(TPath.Combine(AppPath, 'www'), 'swagger')));
Alles, was mit Swagger 2.0 funktioniert hat, funktioniert weiter: JWT- und Basic-Sicherheit, MVCSwagAuthentication, MVCSWAGDefaultModel, die CRUD-Pfade von TMVCActiveRecordController. Das JWT-Schema ist http/bearer, im Fenster Authorize fügst du das Token also so ein, wie es ist. Der Server im Dokument ist relativ, und “Try it out” ruft den Origin auf, der das Dokument ausgeliefert hat, auch hinter einem Proxy.

In Minimal-API-Projekten registriert der Wizard stattdessen den Filter OpenAPI(...) aus MVCFramework.OpenAPI3, der aus den Lambda-Routen ein OpenAPI-3.1-Dokument erzeugt und es unter derselben URL veröffentlicht, mit derselben Swagger UI.
Felder vom Typ TDate, TDateTime und TTime werden jetzt mit den Standardformaten date, date-time und time beschrieben, ein aus dem Dokument neu generierter Client bekommt also Datumstypen statt Strings (auch das kommt mit Marcelos PR). Die Dokumentationsattribute für Felder heißen jetzt alle MVCSwag*: MVCFormat, MVCMinimum und MVCMaximum kompilieren noch, mit einer Warnung, bis zur 4.0.
Die generierten Web-Anwendungen
Das Preset Web Application startet jetzt mit einer vollständigeren Oberfläche: Seitenkopf, ein Panel mit dem Serverstatus, per HTMX aktualisiert, eine Liste “Start here” mit den ersten Schritten, helles und dunkles Theme. Der generierte Code bleibt aber minimal: das Beispiel mit Tabelle und Formular ist in ein eigenes Sample gewandert, dazu weiter unten mehr.


Das Preset Minimal API WebApp erzeugt dieselben Seiten, mit Lambda-Routen statt Controllern. Unten siehst du die Login-Seite nach einem falschen Versuch: der Benutzername bleibt im Feld, das Passwort nicht. Das Formular ist an eine Klasse gebunden, und die Seite zeigt es von dort aus erneut an.

Tabellen und Formulare mit HTMX: webapp_htmx_forms
Das Beispiel mit der People-Tabelle, das vorher im generierten Projekt stand, ist ein eigenes Sample geworden: samples/webapp_htmx_forms. Dort gibt es Suche, Filter, Sortierung und die vollständigen Formulare, ohne jedes neue Projekt damit zu belasten.
Die Tabelle lässt sich filtern, durchsuchen und nach Spalte sortieren. Mit HTMX liefert der Server nur das Fragment der Tabelle zurück, und die Seite lädt nicht neu; die Action entscheidet, ob sie die ganze Seite oder das Fragment schickt, und setzt Vary: HX-Request, weil dieselbe URL zwei verschiedene Bodys hat.

Die Formulare zum Anlegen und Bearbeiten verwenden alle Makros der Formularbibliothek von TemplatePro (bin/templates/lib/forms_bootstrap5.tpro, die der Wizard in jedes TemplatePro-Projekt kopiert) und werden auf dem Server mit den Attributen von DelphiMVCFramework und TMVCValidationEngine validiert. Wenn etwas nicht passt, kommt das Formular mit Status 422 zurück, mit den Werten, die du eingegeben hast, und der Meldung neben dem Feld. Passt alles, folgt ein Redirect zur Tabelle (Post/Redirect/Get), damit ein F5 das Formular nicht erneut sendet.

Auf der TemplatePro-Seite liegt der Cache der kompilierten Views jetzt im Speicher: mit view_cache=true greift eine View nach dem ersten Request nicht mehr auf die Platte zu. Wenn du die Views änderst, während der Server läuft, schaltet dmvc.view_cache_check_changes=true die Prüfung bei jedem Request wieder ein, Layouts und Partials eingeschlossen.
Mit TemplatePro generierte Formulare
Das Formular im Screenshot oben kommt aus der Formularbibliothek von TemplatePro, forms_bootstrap5.tpro, die der Wizard in jedem Projekt mit TemplatePro-Views nach bin/templates/lib kopiert. Du importierst sie einmal oben auf der Seite und hast acht Makros: form, input, textarea, select, checkbox, submit, actions und auto.
{{import "../lib/forms_bootstrap5.tpro" as f}}
{{call f.form(form_action)}}
{{>f.input("id", label="ID", readonly=true)}}
{{>f.input("name", label="Name", required=true)}}
{{>f.select("role", roles, label="Role", empty="Choose a role")}}
{{>f.input("projects", type="number", append="active")}}
{{>f.textarea("notes", label="Notes", rows=3)}}
{{>f.checkbox("remote", label="Works remotely")}}
{{>f.submit("Save")}}
{{endcall}}
Jedes Makro liest den Wert des Felds aus formModel und die Fehlermeldung aus formErrors, zwei Variablen, die du in der Action setzt. Das Modell kann ein Objekt sein, der aktuelle Datensatz eines Datasets, ein JSON-Objekt oder ein Dictionary. Gibt es für ein Feld einen Fehler, bekommt das Steuerelement die Klasse is-invalid, und die Meldung erscheint darunter: das siehst du im erneut angezeigten Formular mit dem 422. Werte und Meldungen sind immer HTML-escaped, Datumswerte werden für die Steuerelemente date, time und datetime-local formatiert, und mit attrs übergibst du eine Map mit zusätzlichen Attributen, zum Beispiel denen von HTMX. Dieselbe Seite dient zum Anlegen und zum Bearbeiten: nur das Modell und die Action ändern sich.
Dann gibt es auto, das das ganze Formular selbst erzeugt:
{{call f.form("/forms", attrs=formattrs)}}
{{>f.auto(demo)}}
{{>f.submit("Save")}}
{{endcall}}

auto geht die Felder des Modells durch (model.@@fields: die Properties eines Objekts oder die Felder eines Datasets) und wählt das Steuerelement nach dem Typ. Ein String wird ein Textfeld mit maxlength aus der Feldgröße, ein Integer ein Zahlenfeld, ein TDate ein Datumswähler, ein TDateTime ein datetime-local, ein TTime ein Uhrzeitfeld, ein Boolean eine Checkbox, ein Memo eine Textarea. Eine Property ohne Setter wird readonly. Die Beschriftung kommt aus dem Namen: aus FullName wird “Full name”. Mit exclude lässt du die Felder weg, die du nicht zeigen willst.
Ist das Modell eine TMVCActiveRecord-Entity, fügst du der uses die Unit MVCFramework.View.Renderers.TemplatePro.ActiveRecord hinzu (der Wizard macht das in Projekten mit ActiveRecord und TemplatePro selbst). Ab dann folgen die Felder dem Mapping von ActiveRecord und den Validatoren: [MVCRequired] wird zum Attribut required, [MVCMaxLength(n)] zu maxlength. Für alles andere gibt es TTProConfiguration.OnGetFieldMetadata, mit dem du Beschriftung, Typ, Sichtbarkeit und Pflichtstatus jedes Felds ändern kannst. Das vollständige Formular mit allen Makros findest du auf der Seite /forms des Samples samples/wizard_showcase/web.
ProblemDetails näher an RFC 7807
Die Antworten von ProblemDetails(...) folgen RFC 7807 jetzt genauer: das Problem-Objekt ist der ganze Body, und der Content-Type ist application/problem+json. Das 422 der Minimal API hat zusätzlich ein Member errors mit der Meldung zu jedem Feld.
Das ist die vom Menü generierte Routengruppe Orders in einem Minimal-API-Projekt: ein POST ohne name, dann ein POST mit einem Array statt des Objekts.
$ curl -s -i -X POST http://localhost:8080/api/orders -H "Content-Type: application/json" -d "{\"id\":7}"
HTTP/1.1 422 Unprocessable Entity
Connection: keep-alive
Content-Type: application/problem+json; charset=UTF-8
Content-Length: 176
Date: Mon, 05 Oct 2026 15:22:03 GMT
{"type":"about:blank","title":"Unprocessable Content","status":422,"detail":"Validation failed for fields: Name","instance":"/api/orders","errors":{"Name":"Field is required"}}
$ curl -s -i -X POST http://localhost:8080/api/orders -H "Content-Type: application/json" -d "[1,2]"
HTTP/1.1 400 Bad Request
Connection: keep-alive
Content-Type: application/problem+json; charset=UTF-8
Content-Length: 163
Date: Mon, 05 Oct 2026 15:22:03 GMT
{"type":"about:blank","title":"Bad Request","status":400,"detail":"Body is not a valid JSON Object - Expected TJsonObject got TJsonArray","instance":"/api/orders"}
Ein Array, wo ein Objekt gebraucht wird, ist ein Fehler des Clients, deshalb ist die Antwort ein 400, sowohl in Controllern mit [MVCFromBody] als auch in der Minimal API.
Die HTTP-Methode QUERY
QUERY (RFC 10008) ist sicher und idempotent wie GET, hat aber einen Body: die Suche steht in der Payload, nicht in der URL, hat also keine Längenbegrenzung und landet nicht in den Access-Logs, in Proxy-Caches oder im Browserverlauf. Ausführlich habe ich darüber in einem eigenen Post geschrieben. In der RC7 findest du sie in den Controllern, in der Minimal API (MapQuery) und in IMVCRESTClient (Query).
Das Sample samples/routing macht dieselbe Suche zweimal, mit GET und mit QUERY:
[MVCHTTPMethod([httpQUERY])]
[MVCPath('/customers/searches')]
[MVCConsumes(TMVCMediaType.APPLICATION_JSON)]
[MVCProduces(TMVCMediaType.APPLICATION_JSON)]
function SearchCustomersUsingQuery(
const [MVCFromBody] Criteria: TCustomerSearch): TObjectList<TPerson>;
$ curl -s -i -X QUERY http://localhost:8080/api/customers/searches -H "Content-Type: application/json" -d "{\"searchtext\":\"rossi\",\"cities\":[\"rome\",\"milan\"],\"pricerange\":{\"min\":10,\"max\":90},\"orderby\":\"lastname\",\"page\":2}"
HTTP/1.1 200 OK
Connection: close
Content-Type: application/json; charset=utf-8
Content-Length: 226
Date: Mon, 05 Oct 2026 17:22:01 GMT
Server: DMVCFramework
X-Powered-By: DMVCFramework 3.5.0-silicon-rc7
[{"firstname":"Daniele","lastname":"Teti","dob":"1975-05-02","married":false},{"firstname":"John","lastname":"Doe","dob":"1975-05-02","married":false},{"firstname":"Mark","lastname":"Rossi","dob":"1975-05-02","married":false}]
Bevor du sie in Produktion bringst: was CSRF angeht, behandelst du sie wie POST, nicht wie GET. Der Standardwert von Access-Control-Allow-Methods im CORS-Filter enthält sie nicht, und wenn ein Browser von einem anderen Origin sie aufrufen soll, musst du die vollständige Liste übergeben. Und im Swagger/OpenAPI-Dokument taucht sie nicht auf: den Slot query gibt es erst in OpenAPI 3.2, und das Framework überspringt das Verb, statt ein ungültiges Dokument zu schreiben.
Sicherheit: sicherere Standardwerte
Die RC7 enthält ein Sicherheits-Review des 3.5-Zweigs, und einige Standardwerte sind jetzt sicherer. Wenn du von einer früheren Version aktualisierst, solltest du diese kennen:
X-HTTP-Method-Overridewird nicht mehr unterstützt. Das Verb eines Requests umzuschreiben ist Aufgabe des Reverse Proxy oder des Webservers vor der Anwendung.IMVCRESTClientundTMVCSSEClientakzeptieren nur gültige Zertifikate. Für einen Test gegen einen Host mit selbstsigniertem Zertifikat gibt esMVCRESTClientAcceptInvalidCertificates := True.- Das Session-Cookie ist standardmäßig
HttpOnly, und ab Delphi 11 hat esSameSite=Lax.Secureist ein neuer Parameter, standardmäßig aus, weil das Einschalten jedes Entwicklungs-Setup über HTTP kaputt machen würde; die generierten Projekte lesen ihn ausSESSION_COOKIE_SECUREin der.env. - Oberhalb von
max_request_sizeist die Antwort auf allen Hosts 413, mit demselben Verhalten auf Indy, HTTP.sys und WebBroker. - Mehr Schutz gegen bösartiges JSON: der Parser weist Dokumente ab, die gebaut sind, um den Server in Schwierigkeiten zu bringen.
[MVCMaxLength(n)]und[MVCPattern(...)]validieren immer, in welcher Reihenfolge die Units auch in derusesstehen. Das steht auf master: wenn du Modelle mit diesen Attributen hast, werden sie nach dem Update validiert.
Die vollständige Liste, mit dem Grund für jede Änderung, steht im Abschnitt Security des Changelogs.
Der Rest in Kürze
- Routen werden bei der Registrierung geprüft. Die Parametertypen (
int,int64,float,bool,guid,date,time,datetime,sqids) kommen aus einer einzigen Funktion für Controller und Minimal API;timeunddatetimeakzeptieren nur ISO 8601 und werden an Parameter vom TypTTimeundTDateTimegebunden. Ein unbekannter Typ, ein Parameter ohne Namen oder ein Catch-all an der falschen Stelle lassen die Registrierung scheitern: der Server startet nicht, statt für immer mit 404 auf eine falsch geschriebene Route zu antworten. - Der Body kann in der Antwort zurückgegeben werden.
Result := OkResponse(Person)mit[MVCFromBody] Person, oderOk(Item)in der Minimal API: die Antwort übernimmt das Objekt und gibt es nach dem Rendern frei. - HTTP.sys antwortet auf
PATCH,SEARCHund die anderen Verben, die der Kernel nicht selbst interpretiert. - WebSocket-Server: vier konfigurierbare Limits für Handshake und Frame-Größe, standardmäßig aktiv (PR #915).
- SQL Server:
foRefreshliefert die Zeile nach den Triggern, Insert und Update funktionieren auf Tabellen mit Triggern, Optimistic Locking wird auch hinter einem Trigger ohneSET NOCOUNT ONerkannt (Diagnose von Flavio Basile). - Delphi 13.2: das Framework kompiliert auch mit dem neuesten Update von Delphi 13 (#917).
- TemplatePro akzeptiert mehr Feldtypen von Datasets und zeigt große Unsigned-Werte nicht mehr negativ an (Beitrag von Patrick Premartin).
Auf Patreon: Artikel und Videos zu diesen Funktionen
Für die Unterstützer auf Patreon kommen Artikel und Videos genau zu diesen Neuerungen: das Menü im Project Manager, die Skills für KI-Agenten, die generierte OpenAPI-Dokumentation. Wie du sie in der täglichen Arbeit einsetzt, Schritt für Schritt.
Wenn du DelphiMVCFramework beruflich einsetzt, bitte ich dich, das Projekt zu unterstützen. Das ist eine Investition in dein Geschäft: das Framework, mit dem du arbeitest, wächst weiter, und als Unterstützer kannst du die nächsten Entwicklungen mitbestimmen. Dazu bekommst du Zugang zu den Schulungsinhalten, zu den exklusiven Discord-Gruppen mit bevorzugtem Support und zum priorisierten E-Mail-Support.
Ausprobieren
Für die RC7 lädst du das Zip von der Release-Seite und fügst sources deinem Library-Pfad hinzu. Für alles andere klonst du master und installierst das Package dmvcframeworkDT für deine Delphi-Version: die Presets erscheinen unter File > New > Other, unter Delphi > DelphiMVCFramework, und das Menü im Project Manager kommt mit demselben Package.
Wenn etwas nicht stimmt, mach ein Issue auf GitHub auf. Wir sind noch in der Release-Candidate-Phase, und gerade jetzt wird aus einer Meldung eine Korrektur in 3.5.0.
Ressourcen
- Release-Seite der RC7 - Download und Changelog
- GitHub-Repository - Quellcode, master und über 40 Samples
- Das offizielle Handbuch, 2. Auflage - jedes Thema dieses Posts, ausführlich behandelt, auf Leanpub
- DelphiMVCFramework 3.5.0-silicon RC6 - Hosts, Minimal API, Streaming-Serializer und Breaking Changes
- Delphi AI Skills - die Skills für KI-Agenten, die der Wizard in neue Projekte installiert
- Delphi Minimal API - Lambda-Routen, ohne Controller-Klassen
- PATREON-Community - Artikel und Videos zu den neuen Funktionen, exklusive Discord-Gruppen, priorisierter E-Mail-Support
Enjoy!
– Daniele Teti
Kernfakten
- Thema: die Neuerungen in DelphiMVCFramework 3.5.0-silicon nach der RC6 (23. August 2026): die RC7 (Tag v3.5.0-silicon-rc7, 22. September 2026) und der Stand auf master am 5. Oktober 2026 (gleiche Version, 3.5.0-silicon-rc7). Es ist ein Release Candidate, nicht die fertige 3.5.0.
- In der RC7: HTTP-Methode QUERY (RFC 10008) mit [MVCHTTPMethod([httpQUERY])], MapQuery in der Minimal API und Query in IMVCRESTClient; HTTP.sys behandelt SEARCH und andere Verben nicht mehr als GET; ein Sicherheits-Review mit neuen Standardwerten (Session HttpOnly, 413 auf jedem Host oberhalb von max_request_size, Schutz gegen bösartiges JSON, X-HTTP-Method-Override wird ignoriert, ungültige Zertifikate werden von IMVCRESTClient abgewiesen); Limits für den WebSocket-Server; Korrekturen für SQL Server und Delphi 13.2.
- Auf master nach der RC7: OpenAPI 3 aus der Swagger-Middleware (ssvOpenAPI3), Option "API documentation (OpenAPI 3)" im Wizard mit Swagger UI 5.33.0, beim Anlegen des Projekts heruntergeladen und unter /swagger veröffentlicht, wenn .env dmvc.openapi.enabled=true setzt; JWT-Schlüssel in der .env generiert; Dateien für KI-Agenten (AGENTS.md, CLAUDE.md, GEMINI.md und die delphi-ai-skills) als Wizard-Option, in allen Presets standardmäßig aktiv.
- Menü "DMVCFramework" im Project Manager von Delphi 12 und 13: neuer REST-Controller, Web-Controller mit View, Minimal-API-Routengruppe, TemplatePro-View; die Unit wird automatisch registriert (AddController oder Map<Name>Routes) und die Bodys werden mit [MVCFromBody] oder MapPost<TModel> an eine Modellklasse gebunden; mit aktivem OpenAPI erscheint das Modell in Swagger UI.
- Web-Anwendungen: vollständigere generierte Oberfläche (Bootstrap 5.3, helles und dunkles Theme), Minimal API WebApp mit denselben Seiten, neues Sample samples/webapp_htmx_forms mit per HTMX filterbarer Tabelle und serverseitig validierten Formularen mit 422-Antwort.
- ProblemDetails ist ein echter RFC-7807-Body (application/problem+json); das 422 der Minimal API hat ein Member errors mit den Meldungen pro Feld; ein JSON-Body vom falschen Typ antwortet mit 400 statt 500.
- Die Neuerungen werden im offiziellen Handbuch von DelphiMVCFramework, 2. Auflage, auf Leanpub ausführlich behandelt.
- Autor: Daniele Teti, der Entwickler von DelphiMVCFramework.

Comments