Sist endret: 29. okt. 2026
Preview: Dette er dokumentasjonen for Altinn Studio v9, som er en forhåndsversjon. Gjeldende versjon er v8. For å se dokumentasjonen for gjeldende versjon, velg v8 i versjonsvelgeren i menyen til venstre.

Definere egne prosess-hooks

Slik kjører du egen kode når en oppgave starter, avsluttes eller avbrytes, og etter at prosessen er avsluttet.

Med prosess-hooks kan appen kjøre egen kode på faste punkter i prosessen. Det finnes fire:

HookKjørerGjelder
IOnTaskStartingHandlernår en oppgave starteroppgavene du velger
IOnTaskEndingHandlernår en oppgave avsluttes, før prosessen går videreoppgavene du velger
IOnTaskAbandoningHandlernår en oppgave avbrytes, for eksempel når brukeren avviseroppgavene du velger
IOnProcessEndedHandleretter at prosessen er avsluttet og lagrethele instansen

Alle grensesnittene ligger i Altinn.App.Core.Features.Process. Andre steder appen kan kjøre egen kode, for eksempel i gateways, systemoppgaver og handlinger, finner du i Grensesnitt for egen kode.

Slik fungerer hookene

Du lager en klasse som implementerer grensesnittet, og registrerer den som en transient tjeneste i Program.cs. Hver hook kjører som et eget steg i arbeidsflytmotoren, og metoden Execute får et kontekstobjekt med:

  • en IInstanceDataMutator som du leser og endrer instansdata med
  • en CancellationToken
  • ID-en til oppgaven, for de tre oppgave-hookene

Endringer du gjør gjennom context.InstanceDataMutator, blir lagret når hooken er ferdig uten feil. Skriv alle endringer gjennom den. Mens arbeidsflyten behandler instansen, avviser Storage endringer som kommer direkte gjennom IDataClient eller IInstanceClient.

Hooken kjører i arbeidsflytmotoren, ikke i forespørselen fra brukeren. IAuthenticationContext.Current er derfor appen selv, ikke brukeren som sendte inn, og HttpContext gir deg ikke brukerens språk eller pålogging.

Execute returnerer et HandlerResult:

  • HandlerResult.Success() når alt gikk bra.
  • HandlerResult.FailedRetryable("melding") når feilen er forbigående, for eksempel at en ekstern tjeneste ikke svarer. Plattformen prøver steget på nytt.
  • HandlerResult.FailedPermanent("melding") når feilen ikke går over av seg selv. Plattformen prøver ikke på nytt.

Kaster Execute et unntak som koden din ikke håndterer, regnes det som FailedRetryable. Hvor ofte og hvor lenge plattformen prøver på nytt, står i Overstyre tidsavbrudd og gjenforsøksstrategi.

Fordi en hook kan bli kjørt flere ganger, må koden tåle det. Den skal gi samme resultat hver gang, og for eksempel ikke sende den samme e-posten eller opprette de samme dataene to ganger.

Kjøre kode når en oppgave starter

Implementer IOnTaskStartingHandler. ShouldRunForTask bestemmer hvilke oppgaver hooken gjelder for, og Execute inneholder koden.

public class MyTaskStartHandler : IOnTaskStartingHandler
{
    public bool ShouldRunForTask(string taskId) => taskId == "Task_1";

    public async Task<HandlerResult> Execute(OnTaskStartingContext context)
    {
        // Les og endre data gjennom context.InstanceDataMutator

        return HandlerResult.Success();
    }
}
services.AddTransient<IOnTaskStartingHandler, MyTaskStartHandler>();

Du kan registrere flere klasser for samme hook, så lenge de gjelder for ulike oppgaver.

Bare én hook av hver type kan gjelde for samme oppgave. Svarer to registrerte IOnTaskStartingHandler true for samme oppgave i process.bpmn, starter ikke appen. Det samme gjelder IOnTaskEndingHandler og IOnTaskAbandoningHandler.

Se grensesnittet IOnTaskStartingHandler på GitHub

Kjøre kode når en oppgave avsluttes

Implementer IOnTaskEndingHandler. Den følger samme mønster som IOnTaskStartingHandler, med Execute(OnTaskEndingContext context).

services.AddTransient<IOnTaskEndingHandler, MyTaskEndHandler>();

Hooken kjører før dataene i oppgaven blir låst, så det er siste mulighet til å endre dem. Er oppgaven den siste i prosessen, kjører hooken også før prosessen avsluttes. Feiler den, blir ikke prosessen avsluttet. Kode som skal kunne stoppe avslutningen, hører derfor hjemme her.

