tirsdag 20. desember 2011

Utviklerskolen del 5, Legge inn en hendelse

I denne delen så ønsker jeg å registrere en hendelse i regObs. Det første jeg gjør er å se på datamodellen og ser at en hendelse (Incident) må være knyttet opp mot en registrering (Registration).
Jeg ønske å lage en webklient og tar utgangspunkt i ett MVC prosjekt hvor jeg bruker Razor syntaks. Jeg har på forhånd generert opp data klassene mine som vist i del 3 av utviklerskolen. Deretter setter jeg opp en rask disposisjon over komponentene jeg ønsker å lage:
  1. IncidentModel, inneholder datamodell og innhold i nedtrekkslistene.
  2. Kontroller som leverer innhold i nedtrekkslistene.
  3. View som inneholder skjema jeg ønsker å sende inn.
  4. Kontroller som lagrer data i regObs.
  5. View som viser at lagring har gått bra.
IncidentModel'en inneholder dataobjektet jeg ønsker å sende inn, samt 3 lister som skal fylle nedtrekkslistene i view mitt. I tillegg så har den en Load metode som laster data inn i listene. Normalt så anbefaler jeg ikke å bruke dataklassen direkte, men for å holde det enkelt så gjør jeg det i dette tilfellet.
public class IncidentModel
{        
    public Incident Incident { getset; }
 
    public List<ComboboxObject> ActiviysList { getset; }
    public List<ComboboxObject> DamageExtendList { getset; }
    public List<ComboboxObject> ForcastAccList { getset; }
 
    public void Load()
    {
        //peker til regObs api'et og oppretter en dbcontext
        var address = new Uri("http://h-web01.nve.no/test_regobsservices/odata.svc/");
        var dbContext = new RegObsEntities(address);
 
        DamageExtendList =
            dbContext.DamageExtentKD.Where(x => x.LangKey == 1).Select(
                x => new ComboboxObject { Id = x.DamageExtentTID, Text = x.DamageExtentName }).ToList();
 
        ForcastAccList =
            dbContext.ForecastAccurateKD.Where(x => x.LangKey == 1).Select(
                x => new ComboboxObject { Id = x.ForecastAccurateTID, Text = x.ForecastAccurateName }).ToList();
 
        ActiviysList =
            dbContext.ActivityInfluencedW.Where(x => x.LangKey == 1 && x.GeoHazardTID == 10)
            .OrderBy(x => x.ActivityInfluencedTID)
                .Select(x => new ComboboxObject { Id = x.ActivityInfluencedTID, Text = x.ActivityInfluencedName })
                .ToList();
    }
}


Når jeg har modellen min på plass så lager jeg en kontroller som returnerer den til view'et.

public ActionResult Index()
{
    //henter ut data og returnerer til view
    var model = new IncidentModel {Incident = new Incident()};
    model.Load();
    return View(model);
}

Deretter oppretter jeg View'et som inneholder skjema som skal fylles ut og sendes inn.
@using MyOdataProject.Models
@model IncidentModel
 
<h2>regObs, utviklerskolen 5</h2>
<p>Fyll inn skjema for å registrere en hendelse.</p>
<div>
    @using (Html.BeginForm())
    {
        <label>Tid: </label>@Html.TextBoxFor(x=>x.Incident.DtEndTime) <br/>
        <label>Overskrift: </label>@Html.TextBoxFor(x=>x.Incident.IncidentHeader) <br/>
        <label>Ingress: </label>@Html.TextBoxFor(x=>x.Incident.IncidentIngress) <br/>
        <label>Beskrivelse: </label>@Html.TextBoxFor(x=>x.Incident.IncidentText) <br />
        <label>Aktivitet: </label>@Html.DropDownListFor(m => m.Incident.ActivityInfluencedTID, new SelectList(Model.ActiviysList, "Id""Text")) <br/>
        <label>Skadeomfang: </label>@Html.DropDownListFor(m => m.Incident.DamageExtentTID, new SelectList(Model.DamageExtendList, "Id""Text")) <br/>
        <label>Nøyaktighet: </label>@Html.DropDownListFor(m => m.Incident.ForecastAccurateTID, new SelectList(Model.ForcastAccList, "Id""Text")) <br/>
        <label>Kommentar: </label>@Html.TextAreaFor(x=>x.Incident.Comment) <br/><br/>
        <p>
        <input type="submit" value="Send inn hendelse" />
        </p>
    }
</div>

Når view'et er ferdig så oppretter jeg en kontroller som tar imot skjema og lagrer tilbake til regObs.Legg merke til måten jeg hente ut en ny regId og knytter hendelsen opp mot denne. Vær obs på at jeg her ikke har knyttet opp mot observatør eller lokasjon. Dette er noe man alltid bør gjøre.

[HttpPost]
public ActionResult Index(IncidentModel model)
{
    //peker til regObs api'et og oppretter en dbcontext
    var address = new Uri("http://h-web01.nve.no/test_regobsservices/odata.svc/");
    var dbContext = new RegObs.RegObsEntities(address);
     //lag et nytt sted (alle registreringer må være knyttet opp mot et sted, koordinater er tilfeldigvalgt)
    var newObsLocation = new ObsLocation
   {
 DtRegTime = DateTime.Now,
 UTMZone = 33,
 UTMEast = 58429,
 UTMNorth = 6922438,
        Comment = "Utviklerskolen"
   };

   dbContext.AddToObsLocation(newObsLocation);
   dbContext.SaveChanges();
    //Lag en ny registrering (alt som skal lagres i databasen er knyttet opp mot en registrering)
   var newRegistration = new Registration
   {
 ObsLocationID = newObsLocation.ObsLocationID,
 DtObsTime = model.Incident.DtEndTime.Value,
 DtRegTime = DateTime.Now,
 CompetenceLevelTID = 0
    };
    dbContext.AddToRegistration(newRegistration);
    dbContext.SaveChanges();
 
    //Knytte incident mot registrering
    model.Incident.RegID = newRegistration.RegId;
    dbContext.AddObject("Incident", model.Incident);
    dbContext.SaveChanges();
    return View("Complete");
}

Komplett eksempel kan lastes ned her

Ingen kommentarer:

Legg inn en kommentar