#

Create und Edit Update

 

Das folgende Beispiel erstellt ändert das Create Formular in ein Edit Formular für Artikel.

Dabei wird folgend die View Edit als Eingabe-Formular zum Erstellen neuer Datensätze verwendet, aber auch als reines Update-Eingabeformular.

 

Öffnen der View

Das View-Formular wird entweder geöffnet über die Controller-Action: Create() oder über Edit(ID)

 

Create

Im vorigen Tutorial wurde eine New-Methode und ein New-View Formular verwendet.

Um der allgemeinen CRUD Definition (Create-Refresh-Update-Delete) zu folgen wurde das Erstellen in Create umbenannt.

Dabei öffnet Create() das Eingabeformular. Da das Eingeben von Neuen Daten fast gleich ist zur Änderungs-Eingabe von Daten, wird nur noch ein Formular mit dem Namen View-Edit verwendet.

Somit öffnet die Create() Methode im Controller das Edit-Formular mit einem leeren Artikel

 

Create Methode

Im MVC Controller befindet sich die Methode Create() zum Öffnen eines leeren Erstellungs-Formulars.

       public IActionResult Create()

        {

            //----< Create New() >----

            //*leeres eingabe-formular fuer neuen Datensatz

            IEnumerable<ModelBase_Produktgruppe > produktgruppen = _context.tblBase_Produktgruppen.ToList();

 

            ViewModels.ViewModel_Artikel_Edit viewModel = new ViewModels.ViewModel_Artikel_Edit

            {

                Artikel = new Model__Artikel(),

                Produktgruppen = produktgruppen

            };

 

            return View("Edit",viewModel);

            //----</ Create New() >----

        }

 

Edit(ID) Methode

Wird das Formular mit Edit geöffnet, dann muss man eine ID mitübergeben.

Artikel  = await _context.tbl_Artikel.SingleOrDefaultAsync(a => a.ID_Artikel == id),

 

Die ID wird aus der URL Adresse wie Artikel/Edit/5 als Parameter übernommen

Edit(int? id)

 

C# Code zum laden des Edit-Formulars

        // GET: Produktgruppens/Edit/5

        public async Task<IActionResult> Edit(int? id)

        {

            //--------< Edit(ID) >--------

            //*open and load Edit View Form

            if (id == null)

            {

                return NotFound();

            }

            //----< Edit or Create >----

            //*leeres eingabe-formular fuer neuen Datensatz

            IEnumerable<ModelBase_Produktgruppe> dropdown_produktgruppen = _context.tblBase_Produktgruppen.ToList();

            ViewModels.ViewModel_Artikel_Edit data = new ViewModels.ViewModel_Artikel_Edit

            {

                Artikel  = await _context.tbl_Artikel.SingleOrDefaultAsync(a => a.ID_Artikel == id),

                Produktgruppen = dropdown_produktgruppen

            };

 

            return View("Edit", data);

            //--------</ Edit(ID) >--------

        }

 

 

 

Rücksenden des Edit-Formulars

Post-Back des Eingabe-Formulars

Wenn man ein ausgefülltes Erstellungs-Formular mit Save absendet, dann werden die Formular-Daten vom Browser zum MVC Controller im IIS Server gesandt.

Das Edit-Formular wird für Create als auch für Edit-Vorgänge jeweils zur Edit-Methode im Controller gesandt.

Zur eindeutigeren Unterscheidung im Code hab ich die Postback Edit(..) Methode deshalb auch Edit_Postback genannt.

Diese Action muss in die Form asp-action=Edit_Postback geschrieben werden.

/Views/Artikel/Edit.cshtml

@model ArtikelWeb.ViewModels.ViewModel_Artikel_Edit

    ..

<div class="row">

    <div class="col-md-4">

        <form asp-action="Edit_Postback">

..

        </form>

    </div>

</div>

 

Eingabe-Edit-Formular

Beim Edit Formular wird ein leerer Datensatz oder ein einzelner Datensatz angezeigt.

Damit dieser eindeutig verarbeitet werden kann, muss die ID als Hidden-Feld unsichtbar hinzugefügt werden.

<input type="hidden" asp-for="Artikel.ID_Artikel"  />

@Html.AntiForgeryToken()

 

Das Feld wird mit der ID als Integer geladen. Beim Laden über eine Create-Methode muss deshalb darauf geachtet werden, dass hier anstatt Null eine 0 eingespeichert wird.

Ansonsten entsteht beim Versuch das Formular zu speichern ein Validierungs-fehler (null zu int).

Dieseses Laden wird dadurch erreicht, indem man in Create() einen leeren Artikel hinzufügt.

Artikel = new Model__Artikel(),

 

@model ArtikelWeb.ViewModels.ViewModel_Artikel_Edit

   

    @*ArtikelWeb.Models.Artikel*@

 

@{

    ViewData["Title"] = "Edit or New";

    Layout = "~/Views/Shared/_Layout.cshtml";

}

 

<h2>New</h2>

 

<h4>Artikel</h4>

<hr />

 

 

<div class="row">

    <div class="col-md-4">

        <form asp-action="Edit_Postback">

            <div asp-validation-summary="ModelOnly" class="text-danger"></div>

 

            <input type="hidden" asp-for="Artikel.ID_Artikel"  />

            @Html.AntiForgeryToken()

 

            <div class="form-group">

                <label asp-for="Artikel.Artikelname" class="control-label"></label>

                <input asp-for="Artikel.Artikelname" class="form-control" />

                <span asp-validation-for="Artikel.Artikelname" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="Artikel.Text_Content" class="control-label"></label>

                <input asp-for="Artikel.Text_Content" class="form-control" />

                <span asp-validation-for="Artikel.Text_Content" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="Artikel.IDBase_Produktgruppe" class="control-label"></label>

 

                <select asp-for="Artikel.IDBase_Produktgruppe"

                        class="form-control"

                        asp-items="@(new SelectList(Model.Produktgruppen,"IDBase_Produktgruppe", "Produktgruppe"))"></select>

 

            </div>

 

            <div class="form-group">

                <label asp-for="Artikel.dtEdit" class="control-label"></label>

                <label asp-for="Artikel.dtEdit" class="control-label" />

            </div>

 

           

 

            <div class="form-group">

                <input type="submit" value="Save" class="btn btn-default" />

            </div>

        </form>

    </div>

