Domanda

Ho un problema che si presenta in un modulo che sto cercando di pubblicare. Nello scenario in cui il modulo non viene convalidato, sto seguendo il percorso standard per chiamare ModelState.AddModelError () e quindi restituire un risultato Visualizza.

Il fatto è che gli helper HTML. * dovrebbero raccogliere il valore pubblicato durante il rendering e sto notando che i miei campi di testo lo fanno SOLO se li includo nell'elenco dei parametri dell'azione postback, che non dovrebbe ' è necessario visto che alcuni moduli hanno troppi campi per elencarli tutti come parametri.

Il mio codice di azione è approssimativamente:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditDataDefinition(long? id, string name)
{
    var dataDefinition = ...

    // do some validation stuff
    if (!ModelState.IsValid)
    {
        // manually set checkbox fields via ViewData seeing as this STILL doesn't work in MC 1.0 :P
        // ...
        return View(dataDefinition);
    }

}

Ora, dataDefinition (che è un'entità LINQ to SQL) ha un campo MinVolume , è gestito nella vista da questa linea:

Minimum: <%= Html.TextBox("MinVolume", null, new { size = 5 })%>

Tuttavia, quando la visualizzazione viene visualizzata dopo una convalida ModelState non riuscita, il valore immesso nella pagina originale che abbiamo pubblicato non viene conservato A MENO CHE non lo includa come parametro nel metodo postback. Letteralmente, posso "risolvere il problema" facendo questo:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditDataDefinition(long? id, string name, string minVolume)

Per qualche motivo ciò costringerà a conservare il valore del campo. Questo mi sembra stupido perché il mio modulo ha molti più valori di questo e non dovrei aggiungere un parametro solo per quel campo.

Qualche idea?

È stato utile?

Soluzione

Potrebbe essere che il tuo codice:

<%= Html.TextBox("MinVolume", null, new { size = 5 })%>

..ha il null per il valore predefinito param? Forse se cambi null in Model.MinVolume , il valore persisterà. In questo modo:

<%= Html.TextBox("MinVolume", Model.MinVolume, new { size = 5 })%>

Non sono sicuro che la tua azione restituisca il valore MinVolume nel modello. In tal caso, quanto sopra dovrebbe funzionare. Altrimenti, potrebbe essere necessario riformattare leggermente l'azione.

Altri suggerimenti

Oh amico, ho appena migliorato il design delle mie applicazioni. Il problema si verifica perché hai una convalida personalizzata (anch'io). Devi aggiungere dopo

ModelState.AddModelError()

questo

ModelState.SetModelValue("MinVolume", ValueProvider["MinVolume"]);

In vista deve essere

Mimum:<%=Html.Textbox("MinVolume")%>

Non so ancora perché funzioni, ma ha funzionato per me.

Qual è la chiave che si sta utilizzando quando si imposta il valore in ModelState su errore? Il codice che imposta il parametro value per un TextBox è simile a:

Parte pertinente del codice framework scaricato .

string attemptedValue = (string)htmlHelper.GetModelStateValue(name, typeof(string));
tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(name) : valueParameter), isExplicitValue);

Come puoi vedere se esiste il valore del tentativo, lo utilizzerà, ma solo se è disponibile la stessa chiave.

So che funziona perché ho un'azione che non accetta parametri e ottiene i valori direttamente da ValueProvider e utilizza AddModelError per indicare errori di convalida. Sono sicuro che i valori nelle mie caselle di testo vengono conservati.

MODIFICA : per conservare i valori, è necessario associarli in qualche modo al modello. Un modo per farlo è aggiungerli all'elenco dei parametri. Un altro modo è utilizzare UpdateModel (con i nomi dei parametri nella whitelist o nessuna whitelist). Un terzo modo è quello di aggiungere esplicitamente il parametro al modello come nella risposta di @ Jenea. Dato che l'helper estrae solo dallo stato del modello, devono essere presenti per mantenere i valori. Non esamina la proprietà Form della richiesta.

A quanto ho capito la soluzione è:

[Transaction]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EditDataDefinition(int id, FormCollection form)
{
    T itemToUpdate = repository.Get(id);
    UpdateModel(itemToUpdate, form.ToValueProvider());

    if (itemToUpdate.IsValid())
    {
        repository.SaveOrUpdate(itemToUpdate);
        return Json(ValidationResultToJson(itemToUpdate.ValidationResults()));
    }

    repository.DbContext.RollbackTransaction();
    return Json(ValidationResultToJson(itemToUpdate.ValidationResults()));
}

buona fortuna!

Un'altra soluzione è se si digita in view:

<%var minVolume=Request["MinVolume"]??"";%>
<%=Html.Textbox("MinVolume",minVolume,new {size=5})%>

Fare riferimento a questo articolo per vedere diversi modi per gestire il postback in ASP.NET MVC

text link

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top