none
Controller von anderem Controller aufrufen RRS feed

  • Frage

  • Hallo Leute,
    ich habe 2 Tabellen
    - Artikel
    - Lieferant

    welche durch die Tabelle
    - ArtikelLieferant
    miteinander verknüpft sind.

    CREATE TABLE [dbo].[Artikel_Lieferant] (
    	[ID]				INT				IDENTITY (1, 1) NOT NULL,
    	[Lieferant_ID]		INT				NULL,
    	[Artikel_ID]		INT				NULL,
    	[HEK]				DECIMAL (18, 4)	NULL,
    	...
    	...
    CONSTRAINT [PK_ArtikelLieferant] PRIMARY KEY CLUSTERED ([ID] ASC),
    CONSTRAINT [FK_ArtikelLieferant_Artikel] FOREIGN KEY ([Artikel_ID]) REFERENCES [dbo].[Artikel] ([ID]),
    CONSTRAINT [FK_ArtikelLieferant_Lieferant] FOREIGN KEY ([Lieferant_ID]) REFERENCES [dbo].[Lieferant] ([ID])
    );

    Für jeden Artikel kann es mehrere Lieferanten geben und jeder Lieferant kann auch mehrere Artikel liefern.

    Ich möchte jetzt in der Artikel Datenbank den jeweils höchsten und niedrigsten Einkaufspreis speichern.
    Dazu gibt es die Felder "EkH" und "EkL"

    Dazu rufe ich nach der ArtikelLieferant Aktualisierung aus dem ArtikelLieferantController den ArtikelController mit den entsprechenden Parametern auf

    ArtikelLieferantController

    return RedirectToAction("EditEk", "Artikel", new { id = artikelLieferant.ArtikelId, idlief = artikelLieferant.LieferantId, HEK = artikelLieferant.Hek });

    Die Parameter dürften zumindestens richtig übergebn werden.
    Im Browser sehe ich folgende URL:
    https://localhost:44339/Artikel/EditEk/75?idlief=8&HEK=0.87

    Im ArtikelController steht bei mir folgendes

            [HttpPost]
            [ValidateAntiForgeryToken]
            public async Task<IActionResult> EditEk(int? id, int idlief, decimal HEK, Artikel artikel)
            {
                if (id != artikel.Id)
                {
                    return NotFound();
                }
    
                if (HEK < artikel.EkL)
                {
                    artikel.EkL = HEK;
                }
    
                if (HEK > artikel.EkH)
                {
                    artikel.EkH = HEK;
                }
    
                if (ModelState.IsValid)
                {
                    try
                    {
                        _context.Update(artikel);
                        await _context.SaveChangesAsync();
                    }
                    catch (DbUpdateConcurrencyException)
                    {
                        if (!ArtikelExists(artikel.Id))
                        {
                            return NotFound();
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
                return RedirectToAction("Details", "Lieferant", new { id = idlief });
            }

    Leider funktioniert das Ganze noch nicht.
    Es werden keine Werte in die Artikel Tabelle geschrieben.
    Die Seite Lieferant/Details wird auch nicht aufgerufen.

    Jemand eine Ahnung was ich hier falsch gemacht habe?

    Samstag, 1. Juni 2019 11:17

Alle Antworten

  • Hallo Paul,

    HttpPost erwartet Daten im Body. Dies wird z.B. bei der Benutzung eine from-Tag in HTML erreicht.

    Du übergibt hier aber Daten über die URL somit musst Du HttpGet nutzen. Du erwartest zudem einen Artikel übergibst diesen aber nicht.

    [HttpGet]
    public IActionResult EditEk([FromRoute] int id, [FromQuery] int idlief, [FromQuery] decimal hek)
    {
        //https://localhost:5001/home/editek/75?idlief=8&hek=0.87
        return RedirectToAction("Index");
    }

    FromeRoute und FromQuery ist nicht unbedingt nötig. Hilft aber ASP.NET und dir zu bessern Übersicht.

    Es ist immer eine schlecht Idee aus einem Controller einen anderen aufzurufen. Der Controller ist nur dafür da View/User Daten entgegen zu nehmen und ans Model weiter zu leiten. 

    Das was Du da machen will, würde ich über das Model lösen


    Gruß Thomas
    13 Millionen Schweine landen jährlich im Müll
    Dev Apps von mir: UWP Segoe MDL2 Assets, UI Strings


    Samstag, 1. Juni 2019 13:53
  • Hallo Thomas,

    Ich dachte mir schon dass das nicht wirklich die eleganteste Lösung ist.
    Ich glaube auch dass ich mit der "Model" Lösung noch weitere "Probleme" lösen kann.

    Aber --  ich habe keine Ahnung wie ich das über die Models realisieren kann.
    Könntest Du mir da einen Lösungsweg verraten?

    Anbei meine beiden Models

    Artikel.cs

    using System;
    using System.Collections.Generic;
    
    namespace racknex.Models412
    {
        public partial class Artikel
        {
            public Artikel()
            {
                ArtikelLieferant = new HashSet<ArtikelLieferant>();
                Dateien = new HashSet<Dateien>();
                ProduktArtikel = new HashSet<ProduktArtikel>();
            }
    
            public int Id { get; set; }
            public decimal? EkH { get; set; }
            public decimal? EkL { get; set; }
    
            public ICollection<ArtikelLieferant> ArtikelLieferant { get; set; }
            public ICollection<Dateien> Dateien { get; set; }
            public ICollection<ProduktArtikel> ProduktArtikel { get; set; }
        }
    }

    ArtikelLieferant.cs

    using System;
    using System.Collections.Generic;
    
    namespace racknex.Models412
    {
        public partial class ArtikelLieferant
        {
            public int Id { get; set; }
            public int? LieferantId { get; set; }
            public int? ArtikelId { get; set; }
            public decimal? Hek { get; set; }
            public int? Ve { get; set; }
    
            public decimal? Summe
            {
                get { return this.Ve * this.Hek; }
                set { value = 0; }
            }
    
            public Artikel Artikel { get; set; }
            public Lieferant Lieferant { get; set; }
        }
    }


    Wie gesagt, sobald ein Eintrag bei "Artikellieferant" gemacht wird, sollen die Werte "EkH" und "EkL" bei Artikel angepasst werden.
    Besser wäre es noch dass sobald eine Änderung bei "Artikellieferant" gemacht wird, die Werte "EkH" und "EkL" angepasst werden.
    Es kann ja auch passieren dass ein Lieferant den Artikel nicht mehr liefert und dann der entsprechende Eintrag gelöscht wird.

    Vielen Dank für Deine Hilfe.
    Paul


    • Bearbeitet Paul_412 Samstag, 1. Juni 2019 19:56
    Samstag, 1. Juni 2019 19:55
  • Erstelle dir doch einfach eine statische Methode in Artikel übergibt die ArtikelId, den dbcontext und errechne den EkH und EkL neu. Wichtig dabei ist nur das die statische Methode alles bekommt was sie zu arbeiten braucht.

    Ist es den wirklich nötig das EkH und EkL in der Datenbank stehen?

    Was passiert den wenn ein User einen Artikel aufruft, werden ihm auch die ArtikelLieferanten zurüchgegeben?

    Und wenn ja, wäre es den nicht sinnvoller den EkH und Ekl erst dann zu berechnen und dem User anzuzeigen.

    Ich persönlich speichere keine Daten in der DB die einfach zu berechnen sind und ein Produkt aus anderen Felder in der DB sind. Wie Du siehst hat das ganze einen langen Ratenschwanz.

     


    Gruß Thomas
    13 Millionen Schweine landen jährlich im Müll
    Dev Apps von mir: UWP Segoe MDL2 Assets, UI Strings

    Samstag, 1. Juni 2019 20:59
  • Hallo Thomas,

    Ich gebe dir recht.
    Leider habe ich keine Ahnung wie ich auf einer Seite diese Informationen auslesen kann.

    Ich habe mehrere "Produkte", welche über "ProduktArtikel" mehrere "Artikel" haben können.
    Jeder "Artikel" hat über "ArtikelLieferant" mehrere "Lieferanten"
    Jeder "Artikel" kann mehrere "Produkte" haben und jeder "Lieferant" kann mehrere "Artikel" haben.

    In der "Produkte" Seite muss ich jetzt die entsprechenden "Artikel" Einkaufspreise aus "ArtikelLieferant" ausgeben.

    Mit der oben beschriebenen Lösung bringe ich das über den Umweg der EkH und EkL in "Artikel" hin.

    Zur Info
    "ProduktArtikel" ist mittels ProduktId und ArtikelId mit "Produkt" und "Artikel" verknüpft.
    "ArtikelLieferant" ist mittels ArtikelId und LieferantId mit "Artikel" und "Lieferant" verknüpft.

    Mit meinem Bescheidenen Kenntnissen schaffe ich es nicht vom "Produkt" Controller auf die entsprechenden Werte von "ArtikelLieferant" zu kommen.

    Ich würde mir den momentan eingeschlagenen Umweg gerne ersparen.

    Falls Du dafür zweckdienliche Hinweise hättest, wäre ich dankbar.

    Sonntag, 2. Juni 2019 19:25