Un bouton d’opération exécute une opération enregistrée par le serveur — une API personnalisée, une action personnalisée, un message propre à Dataverse, ou un code à vous — et ne l’affiche qu’aux utilisateurs pour lesquels il est enregistré. Le bouton demande une fois au serveur quelles opérations l’utilisateur connecté peut exécuter, et vérifie chaque enregistrement qu’il enverrait par rapport à ce que l’utilisateur pourrait lui faire, afin de ne pas offrir ce que le serveur refuserait. Le serveur juge toujours chaque requête lors de son envoi.
Enregistrer une opération dans le Program.csserveur : AddOperationAccess pour une opération Dataverse, AddOperationHandler pour votre propre code. Dans AddPortalRole, WithOperationAccess et WithOperationHandler en accorder une aux titulaires du rôle. Un enregistrement indique qui peut exécuter l’opération, les paramètres qu’une requête peut porter, les enregistrements auxquels elle doit pointer et les sorties qui reviennent.
// Program.cs (the server)
// Une API personnalisée pour les titulaires du rôle de facturation, sur une facture ils peuvent changer
builder.Services.AddPortalRole("Billing", role => role
.WithOperationAccess("ppp_IssueRefund", o => o
.OnRecord("Target", TableSecurityPermission.Write)
.AcceptingParameters("Amount")
.ReturningOutputs("RefundId")));
// Votre propre code, pour tout utilisateur connecté, sur un devis qu’il peut lire
builder.Services.AddOperationHandler<SendQuoteHandler>("SendQuote", o => o
.ForSignedInUsers()
.OnRecord("Quote", TableSecurityPermission.Read)
.ReturningOutputs("SentTo"));
public sealed class SendQuoteHandler(IQuoteMailer mailer) : IPortalOperationHandler
{
public async Task<IReadOnlyDictionary<string, ColumnValueBase?>?> ExecuteAsync(
PortalOperationContext context, CancellationToken cancellationToken)
{
var quote = context.GetParameter<LookupValue>("Quote")!;
var sentTo = await mailer.SendAsync(quote.Value!.Value, cancellationToken);
return new Dictionary<string, ColumnValueBase?> { ["SentTo"] = new StringValue { Value = sentTo } };
}
}
ForEveryone(), ForSignedInUsers(), ForContactsMatching(fetchXml) et ForWebRoles(...) indiquer qui peut l’exécuter ; l’enregistrement d’un rôle est destiné aux titulaires du rôle. Sous la sécurité native Dataverse, les contacts détiennent des rôles web plutôt que des rôles de portail, et une API personnalisée n’est proposée qu’aux utilisateurs dont les rôles de sécurité accordent son privilège d’exécution.Mettez un OperationButton point où l’opération appartient, en nommant l’opération et le paramètre dans lequel son enregistrement est inclus.
<RecordContext table="invoice" queryParameterName="id">
<OperationButton
operation="ppp_IssueRefund"
recordParameter="Target"
label="Issue refund"
icon={<Money20Regular />}
confirmationMessage="Issue a refund for this invoice?"
getParameters={askForAmount}
onCompleted={({ outputs }) => showRefund(outputs.RefundId)}
/>
</RecordContext><RecordContext TableName="invoice" QueryParameterName="id">
<OperationButton Operation="ppp_IssueRefund"
RecordParameter="Target"
Label="Issue refund"
Icon="@(new Icons.Regular.Size20.Money())"
ConfirmationMessage="Issue a refund for this invoice?"
GetParametersAsync="AskForAmountAsync"
OnCompleted="ShowRefund" />
</RecordContext>WhenNotAllowed (whenNotAllowed) pour la désactiver à la place. La réponse est demandée une fois et conservée tant que l’application est ouverte ; une demande refusée par le serveur la demande à nouveau.RecordParameter: Record, n’importe quel enregistrement par référence, ou alors l’enregistrement du RecordContext bouton s’y installe, une fois qu’il est sauvegardé. L’utilisateur doit pouvoir agir dessus comme l’enregistrement l’exige : l’enregistrement d’un formulaire indique ce que l’utilisateur peut lui faire, et un enregistrement nommé par référence est lu pour celui-ci.Parameters sont envoyés avec chaque requête, et GetParametersAsync (getParameters) en recueille davantage lorsque le bouton est cliqué, par exemple depuis une boîte de dialogue, ; ne rien retourner annule le clic. ConfirmationMessage demande avant que l’opération ne s’exécute, et OnCompleted rend ses sorties.Label ou son contenu, ainsi que son icône, infobulle et apparence comme sur n’importe quel autre bouton.La démo enregistre quelques lignes de son propre code comme une opération pour tout le monde. Tapez un nom et cliquez sur le bouton : le serveur répond, et la page formule la salutation.
Dans la barre d’outils d’une grille, OperationGridButton l’opération est exécutée une fois pour chaque ligne sélectionnée, envoyant la ligne dans RecordParameter, puis rafraîchissant la grille. Elle est activée alors que chaque ligne sélectionnée est une sur laquelle l’utilisateur peut agir, ce que chaque ligne indique elle-même. Les requêtes d’une opération Dataverse sont envoyées en une seule transaction, donc elles s’exécutent toutes ou aucune ne s’exécute ; votre propre code s’exécute sur une ligne à la fois et s’arrête à la première qui échoue.
<MainGrid tableName="invoice">
<GridToolbarItems>
<OperationGridButton
operation="ppp_ApproveInvoice"
recordParameter="Target"
label="Approve"
whenNotAllowed="disable"
/>
</GridToolbarItems>
</MainGrid><MainGrid TableName="invoice">
<ToolbarItems>
<OperationGridButton Operation="ppp_ApproveInvoice"
RecordParameter="Target"
Label="Approve"
WhenNotAllowed="OperationButtonBehavior.Disable" />
</ToolbarItems>
</MainGrid>Sélectionnez quelques comptes et cliquez sur Vérifier : le code de la démo lit chacun et répond à son nom. Approuver n’est accordé qu’à un rôle de portail qu’aucun visiteur n’occupe, donc il apparaît désactivé.
Nom du compte
Nom du compte Tapez le nom de l’entreprise ou de l’entreprise. | Numéro de compte Numéro de compte Tapez un numéro d’identification ou un code pour le compte afin de rechercher et d’identifier rapidement le compte dans les vues système. | Téléphone principal Téléphone principal Tapez le numéro de téléphone principal de ce compte. | Adresse 1 : Ville Adresse 1 : Ville Saisissez la ville de l’adresse principale. | Chiffre d’affaires annuel Chiffre d’affaires annuel Saisissez le revenu annuel du compte, utilisé comme indicateur dans l’analyse de la performance financière. | Personne-ressource principale Personne-ressource principale Choisissez le contact principal du compte pour fournir un accès rapide aux coordonnées. | |
|---|---|---|---|---|---|---|
| Abernathy - MacGyver | KTWSLQHY | (491) 600-8029 | Tampa | $15 959 059,84 | Bradford Kiehn | |
| Abshire - Marks | 4EBO9F42 | (432) 879-3107 | Boston | $14 635 260,82 | Archibald Bailey | |
| Adams - Torphy | K6VNNUCN | (864) 842-2566 | Annapolis | $4 567 299,55 | Merle Vandervort | |
| Altenwerth, D'Amore and Mante | F9MN5BAZ | (125) 048-0015 | Gulfport | $3 839 082,81 | Heidi Reichel | |
| Ankunding and Sons | 92P2G0SF | (603) 147-5429 | Fargo | $32 724 448,89 | Fatima White | |
| Balistreri, Heller and Murphy | 3Y0AF481 | (909) 808-9886 | New Haven | $7 097 756,35 | Angie Kreiger | |
| Balistreri, Steuber and Schultz | FF5RCGXG | (435) 761-0052 | Hattiesburg | $35 943 517,75 | Jake Bogisich | |
| Bartoletti LLC | JBQ0L2O8 | (292) 573-7498 | Santa Fe | $766 813,66 | Cecil Sipes | |
| Bartoletti, Ratke and Beatty | WZIDG7K2 | (267) 075-5978 | Portland | $32 338 459,84 | Tabitha Morissette | |
| Barton, Koepp and Cronin | TGAL5Y8F | (821) 885-8434 | Norman | $43 550 293,98 | Marc Dibbert | |
| Bashirian - Hamill | ZS1XZLDL | (792) 135-0145 | Baltimore | $15 916 182,51 | Alexie Dach | |
| Bashirian - Weber | OC5PYOJC | (492) 789-5504 | Cranston | $23 269 960,31 | Emmet Krajcik | |
| Baumbach and Sons | X8V8TZRX | (670) 937-4364 | Ann Arbor | $4 319 879,33 | Charity Sawayn | |
| Baumbach, Maggio and Turner | V24ZA492 | (509) 251-9848 | Orlando | $25 479 745,81 | Cali McClure | |
| Beahan Inc | B9XXSIJM | (262) 429-4179 | Sioux Falls | $45 854 197,84 | Tressa Graham | |
| Berge and Sons | WO8OIGR6 | (165) 108-8947 | Topeka | $40 560 550,52 | Delphine Jerde | |
| Bergnaum Group | T3KB03RE | (381) 148-7032 | Rapid City | $32 406 150,23 | Dakota Ward | |
| Bergstrom and Sons | G99XNRDY | (182) 902-0206 | Casper | $48 880 601,83 | Grant Funk | |
| Bergstrom, Bins and Flatley | J1TXPJ9I | (409) 160-0657 | Pittsburgh | $21 005 421,54 | Blanche Gulgowski | |
| Blanda - Terry | 4L8RSVL9 | (190) 468-0033 | Vancouver | $33 567 160,56 | Fausto Pagac | |
| Bode LLC | F5IR66HK | (386) 496-6921 | Detroit | $1 800 033,15 | Kane Pollich | |
| Bogisich, Mitchell and Balistreri | PCVDL8PS | (267) 567-6606 | Manchester | $10 336 491,66 | Esperanza Luettgen | |
| Borer - Mohr | LHI1SSVO | (070) 539-8404 | Providence | $36 092 236,14 | Emelia Murray | |
| Botsford - Baumbach | 8JZK18K6 | (389) 188-6100 | Cranston | $318 662,34 | Maria Runte | |
| Botsford, Schroeder and Kassulke | U39NNCOJ | (960) 101-3753 | Sacramento | $19 016 940,28 | Raphael Bergnaum | |
| Boyer - Schaefer | EFJQXML0 | (473) 115-3249 | Fort Wayne | $48 601 111,30 | Moses Metz | |
| Boyle, Zulauf and Lakin | XXRF6GXU | (028) 071-4090 | Helena | $31 856 728,91 | Federico Hamill | |
| Brekke LLC | UCLPTB19 | (795) 385-0349 | Norman | $25 296 518,98 | Noemie Stracke | |
| Brekke, Feeney and Johns | VMGNL1M7 | (203) 861-9656 | Charleston | $13 632 447,58 | Kristin Koch | |
| Brown, Rohan and Mayer | EMOSYGOI | (479) 235-6497 | Fairbanks | $49 780 735,02 | Phoebe Legros | |
| Cassin, Kassulke and Schaefer | 5KSSVNW7 | (852) 978-3789 | Flagstaff | $29 260 487,45 | Dedrick Thiel | |
| Christiansen - Metz | GSZJ1ODJ | (183) 163-4723 | Reno | $25 227 451,85 | Hattie Schuster | |
| Cole, Tillman and Langworth | Y1JNB47Q | (289) 893-2488 | Dover | $13 838 171,56 | Jody Rohan | |
| Connelly, Cassin and Ledner | 69QI6R89 | (507) 196-5103 | Wilmington | $28 880 982,86 | Berneice Stracke | |
| Considine Inc | 1ZGMEMAV | (013) 094-8065 | Anchorage | $6 796 633,66 | Guido Hagenes | |
| Considine, Wilkinson and Spencer | HK18ZLOO | (772) 222-6147 | Jersey City | $8 490 647,93 | Douglas Prosacco | |
| Cormier - Hettinger | JFLKC0CK | (508) 849-8368 | Tucson | $14 771 052,63 | Nola Hand | |
| Cremin - Hodkiewicz | 4D30N08W | (757) 968-3487 | Fort Wayne | $27 239 848,21 | America Harber | |
| Cruickshank - Pollich | P3JT5LVY | (048) 698-7364 | Santa Fe | $32 195 480,36 | Joey Reilly | |
| Cruickshank, Auer and Schoen | TV06VSEA | (516) 585-5831 | Sioux Falls | $3 560 781,82 | Tiana Kiehn | |
| Cummerata Group | AJYD1N4I | (429) 577-7392 | Minneapolis | $20 579 317,84 | Gustave Zboncak | |
| Daniel LLC | ADF0WMN9 | (371) 118-7804 | Madison | $49 497 674,02 | Francisco Smitham | |
| Denesik, Skiles and Beier | 2ZMSATDW | (716) 332-8853 | Louisville | $25 958 417,48 | Dock Aufderhar | |
| Dibbert LLC | 4WT0EDV0 | (343) 448-8435 | Huntington | $24 379 660,89 | Elroy Leuschke | |
| Dickinson Inc | C7SI8E20 | (429) 201-5173 | Dover | $44 819 510,87 | Milton Ledner | |
| Dietrich and Sons | LAEDD52L | (189) 560-2423 | Hartford | $3 522 175,29 | Heath Kunde | |
| Donnelly - Sanford | 8SW26RNC | (738) 522-0182 | Fort Wayne | $37 819 037,93 | Betsy King | |
| Dooley - Nitzsche | NUCMFF7S | (574) 958-0441 | Charleston | $11 318 528,04 | Roman Dietrich | |
| Durgan and Sons | CKOSAHML | (332) 942-8325 | Saint Paul | $5 901 769,33 | Connor Marks | |
| Ebert - Wyman | HJBQWXIR | (753) 557-3136 | Los Angeles | $15 782 605,89 | Zetta Nolan |
Les boutons demandent GET /api/permissions/operations, ce qui répond uniquement pour l’utilisateur connecté : chaque opération qu’il peut exécuter, ou seulement celles que vous nommez, avec ce qu’une demande peut contenir et les enregistrements auxquels elle doit pointer. Votre propre interface utilisateur peut poser la même question via IOperationAccessCache ou IPowerPortalsProService.GetOperationAccessForCurrentUserAsync sur Blazor, ou useOperationAccess ppp.retrieveOperationAccessAsync sur React.