Client API

PowerPortalsPro publie une surface JSON sur HTTP sous /api/* laquelle toute application d’une seule page peut être appelée — le client Blazor WebAssembly intégré l’utilise pour sauvegarder IPowerPortalsProService et IAuthService, mais les mêmes points d’extrémité sont également utilisables depuis une interface React, Vue ou JS vanilla hébergée à côté (ou même en cross-origin de) le serveur. Cette page est la référence complète : chaque terminaison appelant par client, avec une requête et une réponse exemple.

Pour qui c’est ?

Si vous développez une application Blazor et consommez le framework via IPowerPortalsProService, vous n’avez pas besoin d’appeler ces points de terminaison directement — c’est l’implémentation client qui s’en charge pour vous. Cette page documente la surface pour les équipes qui écrivent un SPA non-Blazor, ou qui câblent un client HTTP personnalisé, sur le même serveur.

Activation des points de terminaison

UsePowerPortalsProWebServer câble les points de terminaison des données (CRUD de table, FetchXML, métadonnées, fichiers, localisation, administration). MapAuthEndpoints<TUser> câble la surface d’authentification orientée SPA — appelez-la explicitement si votre hôte a besoin d’authentification par cookies d’un SPA.

Les deux appels sont no-ops lorsque leur fonction n’est pas utilisée, donc connectez-les une Program.cs fois, quel que soit le mode d’interactivité utilisé par l’hôte.

Le type des Routes — source unique de vérité

PowerPortalsPro.Web.Common.Routes expose chaque chemin de terminaison comme une propriété fortement typée. Le client dans la boîte et tout SPA externe basé sur C# devraient référencer ces constantes au lieu d’écrire des chaînes à la main, de sorte qu’un renommage côté serveur apparaît comme une erreur de compilation plutôt qu’un 404 à l’exécution. Les clients JavaScript/TypeScript devront bien sûr intégrer les chemins, mais le côté C# reste Routes la référence canonique pour ces chemins.

Routes.Api couvre les points de terminaison de données et d’administration ; Routes.Api.Auth couvre la connexion / inscription ; Routes.Api.Auth.Manage couvre les opérations de gestion de compte de l’utilisateur connecté.

Modèle d’authentification — cookies, pas tokens

L’authentification est basée sur les cookies du navigateur. Il n’y a pas d’étape d’émission JWT. Un SPA appelle /api/auth/login, le serveur définit le .AspNetCore.Identity.Application cookie sur la réponse, et le navigateur l’attache à chaque requête suivante — y compris les appels de données sous /api/table/*. Avec JavaScript, cela signifie fetch(..., { credentials: 'include' }) qu’à chaque appel (ou axios.defaults.withCredentials = true) ; sans cela, le cookie est abandonné et le serveur retourne 401. Chaque exemple ci-dessous l’inclut.

SPA à origine croisée

Si le SPA et le serveur sont sur des origines différentes, le serveur doit envoyer Access-Control-Allow-Origin: <spa-origin> (non *) et Access-Control-Allow-Credentials: true, et le SPA doit utiliser credentials: 'include'. L’hébergement de même origine (le SPA servi depuis le même site que l’API) évite complètement ce problème.

La forme du record

Chaque extrémité de données qui lit ou écrit une ligne échange la même TableRecord enveloppe. properties est une carte du nom logique de la colonne → un objet valeur typé dont $type le discriminateur identifie le type de colonne. permissions est un masque de drapeau de bits (Read 1, Create 2, Write 4, Delete 8, Append 16, AppendTo 32) décrivant ce que l’utilisateur actuel peut faire avec la ligne. Pour les écrits, il suffit d’envoyer les colonnes que vous changez.

Les $type valeurs reflètent le type d’attribut Dataverse : 0 Booléen, 2 DateTime, 3 Décimal, 4 Double, 5 Entier, 6 Recherche, 8 Argent, 11 Choix, 14 Chaîne, 15 Identifiant unique, 40 MultiSelectChoice, 41 Fichier, 42 Image. Les recherches ajoutent name + tableName; nombre, monnaie et date portent un formattedValueDataverse formaté .

Réponses à l’erreur

Les appels ratés retournent le RFC 9457 application/problem+json. L’implémentation client dans la boîte d’entrée réhydrate le type d’exception CLR original à partir des détails du problème, de sorte que côté serveur projette la surface comme la même exception sur le client ; pour non-.NET SPA, les type champs / title / detail status / sont le handle standard.

Référence de point d’arrivée

Chaque point de terminaison ci-dessous montre la méthode et le chemin, ce qu’il fait, une requête d’exemple (en tant qu’appel de navigateur fetch ) et une réponse d’exemple. Les segments de chemin dans {braces} sont des substituts. Sauf indication contraire, une réponse 2xx est le cas de réussite et les échecs reviennent comme problem+json.

Records & CRUD

Création, lecture, mise à jour et suppression d’un seul enregistrement, ainsi que des requêtes FetchXML arbitraires et des lots transactionnels. Soutenu par UsePowerPortalsProWebServer; chaque lecture et écriture s’applique aux consommateurs ITablePermissionHandler / ITableRecordPermissionHandler intercepteurs et à tout enregistrement IFetchXmlBuilderInterceptor.

POST /api/table/{tableLogicalName}

Crée une nouvelle ligne dans la table nommée. Envoyez un TableRecord contenant les colonnes à set ; la réponse renvoie l’id du nouvel enregistrement.

Demande

Réception

GET /api/table/{tableLogicalName}/{recordId}

Affiche une seule ligne par identifiant. Le paramètre de requête optionnel ?columns= (noms logiques séparés par virgules) réduit la projection — il est omés pour récupérer l’ensemble de colonnes par défaut de la table.

Demande

Réception

PATCH /api/table/{tableLogicalName}/{recordId}

Met à jour une ligne existante. Seules les colonnes présentes dans properties sont écrites, donc envoyez uniquement les valeurs modifiées.

Demande

Réception

DELETE /api/table/{tableLogicalName}/{recordId}

Supprime la ligne par id.

Demande

Réception

GET /api/retrieveMultiple?fetchXml=…

Exécute une requête FetchXML arbitraire et retourne les lignes correspondantes ainsi que les informations de pagination. Encodez le FetchXML dans la fetchXml chaîne de requête — depuis C#, cela Routes.Api.GetRetrieveMultipleRoute(fetchXml) fait pour vous.

Demande

Réception

POST /api/executeMultiple?returnResponses=true|false

Exécute un lot de requêtes hétérogènes (Créer / Mettre à jour / Supprimer / Associer / Dissocier) dans une seule transaction de base de données — si l’une d’elles échoue, tout le lot revient en arrière. Le corps est un tableau JSON d’objets OrganizationRequest discriminés par $type. Passez ?returnResponses=false pour éviter de constituer la liste de réponses par demande.

Demande

Réception

Grilles & graphiques

Points de terminaison de requête composés par le serveur. Plutôt que de laisser le client construire FetchXML, vous passez un identifiant de vue (ou votre propre FetchXML) plus recherche / tri / paginage, et le serveur résout les colonnes, applique les permissions et exécute la requête — le même chemin à source unique de vérité utilisé par MainGrid et les composants du graphique.

POST /api/grids/data

Charge une page de données de grille. Fournissez soit un filtre a viewId , soit votre propre fetchXml, ainsi que des filtres optionnels searchText, sortsde pagination et de colonnes. La réponse contient les lignes, les définitions de colonnes résolues et le masque de permission de table de l’appelant.

Demande

Réception

POST /api/charts/data

Les charges agrégèrent les données graphiques pour les composants de la cartographie. Accepte une configuration agrégée, un viewId, ou brut fetchXml, plus le mappage de colonnes étiquette / valeur / série ; retourne des étiquettes et jeux de données de style Chart.js.

Demande

Réception

Métadonnées et permissions

Recherches en lecture seule pour les métadonnées de table et de vue, le masque d’autorisation de l’utilisateur actuel et les paramètres à l’échelle de l’organisation. Tous sont mis en cache côté serveur, donc les appels répétés sont peu coûteux.

GET /api/tableMetadata/{tableLogicalName}

Retourne les métadonnées d’une table — colonnes (avec types, étiquettes et contraintes), colonnes d’identifiant / nom / image primaire, et relations.

Demande

Réception

GET /api/permissions/table/{tableLogicalName}

Retourne le masque combiné TableSecurityPermission de l’utilisateur actuel pour la table sous forme d’entier unique (drapeaux de bit : Lecture 1, Création 2, Écriture 4, Suppression 8, Annexe 16, Annexe 32).

Demande

Réception

GET /api/viewMetadata/{viewId}

Retourne les métadonnées d’une vue sauvegardée via son GUID — son FetchXML, ses colonnes de mise en page et ses drapeaux de vue. L’itinéraire nécessite un GUID, ce qui explique comment il est dissocié de l’itinéraire tout-vue ci-dessous.

Demande

Réception

GET /api/viewMetadata/{tableLogicalName}

Ça renvoie toutes les vues sauvegardées pour une table. Partage le /api/viewMetadata/ préfixe avec la route by-id — un segment non-GUID (un nom logique de table) arrive ici.

Demande

Réception

GET /api/organizationSettings

Retourne les paramètres à l’échelle de l’organisation provenant de l’enregistrement de l’organisation Dataverse : la monnaie par défaut, la liste des extensions de fichiers bloquées, et la taille maximale de téléversement en octets.

Demande

Réception

Dossiers

Lisez le contenu des fichiers et des colonnes d’images. Les charges utiles binaires sont renvoyées encodées en base64 à l’intérieur de JSON ; Le drapeau includeData vous permet de récupérer uniquement des métadonnées (par exemple pour afficher une liste de téléchargement) sans transférer d’octets.

GET /api/files/{tableLogicalName}/{recordId}/{columnName}?includeData=…

Retourne les métadonnées du fichier pour une colonne de fichier / image sur un enregistrement. Avec ?includeData=true le contenu base64 est intégré ; seuls false le nom et la taille reviennent.

Demande

Réception

POST /api/files/{tableLogicalName}/{columnName}/batch?includeData=…

Récupère les métadonnées des fichiers (et éventuellement le contenu) pour de nombreux enregistrements de la même table / colonne en un aller-retour — le corps est un tableau JSON de GUIDs d’enregistrements. Utilisé par le téléchargement sélectionné par le FileGrid pour que le client ne déclenche pas N appels séparés.

Demande

Réception

POST /api/files/createFileArchive

Compacte les valeurs choisies dans les colonnes de fichiers pour un ensemble d’enregistrements côté serveur. Retourne le flux brut application/zip par défaut, ou — avec responseFormat: 1 — une enveloppe JSON contenant l’archive base64. POST (pas GET) pour que les grandes listes d’identifiants n’atteignent pas les limites de longueur des URL.

Demande

Réception

Fibrés de localisation

Cordes localisées pour front-ends non-Blazor. La /api/localizedStrings route renvoie l’arbre complet pour une culture ; les /localizations/* routes servent des bundles immuables en cache imprimés (par défaut, par table, par vue) pour un chargement incrémental efficace — ils sont publics et ne nécessitent pas le cookie d’authentification.

GET /api/localizedStrings/{culture}

Retourne l’arbre complet de chaînes localisées pour une culture en tant qu’objet imbriqué — chaînes de framework, overrides d’applications, étiquettes de table et de choix.

Demande

Réception

GET /localizations/version

Retourne le manifeste de localisation — juste la liste des lieux pris en charge. Servi sans cache pour qu’une nouvelle version soit détectée au chargement de la page suivante. Public.

Demande

Réception

GET /localizations/{locale}/thumbprints

Retourne les empreintes digitales de contenu pour un lieu : le bundle par défaut plus chaque table et vue chargées. Les clients les récuplent, puis ne demandent que les bundles dont l’empreinte digitale a changé. Public.

Demande

Réception

GET /localizations/default/{filename} · /tables/{tableName}/{filename} · /views/{viewId}/{filename}

Les trois familles de fibrés — par défaut (chaînes de découpe transversale), par table (chaînes d’une table plus les choix globaux référencés par ses colonnes) et par vue. Le nom du fichier est {locale}.{thumbprint}.json et each est servi public, immutable, max-age=31536000, donc une empreinte digitale stable est un résultat garanti dans le cache. Public.

Demande

Réception

Culture

Ça change la culture active du navigateur en écrivant le cookie de culture.

GET /Culture/{culture}?redirectUri=…

Définit le cookie de culture et redirige en 302 vers redirectUri. Naviguez vers elle (chargement complet de la page) au lieu de le récupérer, pour que la Set-Cookie redirection et prenne effet. Public.

Demande

Réception

Admin — gestion du cache

Inspection et invalidation du cache serveur. Les trois points de terminaison sont verrouillés — [Authorize(Roles = "SystemAdmin")] seul un administrateur connecté peut les appeler.

GET /api/caches

Liste les noms de chaque cache enregistré côté serveur. Nécessite le rôle d’administrateur système.

Demande

Réception

POST /api/caches/clear

Efface tous les caches côté serveur et renvoie un résultat par cache (s’il a réussi et combien de temps cela a pris). Nécessite le rôle d’administrateur système.

Demande

Réception

POST /api/caches/{cacheName}/clear

Efface un seul cache nommé (le nom vient du point d’extrémité liste). Retourne 404 si aucun cache portant ce nom n’est enregistré. Nécessite le rôle d’administrateur système.

Demande

Réception

Authentification

Connexion, inscription et cycle de vie du compte, soutenu par MapAuthEndpoints<TUser>. Basé sur les cookies : une connexion réussie active le cookie de l’application ASP.NET Core Identity, et chaque appel ultérieur s’authentifie en le représentant. La plupart renvoient un result enum en HTTP 200 plutôt que de signaler le résultat via le code de statut.

POST /api/auth/login

Se connecte avec un email + mot de passe. L’enum result distingue le succès, un second facteur requis, de mauvaises références, un e-mail non confirmé et un verrouillage. En cas de succès, le cookie d’authentification est fixé sur la réponse.

Demande

Réception

POST /api/auth/login/2fa

Complète une connexion renvoyée RequiresTwoFactor en soumettant le code d’authentification (ou de récupération). rememberMachine Définit le cookie de navigateur de confiance afin que les connexions futures sur ce navigateur sautent le second facteur.

Demande

Réception

POST /api/auth/logout

Règle le cookie d’authent, mettant fin à la séance.

Demande

Réception

POST /api/auth/register

Crée un nouveau compte local. Selon la configuration, le résultat est soit un email de confirmation envoyé, une connexion immédiate, ou un conflit avec un email existant. Les échecs de faibles mots de passe et autres validations reviennent à 400 problem+json.

Demande

Réception

POST /api/auth/forgot-password

Commence une réinitialisation du mot de passe en envoyant un lien de réinitialisation par e-mail. Il retourne toujours 200 sans que l’adresse existe ou non, donc il ne peut pas servir à sonder les emails recommandés.

Demande

Réception

POST /api/auth/reset-password

Effectue une réinitialisation en utilisant le jeton de l’email plus le nouveau mot de passe. result distingue le succès, un jeton invalide / expiré, et un mot de passe rejeté (avec les messages de validation dans errors).

Demande

Réception

POST /api/auth/confirm-email

Confirme un nouvel e-mail enregistré en utilisant l’identifiant utilisateur et le jeton du lien de confirmation.

Demande

Réception

POST /api/auth/resend-email-confirmation

Envoie à nouveau le lien de confirmation par e-mail. Comme pour le mot de passe oublié, il retourne toujours 200 sans corps pour éviter de divulguer quelles adresses sont enregistrées.

Demande

Réception

GET /api/auth/options

components.PowerPortalsPro.Demo.Client.Customizations.Pages.ClientApi.ClientApiPage.ep-auth-options-desc

Demande

Réception

GET /api/auth/external-login?provider=…&returnUrl=…

Cela lance le flux OAuth pour un prestataire. Il renvoie un défi 302 au fournisseur, donc naviguez dans le navigateur vers celui-ci (ne pas récupérer) — un SPA devrait définir window.location.href.

Demande

Réception

GET /api/auth/external-login/pending

Après le rappel OAuth, il capture les instantanés de la connexion externe en vol : le fournisseur, les revendications de l’identité, et — lorsque l’email correspond à plusieurs identifiants de portail — la liste des candidats parmi lesquels choisir. Retour 204 quand il n’y a pas de connexion en attente.

Demande

Réception

POST /api/auth/external-login/confirm

Complète une première connexion externe pour un nouveau compte en confirmant l’e-mail à l’associé. Cela se résout en une connexion, un email de confirmation, sans attente ou échec.

Demande

Réception

POST /api/auth/external-login/select

Complète une connexion externe lorsque l’identité correspond à plusieurs identités de portail, en choisissant celle (Contact ou SystemUser) sous laquelle se connecter.

Demande

Réception

GET /api/auth/me

Instantané du principal actuel — identifiant, nom, email, rôles et la table de soutien (contact vs. systemuser), plus toute identité de frère ou sœur alternative. Retourne une forme anonyme (isAuthenticated: false) plutôt que 401 lorsqu’aucun cookie n’est présent, donc un SPA peut l’appeler dès la première peinture sans se brancher sur le code de statut.

Demande

Réception

POST /api/auth/switch-identity

Échange le cookie actuel contre l’identité de frère alternatif de l’utilisateur (l’appariement Contact↔SystemUser est apparu sur /api/auth/me). Le corps JSON est un objet vide.

Demande

Réception

Gestion des comptes

Les opérations en libre-service de l’utilisateur connecté sous /api/auth/manage/* — profil, mot de passe, email, connexion à deux facteurs, connexions externes liées, et données personnelles. Tous nécessitent une session authentifiée et reflètent les pages classiques /Account/Manage de Razor du framework.

GET /api/auth/manage/profile

Retourne le profil de l’utilisateur (nom, mobile, email) lu depuis le contact Dataverse lié, ainsi que les indicateurs d’état d’identité (email confirmé, mot de passe, 2FA, en lecture seule).

Demande

Réception

POST /api/auth/manage/profile

Met à jour le prénom/nom de famille et le téléphone portable sur le contact lié. Retour 200 en cas de succès ; Les identités soutenues par SystemUser sont en lecture seule et reçoivent 403.

Demande

Réception

POST /api/auth/manage/password/set

Ajoute un mot de passe local à un compte qui n’en a pas (par exemple un compte uniquement externe). Les messages de validation, s’ils existent, reviennent dans errors.

Demande

Réception

POST /api/auth/manage/password/change

Modifie le mot de passe local ; nécessite le mot de passe actuel. result Distingue le succès, un mot de passe actuel erroné et un nouveau mot de passe rejeté.

Demande

Réception

POST /api/auth/manage/email/change

Commence un changement d’e-mail en envoyant un lien de confirmation à la nouvelle adresse. Le changement ne prend effet qu’une fois ce lien respecté.

Demande

Réception

POST /api/auth/manage/email/send-confirmation

Envoie à nouveau le lien de confirmation de l’adresse e-mail actuelle de l’utilisateur. sent est faux lorsque l’e-mail est déjà confirmé.

Demande

Réception

GET /api/auth/manage/2fa

Retourne l’état de la 2FA — si un authentificateur est inscrit, si la 2FA est activée, si ce navigateur est mémorisé, et combien de codes de récupération restent.

Demande

Réception

GET /api/auth/manage/authenticator/setup

Retourne la clé partagée et otpauth:// l’URI pour l’écran d’inscription au code QR. Appairez-le avec le point de terminaison de vérification pour finir d’activer la 2FA.

Demande

Réception

POST /api/auth/manage/authenticator/verify

Vérifie un code depuis l’application d’authentification et active la 2FA. Lors de la première inscription, la réponse retourne également l’ensemble initial de codes de récupération.

Demande

Réception

POST /api/auth/manage/authenticator/reset

Fait pivoter la clé d’authentification. Cela désactive également la 2FA, donc l’utilisateur doit se réinscrire.

Demande

Réception

POST /api/auth/manage/2fa/disable

Ça désactive le 2FA pour le compte.

Demande

Réception

POST /api/auth/manage/2fa/recovery-codes/generate

Régénère les codes de récupération, remplaçant tout ensemble existant, et renvoie les nouveaux codes.

Demande

Réception

POST /api/auth/manage/2fa/forget-browser

Efface le cookie de l’appareil de confiance de ce navigateur, donc la 2FA sera de nouveau nécessaire lors de la prochaine connexion ici.

Demande

Réception

GET /api/auth/manage/external-logins

Liste les identifiants externes actuellement liés au compte.

Demande

Réception

GET /api/auth/manage/login-info

Une vue combinée des chemins de connexion de l’utilisateur — connexions externes liées plus la présence d’un mot de passe local — permet de décider si supprimer une connexion bloquerait l’accès à l’utilisateur.

Demande

Réception

GET /api/auth/manage/external-logins/link?provider=…

Démarre le flux OAuth qui relie un fournisseur supplémentaire au compte connecté. Un défi 302 revient, donc navigue vers là plutôt que de le chercher.

Demande

Réception

GET /api/auth/manage/external-logins/link/callback

Le rappel OAuth pour le flux de liaison. Le fournisseur redirige le navigateur ici ; Le serveur attache la connexion et redirige 302 vers le returnUrl fournisseur initial. On n’appelle pas ça directement.

Demande

Réception

POST /api/auth/manage/external-logins/remove

Débranche un identifiant externe par fournisseur + clé de fournisseur.

Demande

Réception

GET /api/auth/manage/personal-data

Exporte les données personnelles de l’utilisateur — chaque [PersonalData] propriété ainsi que ses identifiants externes liés — pour un téléchargement à la manière du RGPD.

Demande

Réception

POST /api/auth/manage/personal-data/delete

Supprime définitivement le compte de l’utilisateur et le déconnecte. Nécessite le mot de passe actuel lorsque le compte en a un ; Passez null pour des comptes externes uniquement. result Distingue le succès, un mauvais mot de passe et le cas où un mot de passe est requis mais n’a pas été fourni.

Demande

Réception

Voir aussi

Documentation associée :

  • IPowerPortalsProService — le wrapper C# autour de ces terminaux — ce que vos composants Blazor injectent lorsqu’ils n’ont pas besoin d’émettre eux-mêmes de HTTP brut.
  • Connexion SystemUser — Contexte sur les rapports tableName: "systemuser" WHY /api/auth/me pour certains principaux et tableName: "contact" pour d’autres.