MVC 3 Obtenga el resultado de la vista parcial en el modelo

Estoy seguro de que esto es fácil, pero tal vez no he buscado bien...

Quiero saber cómo obtener resultados de una vista parcial del modelo y/o controlador.

Si el usuario ingresa un Nombre, Género (del menú desplegable) y Grado (del menú desplegable), solo encuentro Nombre y Género en el modelo. Quiero saber cómo obtener el Grado desde el menú desplegable en la vista parcial hasta el modelo, para poder verlo en el controlador.

Busque esta pregunta en el código del controlador:

¿Qué debo hacer para que el GradeLevel de la clase parcial esté aquí: <<<<

Nota: este no es el código exacto. Puede haber errores tipográficos pequeños e insignificantes.

EDITAR: Aparentemente no puedes agregar un comentario largo, así que lo agregaré aquí:

Gracias, Tom y Mystere Man. Tom me hizo pensar en por qué no funciona. No pensé en la vinculación del modelo. Con el diseño que propuse, el HTML se procesa y el menú desplegable Grado tiene esta identificación: "Grado". La propiedad en el modelo al que quiero vincularme es: "GradeLevelID". Si cambio el asistente en la vista parcial para que sea @Html.DropDownList("GradeLevelID"... funciona perfectamente.

Pero esa no es una buena solución. Mi idea era abstraer la vista parcial de la vista principal. ¡La codificación difícil del nombre arruina eso! Trabajé en una solución ligeramente mejorada. En la vista principal, cambio la instrucción @Html.Partial para pasar el nombre de la propiedad del modelo al parcial. Como tal:

@Html.Partial("GradeDropDown", (SelectList)Model.GradeSelectList, new ViewDataDictionary { { "modelPropertyName", "GradeLevelID" } })

Entonces podría cambiar la vista parcial para decir

@model System.Web.Mvc.SelectList
@Html.DropDownList((string)ViewData["modelPropertyName"], Model)

Pero eso también parece una forma tonta de abordar las cosas. Gracias por la ayuda. Veré EditorTemplates.


Aquí está mi modelo:

public class RegisterModel{

    public MemberRegistration MemberRegistration{
        get{
            if (HttpContext.Current.Session["MemberRegistration"] == null){
                return null;
            }
            return (MemberRegistration)HttpContext.Current.Session["MemberRegistration"];

        }

        set{
            HttpContext.Current.Session["MemberRegistration"] = value;
        }

    }

    public string FirstName{
        get{
            return MemberRegistration.FirstName;
        }
        set{
            MemberRegistration.FirstName = value;
        }
    }

    public SelectList GenderSelectList{
        get{

            List<object> tempList = new List<object>();

            tempList.Add(new { Value = "", Text = "" });
            tempList.Add(new { Value = "M", Text = "Male" });
            tempList.Add(new { Value = "F", Text = "Female" });

            return new SelectList(tempList, "value", "text", MemberRegistration.Gender);
        }
    }

    [Required(ErrorMessage = "Gender is required")]
    public string Gender{
        get{
            return MemberRegistration.MemberPerson.Gender;
        }
        set{
            MemberRegistration.MemberPerson.Gender = value;
        }
    }

    public SelectList GradeLevelSelectList{
        get{
            List<object> tempList = new List<object>();

            tempList.Add(new { Value = "", Text = "" });
            tempList.Add(new { Value = "1", Text = "1st" });
            tempList.Add(new { Value = "2", Text = "2nd" });
            tempList.Add(new { Value = "3", Text = "3rd" });
            tempList.Add(new { Value = "4", Text = "4th" });

            return new SelectList(tempList, "value", "text", MemberRegistration.GradeLevel);
        }
    }

    [Required(ErrorMessage = "Grade is required")]
    public Int32 GradeLevel{
        get{
            return MemberRegistration.GradeLevel;
        }
        set{
            MemberRegistration.GradeLevel = value;
        }
    }
}

Aquí está mi vista principal:

@model RegisterModel

@using (Html.BeginForm())
{
   <p class="DataPrompt">
        <span class="BasicLabel">First Name:</span>
        <br />
        @Html.EditorFor(x => x.FirstName)
    </p>

    <p class="DataPrompt">
        <span class="BasicLabel">Gender:</span>
        <br />
        @Html.DropDownListFor(x => x.Gender, Model.GenderSelectList)
    </p>

    <p class="DataPrompt">
        <span class="BasicLabel">Grade:</span><span class="Required">*</span>
        <br />
        @Html.Partial("GradeDropDown", (SelectList)Model.GradeLevelSelectList)
    </p>

    <p class="DataPrompt">
        <input type="submit" name="button" value="Next" />
    </p>

}

Aquí está mi vista parcial (llamada "GradeDropDown"):

@model System.Web.Mvc.SelectList

@Html.DropDownList("Grade", Model)

Aquí está mi controlador:

[HttpPost]
public ActionResult PlayerInfo(RegisterModel model)
{
    string FirstName = model.Registration.FirstName;
    string Gender = model.Registration.Gender;

    >>>>> What do I need to do to get the GradeLevel from the partial class to be here: <<<<<
    Int32 GradeLevel = model.Registration.GradeLevel;           

    return RedirectToAction("Waivers");
}

preguntado el 03 de mayo de 12 a las 17:05

Comience por pasar el RegisterModel en lugar de un SelectList a su vista parcial, de modo que puede usar DropDownListFor. De esa manera, usará el nombre correcto para el elemento de modo que se publique correctamente. -

No quiero pasar el RegisterModel al parcial porque estoy tratando de encontrar una manera de tener la vista parcial sin necesidad de saber qué tipo de modelo va a estar en la vista principal. Estoy creando la vista parcial para que pueda usarse con diferentes vistas y modelos. Habrá otros modelos donde necesito un nivel de grado. -

@ user886740 - Estás usando la herramienta incorrecta. NO usa vistas parciales para lo que está tratando de hacer. Debería usar EditorTemplates, o quizás RenderActions. Los parciales deben usarse solo para sustituciones simples de tipo "incluir". -

2 Respuestas

Ni siquiera sé por qué estás usando una vista parcial. Todo lo que está haciendo es usar un método auxiliar, podría reemplazar la vista parcial con el método auxiliar en la vista y sería menos código.

En segundo lugar, deberías usar Html.DropDownListFor() en lugar de Html.DropDownList(), entonces nombrará correctamente los controles html por usted.

Solo haz esto:

<p class="DataPrompt"> 
    <span class="BasicLabel">Grade:</span><span class="Required">*</span> 
    <br /> 
    @Html.DropDownListFor(m => m.GradeLevel, (SelectList)Model.GradeLevelSelectList) 
</p> 

contestado el 03 de mayo de 12 a las 18:05

Sí, gracias por la sugerencia. Puede notar que eso es exactamente lo que hice con el menú desplegable Género. Sin embargo, mi objetivo es aprender a pasar datos de una vista parcial al modelo. Tendré una situación mucho más compleja cuando realmente ponga esto en producción. - Cary

@ user886740: no pasa datos de un parcial al modelo. Los parciales solo están separados en teoría, se representan en una sola vista con la vista principal, por lo que los datos se publican desde el parcial como cualquier dato en el principal. No son cosas separadas. - Erik Funkenbusch

intente esto para obtener el nombre correcto de los elementos cuando se publiquen.

En tu vista principal

 @Html.Partial("GradeDropDown", Model) //Pass the Model to the partial view

Aquí está su vista parcial (llamada "GradeDropDown"):

 @model RegisterModel

   @Html.DropDownList("Grade", (SelectList)Model.GradeLevelSelectList)

contestado el 03 de mayo de 12 a las 20:05

Ojalá eso lo hiciera. Primero, el modelo de la vista parcial no coincide. Entonces lo cambio a: @model RegisterModel. Eso permitió que Intellisense aceptara Model.GradeLevelSelectList. - Cary

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.