Se grensesnittet IOnTaskEndingHandler på GitHub

Kjøre kode når en oppgave avbrytes

Implementer IOnTaskAbandoningHandler. Den følger samme mønster, med Execute(OnTaskAbandoningContext context).

services.AddTransient<IOnTaskAbandoningHandler, MyTaskAbandoningHandler>();

Når brukeren avviser en oppgave, kjører denne hooken i stedet for IOnTaskEndingHandler. Skal koden kjøre uansett om oppgaven blir sendt videre eller avvist, trenger du begge hookene.

Se grensesnittet IOnTaskAbandoningHandler på GitHub

Kjøre kode etter at prosessen er avsluttet

Implementer IOnProcessEndedHandler. Hooken kjører én gang for hele instansen, når prosessen har nådd en sluttilstand (endEvent) og dette er lagret. Den kjører uansett hvilken vei prosessen tok til slutten. Bruk den til kode som først skal kjøre når avslutningen er lagret, for eksempel for å varsle et eksternt system.

public class MyProcessEndedHandler : IOnProcessEndedHandler
{
    public async Task<HandlerResult> Execute(OnProcessEndedContext context)
    {
        // Les og endre data gjennom context.InstanceDataMutator

        return HandlerResult.Success();
    }
}
services.AddTransient<IOnProcessEndedHandler, MyProcessEndedHandler>();

Du kan bare registrere én IOnProcessEndedHandler. Med flere starter ikke appen. Hooken har ingen ShouldRunForTask, og konteksten har ingen oppgave-ID. Hvilken sluttilstand prosessen nådde, finner du i context.InstanceDataMutator.Instance.Process.EndEvent.

Hooken kjører før datatyper med autoDeleteOnProcessEnd blir slettet, så den ser alle dataene. Er autoDeleteOnProcessEnd slått på for hele appen, blir instansen slettet etter at hooken er ferdig.

Feiler hooken, er prosessen likevel avsluttet. Instansen blir værende under behandling til arbeidsflyten blir startet på nytt fra arbeidsflytmotoren. Skal en feil kunne stoppe avslutningen, bruk IOnTaskEndingHandler for den siste oppgaven i stedet. Avslutter en avvisning prosessen, kjører IOnTaskAbandoningHandler for oppgaven i stedet.

Se grensesnittet IOnProcessEndedHandler på GitHub

IProcessEnd fra v8 finnes ikke i v9. Flytt koden til IOnProcessEndedHandler, eller til en IOnTaskEndingHandler for den siste oppgaven hvis den skal kjøre før avslutningen er lagret. studioctl app upgrade v9 viser hvilke klasser og registreringer du må flytte.

Overstyre tidsavbrudd og gjenforsøksstrategi

Alle fire hookene kan overstyre standard tidsavbrudd og gjenforsøk for steget sitt med egenskapen StepOptions. Setter du den ikke, gjelder standardverdiene i plattformen. De kan avvike mellom miljøene:

VerdiStandardGrense
MaxExecutionTime for en hook100 sekunder2 timer
Nye forsøk etter FailedRetryable eller et uhåndtert unntakøkende pause fra ett sekund, maks fem minutter mellom forsøkene, i opptil ett døgn—

Eksempelet under gir hooken to minutter per forsøk, og prøver på nytt opptil fem ganger med økende pause:

public class MyTaskStartHandler : IOnTaskStartingHandler
{
    public ProcessStepOptions? StepOptions =>
        new()
        {
            MaxExecutionTime = TimeSpan.FromMinutes(2),
            RetryStrategy = ProcessStepRetryStrategy.Exponential(
                baseInterval: TimeSpan.FromSeconds(5),
                maxRetries: 5,
                maxDelay: TimeSpan.FromMinutes(1)
            ),
        };

    public bool ShouldRunForTask(string taskId) => taskId == "Task_1";

    public async Task<HandlerResult> Execute(OnTaskStartingContext context)
    {
        // Egendefinert logikk her

        return HandlerResult.Success();
    }
}
  • MaxExecutionTime er hvor lenge ett forsøk får bruke før plattformen avbryter det og regner det som feilet.
  • RetryStrategy styrer hvor mange nye forsøk plattformen gjør, og hvor lang pausen mellom dem er. Du kan velge Exponential, Linear eller Constant. ProcessStepRetryStrategy.None() slår av nye forsøk.

Felt du ikke setter, får standardverdien.

Systemoppgaver bruker den samme egenskapen, men har et lengre standard tidsavbrudd. Se Lage en egendefinert systemoppgave.