Pouze tento týden sleva až 80 % na e-learning týkající se C# .NET. Zároveň využij akci až 30 % zdarma při nákupu e-learningu - Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
discount 30 + hiring

Diskuze: ASP.NET MVC Předávání dat

Aktivity
Avatar
Michal Pflegshörl:18.11.2020 14:44

Potřebuju předat data z jednoho View/Controlleru do jiného View/Controlleru

Zkusil jsem: V Controllers/Tes­tController.cs:

public IActionResult Index()
        {
            ViewData["Title"] = "Test";

            DatumVytvoreni Vytvoreno = new DatumVytvoreni(); //vlastní datový typ
            Vytvoreno.Datum = DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss");

            return View(Vytvoreno);
        }

        public ActionResult ZobrazTest2(DatumVytvoreni Vytvoreno)
        {
            return RedirectToAction("Index", "Test2", Vytvoreno);
        }

ve View/Test/Index­.cshtml

@model Web.Models.DatumVytvoreni
<div>
    Vygenerováno v @Model.Datum;
</div>
<div>
    @Html.ActionLink("Zobraz test 2", "ZobrazTest2", Model)
</div>

v Controllers/Tes­t2Controller.cs

public IActionResult Index(DatumVytvoreni Vytvoreno)
        {
            ViewData["Title"] = "Test 2";

            return View(Vytvoreno);
        }

a ve View/Test2/In­dex.cshtml

@model Web.Models.DatumVytvoreni
<div>
    Vygenerováno v @Model.Datum;
</div>

Bohužel při předání z View do Controlleru i mezi Controllery je proměnná Vytvořeno vždy nastavena na výchozí hodnoty

Chci docílit: Potřebuji předávat proměnnou vlastního datového typu mezi Controllery a View

 
Odpovědět
18.11.2020 14:44
Avatar
Odpovídá na Michal Pflegshörl
Michal Štěpánek:19.11.2020 9:24

V ASP.NET MVC jsem musel tomu parametru pro předání přidat nějakou hodnotu, např.

return RedirectToAction("MyRequests", "Requests", new { id = prihluziv });

v Core se to dělá jinak?

Nahoru Odpovědět
19.11.2020 9:24
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Odpovídá na Michal Štěpánek
Michal Pflegshörl:20.11.2020 11:36

Takhle se dají bohužel předávat pouze textové hodnoty, nebo ne?
Já potřebuju předávat vlastní datový typ.
Našel jsem řešení pomocí přetížení Session

public static class SessionExtensions
    {
        public static void SetObjectAsJson(this ISession session, string key, object value)
        {
            session.SetString(key, JsonConvert.SerializeObject(value));
        }

        public static T GetObjectFromJson<T>(this ISession session, string key)
        {
            var value = session.GetString(key);
            return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
        }
    }

Nevím jestli je to ideální řešení protože je tam určitý timeout, a nevím jak přesně funguje.
Timeout se týká celé Session (tzn. Počítá se od spuštění aplikace a po ulynutí se celá vymaže, nebo se počítá od vytvoření konkrétního objektu a po uplynutí se vymaže jen ten konkrétní objekt?
Jaká je rozdíl mezi Session a TempData? Nebylo by použití TempData vhodnější?

Ještě jsem narazil na problém s globální proměnou. Existuje způsob jak jí v rámci controlleru např. v Action Index přiřadit hodnotu a později při zavolání jiné akce tu hodnotu načíst?

 
Nahoru Odpovědět
20.11.2020 11:36
Avatar
Michal Štěpánek:20.11.2020 12:15

Session bych v tomto případě asi nepoužil, protože to lze na prohlížeči "vypnout" a v tu chvíli by ti to přestalo fungovat.

Nahoru Odpovědět
20.11.2020 12:15
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Tadeáš Burda
Brigádník
Avatar
Odpovídá na Michal Pflegshörl
Tadeáš Burda :20.11.2020 15:13

TempData je good nato...Sprav si extension na TemData a potom budes volat vnutry controlleru

public static class TempDataExtensions
    {
            public static T DeserializeToObject<T>(this ITempDataDictionary tempData, string key) where T : new()
            {
                    string entry = tempData[key]?.ToString();

                    T result = (entry == null) ? new T() : JsonConvert.DeserializeObject<T>(entry);

                    return result;
            }

            public static void SerializeObject<T>(this ITempDataDictionary tempData, T obj, string key)
            {
                    tempData[key] = JsonConvert.SerializeObject(obj, Formatting.Indented);
            }
    }

V controlleru potom volas this.TempData­.SerializeObjec­t(TVUJ OBJECT, KLUC)....Spatky to dostanes obdobne this.TempData­.DeserializeTo­Object<TVOJ OBJECT>(KLUC)­....Nejsem si isty ci v asp.net core 5.x uz ide predavat aj object, tady sa to roby cez JSON...Ten object je potom dostupni globalne v celem projekte a zanikde az si ho nekdo vipita cez kluc, dovtedy by ho mali TempData drzat...SNad pomohlo ;-)