</div>

 

<div>

    <a asp-action="Index">Back to List</a>

</div>

 

 

 

 

 

Edit_Postback

Normalerweise wird das Formular an die Edit(Formulardaten) Methode gesendet.

Damit man die Methode aber besser unterscheiden kann, habe ich die Methode Edit_Postback genannt.

Die Daten werden als HttpPost gesendet und nicht über HttpGet. Deshalb setzt man vor die Methode das Attribut [HttpPost]

 [HttpPost]

Als Rücksende-Daten werden die Formulardaten im Parameter übergeben.

ASP.Net MVC bindet dabei die Daten automatisch an den Typ, welcher als Rückgabeparameter definiert wird.  In diesem Fall werden die einzelnen Parameter automatisch in ein ViewModel Artikel_Edit zugeordnet

DataBinding / Formdata Binding

ViewModels.ViewModel_Artikel_Edit formData

 

Die Daten werden nur verarbeitet, wenn die Formular-Validierung richtig ist. Das heißt, dass alle Eingabedaten den Vorgaben entsprechen wir Zahl, Textlänge, Null und Integer.

Die Gültigkeit wird mit ModelState abgefragt.

if (ModelState.IsValid) {..}

 

Wenn das Formular von Create New kommt, dann ist die ID=0. Dann muss wie in dem vorigen Tutorial der Datensatz neu erstellt werden.

if (id==0)

{

  //----< Create() >----

  //*add a new dataset

  _context.Add(data);

  await _context.SaveChangesAsync();

  return RedirectToAction(nameof(Index));                    

  //----</ Create() >----   

}

 

Wenn eine ID Vorhanden ist, dann werden die Daten in der Datenbank geändert.

Hierzu wird aus der Datenbank-Schnittstelle das Datenset mit der passenden ID geholt und dann alle einzelnen Eigenschaften übernommen.

Anschliessend wird mit SaveChangesAsync() die Daten von lokalen Context-Zwischenspeicher zur SQL Server übernommen und aktualisert.

else

{

    //----< Update() >----  

    //*all Datafields

    //*_context.Update(data);

 

    //--< fields >--

    //*save defined fields

    var dataInDb = _context.tbl_Artikel.Single(a => a.ID_Artikel == id);

    dataInDb.Artikelname = data.Artikelname;

    dataInDb.Text_Content = data.Text_Content ;

    dataInDb.IDBase_Produktgruppe = data.IDBase_Produktgruppe ;

    dataInDb.dtEdit = DateTime.Now;

    //--</ fields >--

    await _context.SaveChangesAsync();

    //----</ Update() >----  

}  

 

Man kann einfacher per Update(Dataset) gleich das lokalen Speicher anpassen, aber dabei werden immer alle Eigenschaften übernommen.

//*all Datafields

//*_context.Update(data);

 

Edit Postback Code in /Controller

      // POST: Produktgruppens/Edit/5

        // To protect from overposting attacks, please enable the specific properties you want to bind to, for

        //public async Task<IActionResult> Edit(int id, [Bind("IDProduktgruppe,Produktgruppe")] ModelBase_Produktgruppe produktgruppen)

        [HttpPost]

        [ValidateAntiForgeryToken]       

        public async Task<IActionResult> Edit_Postback(int id, ViewModels.ViewModel_Artikel_Edit formData )

        {

            //------------< Edit_Postback() >------------

            Model__Artikel data = formData.Artikel;

            if (id != data.ID_Artikel)

            {

                return NotFound();

            }

 

            if (ModelState.IsValid)

            {

                try

                {

                    if (id==0)

                    {

                        //----< Create() >----

                        //*add a new dataset

                        _context.Add(data);

                        await _context.SaveChangesAsync();

                        return RedirectToAction(nameof(Index));

                        //return RedirectToAction("Index", "Artikel");

                        //return View(data);

                        //----</ Create() >----   

 

                    }

                    else

                    {

                        //----< Update() >----  

                        //*all Datafields

                        //*_context.Update(data);

 

                        //--< fields >--

                        //*save defined fields

                        var dataInDb = _context.tbl_Artikel.Single(a => a.ID_Artikel == id);

                        dataInDb.Artikelname = data.Artikelname;

                        dataInDb.Text_Content = data.Text_Content ;

                        dataInDb.IDBase_Produktgruppe = data.IDBase_Produktgruppe ;

                        dataInDb.dtEdit = DateTime.Now;

                        //--</ fields >--

                        await _context.SaveChangesAsync();

                        //----</ Update() >----  

                    }                }

                catch (DbUpdateConcurrencyException)

                {

                    //if (!ProduktgruppenExists(produktgruppen.IDBase_Produktgruppe))

                    //{

                    //    return NotFound();

                    //}

                    //else

                    {

                        throw;

                    }

                }

                return RedirectToAction(nameof(Index));

                //return View(nameof(New));

            }

            return View(nameof(Index));

            //------------< Edit_Postback() >------------

        }

 

Visual Studio: Controllers/ArtikelController.cs in C#

 

Mobile

.

123movies