Tjenester
Hvordan benytte enkelte bortgjemte tjenester og klienter i app template bibliotekene.
Personoppslag
Tjenesten for personoppslag kan brukes til å verifisere et personnummer og til å hente informasjon om den identifiserte personen. Brukeren vil måtte oppgi både et personnummer og etternavnet til personen. Tjenesten vil da gjøre et oppslag på personnummeret og sjekke at etternavnet stemmer. Begge verdiene er obligatoriske og etternavnet brukes til å forhindre vasking av personnummer. Hvis brukeren oppgir feil informasjon for mange ganger vil brukeren bli sperret fra å gjøre flere oppslag i en liten periode.
De returnete persondataene kan brukes til å fylle ut andre felter i datamodellen.
Personoppslag eksempel
Tjenesten kan benyttes fra alle “handlers” i logikk klassene i en app. Nedenfor har vi laget et eksempel som gjør oppslag i ProcessDataWrite
metoden i DataProcessor
.
using System;
using System.Threading;
using System.Threading.Tasks;
using Altinn.App.Core.Features;
using Altinn.App.Core.Interface;
using Altinn.App.Models;
using Altinn.Platform.Register.Models;
using Altinn.Platform.Storage.Interface.Models;
using Microsoft.Extensions.Logging;
namespace Altinn.App.AppLogic.DataProcessing;
public class DataProcessor : IDataProcessor
public async Task<bool> ProcessDataWrite(
Instance instance, Guid? dataId, object data)
{
if (data is MessageV1 message)
{
Person person = await _personLookup.GetPerson(
message.Personnummer,
message.Etternavn,
CancellationToken.None);
message.Fornavn = person.FirstName;
return true;
}
return false;
}
For at dette skal fungere må vi gjøre et par andre endringer i DataProcessor
.
Legg til et privat felt _personLookup
for tjenesten og oppdater klassens konstruktør til å ta inn en instanse av tjenesten som input. Set det private feltet i konstruktøren.
private readonly IPersonLookup _personLookup;
public DataProcessor(IPersonLookup personLookup)
{
_personLookup = personLookup;
}
Registrer din implementering i Program.cs klassen.
void RegisterCustomAppServices(IServiceCollection services, IConfiguration config)
{
services.AddTransient<IPersonService, PersonService>();
services.AddTransient<IDataProcessor, DataProcessor>();
// Other custom services
}
Personoppslag eksempel
Tjenesten kan benyttes fra alle “handlers” i logikk klassene i en app. Nedenfor har vi laget et eksempel som gjør oppslag i ProcessDataWrite
metoden i DataProcessingHandler
.
public async Task<bool> ProcessDataWrite(
Instance instance, Guid? dataId, object data)
{
if (data is MessageV1 message)
{
Person person = await _personLookup.GetPerson(
message.Personnummer,
message.Etternavn,
CancellationToken.None);
message.Fornavn = person.FirstName;
return true;
}
return false;
}
For at dette skal fungere må vi gjøre et par andre endringer i DataProcessingHandler
.
Legg til et privat felt _personLookup
for tjenesten og oppdater klassens konstruktør til å ta inn en instanse av tjenesten som input. Set det private feltet i konstruktøren.
private readonly IPersonLookup _personLookup;
public DataProcessingHandler(IPersonLookup personLookup)
{
_personLookup = personLookup;
}
Endringene i DataProcessingHandler
konstruktøren medfører at man også må gjøre endringer i konstruktøren til App
klassen. Legg til IPersonLookup
som input parameter og bruk verdien som input i konstruktøren til DataProcessingHandler
.
public App(
...
IText textService,
IPersonLookup personLookup,
IHttpContextAccessor httpContextAccessor) : base(...)
{
_logger = logger;
_validationHandler = new ValidationHandler(httpContextAccessor);
_dataProcessingHandler = new DataProcessingHandler(personLookup);
_instantiationHandler = new InstantiationHandler(profileService, registerService);
_pdfHandler = new PdfHandler();
}
Håndtering av feil
Uten flere endringer enn de som er beskrevet over, vil app backend begynne å svare med statuskode 429 - TooManyRequests
hvis brukeren har oppgitt feil data for mange ganger. Denne statuskoden er for øyeblikket ikke håndtert av frontend delen av app koden. Dette vil i utganspunktet resultere i “ukjent feil” som kan unngås ved å legge inn håndtering av exceptions. Det kan legges inn kode som fanger opp PlatformHttpException med en response med statuskode 429, men det er i dag ingen god innebygget mekanisme som kan brukes til å informere brukeren om hvorfor noe gikk galt. Det man eventuelt kan gjøre er å benytte et felt i datamodellen.
try
{
...
return true;
}
catch (PlatformHttpException phex)
{
switch (phex.Response.StatusCode)
{
case HttpStatusCode.TooManyRequests:
// Add corrective messures
break;
case HttpStatusCode.NotFound:
// Add corrective messures
break;
}
throw;
}