Zpracování několika formulářů na jedné stránce - ASP.NET MVC   zodpovězená otázka

C#, ASP.NET MVC

Potřebuji na jedné URL adrese mít několik formulářů (post metodou) pro výpočet, výsledek se pak vypíše třeba pod daný formulář. Hledal jsem jak by se to dalo udělat - všude ukazují akorát validaci několika formulářů na jedné stránce a samotná akce vede na jinou akci/uplně jiný controller. Já bych to potřeboval mít všechno na jedné stránce. V Nette se to dá udělat celkem snadno, jde to v ASP.NET MVC vůbec?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Jestli jsem to dobře pochopil, tak jde o to, že každý formulář bude mít vlastní model. Pokud je to tak, tak to udělat lze, zrovna minulý týden jsem to použil. Finta je v tom, že ve VIEW použiju

Html.RenderPartial("_PartialView1", Model.item1)

a pak třeba o kus níž

Html.RenderPartial("_PartialView2", Model.item2)

s tím, že oba vedou na týž Controller. V mém případě je v modelu

@ModelType Tuple(Of KDESI, COSI)

ale pochopitelně tam může být úplně cokoliv. Je pak na controlleru, aby z předaných hodnot poznal, co má s modelem udělat. Neboli pokud budete mít např. 3 formuláře, tak je na controlleru, aby poznal, který z nich se odeslal.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Já to také moc nechápu.. Každopádně mám několik odpovědí na případné vaše otázky:

A) 3 formuláře - 3 různé akce, odpověď jako refresh části stránky pomocí ajaxu:

jde udělat jednoduše pomocí Ajax.BeginForm:

@using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "result" }))
{
    @Html.EditorFor(x => x.Foo)
    @Html.ValidationMessageFor(x => x.Foo)
    <input type="submit" value="OK" />
}

div id="result"></div>

    [HttpPost]
    public ActionResult Index(ViewModel model)
    {
        return Content("vysledek", "text/html");
    }

B) 3 formuláře a všechny mají odesílat na jednu akci, 3 ma různýma submit buttonkama.. todle je poměrně tricky a po napsání primitivního action selectoru je i použití velmi jednoduché:

http://blog.ashmind.com/2010/03/15/multi...

C) Napsal již Petr Zajíc

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ajax teď nepotřebuju. Jde mi jen o to směrovat dva formuláře na stejnou stránku. V podstatě mám toho http://stackoverflow.com/questions/15788... , jenže oni směrují jeden formulář na akci "Login" a druhý na "Register" a jiná akce=jiná url adresa, ne? Já po potřebuju mít na stejný. V podstatě by se mi hodilo mít dvě metody:

[HttpPost]
public ActionResult StejnaAkce(Model m) {
}

[HttpPost]
public ActionResult StejnaAkce(Model2 m2) {
}

Ale to nejde. Alternativně mě napadá směřovat oba formy na jednu akci a v ní rozpoznat jakej byl odeslanej, ale tím vlastně oba formuláře nebudou na sobě nezávislý.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Proč chcete mít odlišné formy posílané na stejnou akci? To mi vůbec nedává smysl a popravdě mi to přijde jako nepochopení konceptu trošku... Přeci jiný formulář = jiný request = jiný request handler = jiná akce...

Nechápu pointu toho, že chcete posílat 2 formuláře na stejnou akci.. jako aby jste neměl v HTML kódu jiné URL? nebo čeho chcete dosáhnout?? I v HTML můžete mít u všech formů stejnou akci a rozhodovat se na základě třeba názvu submit tlačítka - jak jsem psal v bodě B). To že máte ve vaší ukázce 2 akce se stejným názvem ale jiným modelem značí to, že by to logicky měly být dvě akce rozdílného názvu a né jedna..

aby jste mě pochopil,.. nevidím důvod toho, čeho chcete dosáhnout.. Máte 2 modely, 2 formy.. proč nemít dvě akce. Můžete na to mít 1 routu a vybírat akci na základě Name.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Já je nechci mít na stejnou akci, ale nevim jak mam pro 2 akce použít stejnou routu. Napadlo mě udělat:

[HttpPost]
public ActionResult Akce(Model1 m1, Model2 m2)

