Asp.Net MVC: ¿Por qué mi vista pasa modelos NULL a mi controlador?

Resuelto Kram_Koorbse asked hace 8 años • 2 respuestas

No puedo entender por qué mi vista solo devuelve un NULL para un modelo a mi controlador. Esto es para un método Editar publicación. Revisé otros controladores con métodos Editar publicación que están estructurados de la misma manera que este y funcionan bien. Parece ser solo esta vista y controlador.

Aquí está mi punto de vista:

@model Non_P21_Quote_System_v1._0.Models.gl_code

@{
    ViewBag.Title = "Edit";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Edit</h2>

@if (TempData["Message"] != null)
{
    <div style="color:green">
        @TempData["Message"]
    </div><br />
}
@if (ViewBag.error != null)
{
    <div style="color:red">
        <h3>@ViewBag.error</h3>
    </div><br />
}

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>gl_code</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.ID)

        <div class="form-group">
            @Html.LabelFor(model => model.GL_code, "GL Code", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.GL_code, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.GL_code, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.GL_description, "Gl Description", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.GL_description, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.GL_description, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.expense_type_ID, "Expense", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("expense_type_ID", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.expense_type_ID, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.eag, "Employee Account Group", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.DropDownList("eag", null, htmlAttributes: new { @class = "form-control" })
                @Html.ValidationMessageFor(model => model.eag, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "gl_Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Aquí está mi método de controlador:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "ID,GL_code,GL_description,expense_type_ID,eag")] gl_code gl_code)
{
    if (ModelState.IsValid)
    {           
        db.Entry(gl_code).State = EntityState.Modified;
        await db.SaveChangesAsync();
        return RedirectToAction("gl_Index");      
    }
    ViewBag.eag = new SelectList(db.employee_account_group, "ID", "eag_name");
    ViewBag.expense_type_ID = new SelectList(db.expense_type, "ID", "type", gl_code.expense_type_ID);
    return View(gl_code);
}

Cuando lo depuro, veo que el modelo que se pasa tiene un valor NULL. Veo esto en el lado del controlador en la parte de parámetros del método Editar.

Kram_Koorbse avatar Jan 19 '16 03:01 Kram_Koorbse
Aceptado

Es nulo porque su modelo contiene una propiedad denominada gl_codey también ha nombrado el parámetro de su modelo gl_codeen el método POST.

Cambia el nombre de uno u otro y el modelo se enlazará correctamente.

Lo que sucede internamente es que el formulario envía un par de nombre/valor para cada control de formulario exitoso, en su caso gl_code=someValue. El DefaultModelBinderprimero inicializa una nueva instancia de su modelo. Luego lee los valores del formulario, encuentra una coincidencia para la propiedad en su modelo y la establece en someValue. Pero también encuentra una coincidencia en los parámetros del método e intenta establecer el valor del parámetro en someValue, lo cual falla (porque no puede hacerlo gl_code gl_code = "someValue";) y el modelo se convierte en null.

 avatar Jan 18 '2016 21:01

Parece que tiene una propiedad en su modelo de vista llamada gl_code. En su controlador, también hace referencia al modelo de vista como gl_code.

Intenta cambiar esto.

public async Task<ActionResult> Edit(gl_code gl_code)

A

public async Task<ActionResult> Edit(gl_code model)
KevDev avatar Jan 18 '2016 21:01 KevDev