Editováno 20.11.2020 15:13
Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
 
Nahoru Odpovědět
20.11.2020 15:13
Avatar
Tadeáš Burda
Brigádník
Avatar
Odpovídá na Michal Pflegshörl
Tadeáš Burda :20.11.2020 15:18

Ještě jsem narazil na problém s globální proměnou.

Globalne promnene nepouzivaj, v Core a ASP je uplne super podpora pro DI, pouzi raci to ked uz

 
Nahoru Odpovědět
20.11.2020 15:18
Avatar
Odpovídá na Tadeáš Burda
Michal Pflegshörl:24.11.2020 11:15

Díky,
tohle funguje dobře a pokud se to ještě takto upraví je z toho trvalá globální proměnná

public static T DeserializeToObject<T>(this ITempDataDictionary tempData, string key) where T : new()
        {
            string entry = tempData[key]?.ToString();

            T result = (entry == null) ? new T() : JsonConvert.DeserializeObject<T>(entry);

            SerializeObject<T>(tempData, result, key);

            return result;
        }
 
Nahoru Odpovědět
24.11.2020 11:15
Avatar
Tadeáš Burda
Brigádník
Avatar
Odpovídá na Michal Pflegshörl
Tadeáš Burda :24.11.2020 11:35

To je zbytecnem pouzi DI...

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    // ...

    services.AddScoped<ITvojObjekt, TvojObjekt>();

   // ...
}

TvojObjekt.cs

public interface ITvojObejkt
{
   // ...
}

public class TvojObjekt: ITvojObjekt
{
    // ...
}

Controller.cs

private readonly ITvojObjekt tvojObjekt;

public Controller(ITvojObjekt tvojObjekt)
{
    this.tvojObjekt = tvojObjekt;
}

Je to lepsi lebo takto stale serialicujes a deserializujes ten objekt a vytvaras novy... TempData neni nato, nato je DI... Takto budes mnet len jeden objekt dostupni v kazdem controllery co si ho necha vstriknut... Controller netreba pridavat do servce ti uz tam su :-)

Pokad chces predat objekt pouzi TempData...
Pokad chces globalny objekt pouzi DI...

Editováno 24.11.2020 11:36
 
Nahoru Odpovědět
24.11.2020 11:35
Avatar
Odpovídá na Tadeáš Burda
Michal Pflegshörl:25.11.2020 9:45

Můžeš mi to prosím ukázat konkrétněji.

Řekněme, že potřebuju tenhle vlastní objekt v jednom controlleru nastavit a takto nastavený ho mít k dispozici v ostatních controllerech

public class Nastaveni
    {
        public string Textik {get; set;}
        public int Cislo {get; set;}
    }
Editováno 25.11.2020 9:46
 
Nahoru Odpovědět
25.11.2020 9:45
Avatar
Tadeáš Burda
Brigádník
Avatar
Odpovídá na Michal Pflegshörl
Tadeáš Burda :25.11.2020 11:41

No...ne, to je cele :D Vyment TvojObjekt.cs za Nastaveni.cs a Controller.cs su ti tvoje kontrolery....To je secko....Tady mas doc skus si pozret to

 
Nahoru Odpovědět
25.11.2020 11:41
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Odpovídá na Tadeáš Burda
Michal Pflegshörl:27.11.2020 11:27

Startup.cs

public void ConfigureServices(IServiceCollection services)
        {
            services.AddScoped<INastaveni, Nastaveni>();
            services.AddControllersWithViews();
        }

Models/Nastaveni.cs

public interface INastaveni
    {
        // ...
    }

public class Nastaveni: INastaveni
    {
        public string Text { get; set; }
        public int Cislo { get; set; }
    }

Controllers/Home.cs

private readonly INastaveni nastaveni;

public Controller(INastaveni nastaveni)
        {
            this.nastaveni = nastaveni;
        }

public Controller(INas­taveni nastaveni) hlásí chybu CS1520 Metoda musí mít typ vrácené hodnoty.

 
Nahoru Odpovědět
27.11.2020 11:27
Avatar
Tadeáš Burda
Brigádník
Avatar
Odpovídá na Michal Pflegshörl
Tadeáš Burda :27.11.2020 12:15

ty si ten controller pomenoval jak??? HomeController, neco??....stej chyby mi vypliva ze si len do tvojeho controlleru vlozil ten muj kod....takto si vitvoril metodu a navratovi tip je controller....mnel to byt len priklad...to public Controlelr(Ineco neco), je konstrukt tvojeho kontroleru...tam si nechas to DI vstriknut....neni to metoda v kotroleru

 
Nahoru Odpovědět
27.11.2020 12:15
Avatar
Odpovídá na Tadeáš Burda
Michal Pflegshörl:27.11.2020 13:05

Promiň já jsem ten přípsěvek zpětně opravoval, ale asi se neuložil.
Chybu jsem zvládl opravit, pořád to ale nefunguje.
Když v metodě jednoho controlleru tomu nastaveni přiřadím hodnoty, tak v jiném kontrolu má nastavení výchozí hodnoty.
Jakým způsobem to nastavení předám jinému controlleru?

Editováno 27.11.2020 13:05
 
Nahoru Odpovědět
27.11.2020 13:05
Avatar
Tadeáš Burda
Brigádník
Avatar
Odpovídá na Michal Pflegshörl
Tadeáš Burda :27.11.2020 15:37

Aha asi sem spravil chybu ja...Skus pouzit AddSingleton<>()­...Ak to nepujde napis mi a posly aj kod, lebo inak nevim

Editováno 27.11.2020 15:37
 
Nahoru Odpovědět
27.11.2020 15:37
Avatar
Tadeáš Burda
Brigádník
Avatar
Odpovídá na Michal Pflegshörl
Tadeáš Burda :27.11.2020 15:40

Problem bude asi toto stackoverflow ...DI ti pokazde vytvori novu instanci...Takto by si mal mat len jednu

 
Nahoru Odpovědět
27.11.2020 15:40
Avatar
Tadeáš Burda
Brigádník
Avatar
Odpovídá na Michal Pflegshörl
Tadeáš Burda :27.11.2020 16:00

Mozno este keby vytvoris sam tu instancy Nastaveni.cs a regnes ju v DI a DI si ju ulozi a pak ju vstrikuje do Controlleru..­.Kazdooadne pointa je vtem ze DI drzi len tu jednu instanci a kazdemu kdo si ju vipita ju da...Potom ked neco vni zmenis odkadkolvek tak sa to zmeni globalne lebo vseci sa odkazuju len na tu jednu instanci....Mnelo by to ist

 
Nahoru Odpovědět
27.11.2020 16:00
Avatar
Michal Pflegshörl:14.12.2020 14:33

Tak to vypadá že po nahrazení

services.AddScoped<INastaveni, Nastaveni>();

za

services.AddSingleton<INastaveni, Nastaveni>();

se to chová přesně tak jak potřebuji (jako jedna proměná pro celý projekt)

 
Nahoru Odpovědět
14.12.2020 14:33
Avatar
Michal Pflegshörl:13.7.2021 8:45

Tak jsem se dostal k testování server-client v lokální síti a bohužel se to chová tak, že všichni clienti přebírají stejné nastavení.
To znamená, že pokud si jeden client něco v nastavení upraví, promítne se to všem ostatním clientům.
Já, ale logicky potřebuji aby každý client používal své vlastní nastavení.

Editováno 13.7.2021 8:46
 
Nahoru Odpovědět
13.7.2021 8:45
Avatar
Patrik Valkovič
Člen IT Redactor Gang
Avatar
Odpovídá na Michal Pflegshörl
Patrik Valkovič:13.7.2021 9:06

Ahoj. Reaguješ na půl roku starý příspěvek. Vytvoř si prosím nové vlákno.

Nahoru Odpovědět
13.7.2021 9:06
Nikdy neumíme dost na to, abychom se nemohli něco nového naučit.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 19 zpráv z 19.