A tady rozhodnout jakej form se vlastně odeslal a zavolat přislušnou metodu na zpracování dat. Je to správně?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Je to špatně. Asi Vám poradíme, ale řekněte nám - slovy - čeho chcete vlastně dosáhnout. Máte 2 modely - jsou stejného typu, nebo jiného? Máte dva formuláře v jednom view. A chcete zpracovat ten, co se odešle. A teď buď tápete v pojmech "controller" a "akce", nebo existuje nějaký důvod, proč to potřebujete mít v jedné akci (to ale z komentáře výše nevyplývá) anebo chcete mít dvě akce a z nich se pak vracet na stejné místo (což samozřejmě jde). Čili asi poradíme, až pochopíme dotaz.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Předpokládám, že pod pojmem routa nemyslíte tedy Routu v routeconfigu, ale URL tedy chcete mít dva formuláře a odeslat je na stejné url /controller/akce .. To lze udělat tak, jak jsem vám již posílal link, tedy povíte MVC ať neselectne akci jen na základě routy, ale na základě názvu submit buttonu.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Asi už si rozumíme a kdyby ne, chci udělat tohle http://tinyurl.com/zcgmlln

Zkusil jsem to udělat podle toho článku (http://blog.ashmind.com/2010/03/15/multi..., ale odeslání formu post metodu to nespustí. Vypadá to nějak takhle:

public class ViewModel {
    public Search Search { get; set; }
    public Post Post { get; set; }
}

[ValidateInput(false)] 
public ActionResult Index() {
    ViewBag.q= "nic";
    return View(GetModel());
}

[HttpParamAction]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Search(Search search) {
    ViewBag.q= "search";
    return View(GetModel());
}

[HttpParamAction]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SavePost(Post post) {
    ViewBag.q= "post";
    return View(GetModel());
}

@model WebApplication3.Models.ViewModel 
<h1>@ViewBag.q</h1>

@using (Html.BeginForm()) { 
    @Html.TextBoxFor(model => model.Search.Query)
    <input type="submit" name="search" value="Odeslat" />
}

@using (Html.BeginForm())
{
    @Html.EditorFor(model => model.Post.Content, new { htmlAttributes = new { @class = "form-control" } })
    @Html.ValidationMessageFor(model => model.Post.Content, "", new { @class = "text-danger" })
    <input type="submit" name="savePost" value="Odeslat" />
}
nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ve formuláři musíte uvést akci, na kterou se má formulář odeslat.

Zkuste:

@using(Html.Action("SavePost")) {
...

@using(Html.Action("Search")) {
...
nahlásit spamnahlásit spam 0 odpovědětodpovědět

Zdravím,

no já to chápu tak, že to on právě nechce. On to chce poslat třeba 10ti tlačítky na "1 url".

Každopádně, mu tam skutečně chybí akce.

@using (Html.BeginForm("Action", "Post")){
  <input type="submit" name="saveDraft" value="Save Draft" />
  <input type="submit" name="publish" value="Publish" />
}

Na základě odekorání tímdle:

public class HttpParamActionAttribute : ActionNameSelectorAttribute {
    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo) {
        if (actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase))
            return true;

        if (!actionName.Equals("Action", StringComparison.InvariantCultureIgnoreCase))
            return false;
        
        var request = controllerContext.RequestContext.HttpContext.Request;
        return request[methodInfo.Name] != null;
    }
}

si vybere akci na základě name submit buttonu. Je to použito takto například tady:

https://vyhrajfabii.skoda-info.cz

<form method="post" novalidate="novalidate">
	<input type="submit" class="cancel btn-back" name="step3:back" value="Zpět" data-step="2">
      	<input type="submit" class="btn-next" name="step3:save" value="Pokračovat">
</form>
nahlásit spamnahlásit spam 0 odpovědětodpovědět

To nefunguje, přesměruje mě to na neexistující view Post/Action. Funguje až toto http://stackoverflow.com/a/16480167/5265....

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Hmm ze bych poslal spatny link? :-/ Je to mozne, kazdoapdne, hlavne ze jste to vyresil :-)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Možná pro příště - workflow pro výběr metody pro akce v MVC mám popsanou na plakátku, který je ke stažení na

http://martinstrimpfl.blogspot.cz/2014/1...

stránka 9 - může se vám to hodit.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Kouknu. Díky všem za pomoc.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Martine, mohu vaše slidy použít(odkázat na ně) v některém z dílů v mém seriálu?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Jistě, je to k volnému použití, respektive jsou pod touhle licenci - https://creativecommons.org/licenses/by/.... Ta je tam spíše proto, že jsem nenašel žádnou ještě méně restriktivní - ten 'appropriate credit' ani nemusí být, spíše to potěší. Ostatně já sám na některých stránkách používám výtvor někoho dalšího (uvádím tam zdroje)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Použil by jsem ViewModel. To znamená, že pro jednu stránku mohu použít jakýkoliv datový model.

Deklarace by pak byla:

[HttpPost]

public ActionResult StejnaAkce(Model model)

{

}

public SpolecnyViewModel

{

public Model1 model_1 { get; set}

public Model2 model_2{ get; set}

}

Controller:

public async Task<ActionResult> Login(SpolecnyViewModel model)

{

model.Model_1 = .....

model.Model_1 = .....

//atd....

return View(model)

}

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback