Rendering Partials in ASP.NET MVC

6

I'm having a problem in my application where I wanted to use partial to render one page inside another. That is, one controller inside another. But what happens is the partial does not render at all and I've done almost everything, but it does not appear.

Here is the part of the code that calls partial:

  <div id="ocorrencias" class="panel-collapse collapse in">
        <div class="panel-body">
            @if (Model.Ocorrencias.Count > 0)
            {
                foreach (var ocorrencia in Model.Ocorrencias)
                {
                    @Html.Partial("_AdicionaOcorrencia", ocorrencia)
                }
            }
            else
            {
                <div>Ainda não há ocorrências</div>
            }
        </div>
    </div>

Directories and their files:

Students:

  • _AdditionAcurrent.cshtml
  • Add.cshtml
  • Details.cshtml
  • Edita.cshtml
  • Index.cshtml
  • Remove.cshtml

Occurrences:

  • Add.cshtml
  • Details.cshtml
  • Edita.cshtml
  • Index.cshtml
  • Remove.cshtml

Shared:

Inside Shared I have the EditorTemplates directory and it contains:

  • Collection.cshtml

Inside Shared:

  • _Layout.cshtml
  • _LoginPartial.cshtml
  • Error.cshtml

Controller

    private EntidadesContext db; //= new EntidadesContext();

    public OcorrenciasController(EntidadesContext contexto)
    {
        this.db = contexto;
    }
     public ActionResult Index()
    {
        var ocorrencias = db.Ocorrencias.Include(o => o.Aluno);
        return View(ocorrencias.ToList());
    }

    public ActionResult Adiciona(long id) /* Esse Id é de Aluno, não de Ocorrencia */
    {
        var aluno = db.Alunos.SingleOrDefault(a => a.Id == id);
        var ocorrencia = new Ocorrencia
        {
            Aluno = aluno
        };
        db.SaveChanges();
        return View(ocorrencia);
    }
     public ActionResult Edita(Ocorrencia ocorrencia)
    {
        db.Entry(ocorrencia).State = EntityState.Modified;
        db.SaveChanges();
        return View(ocorrencia);
    }
     public ActionResult Remove(long? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Ocorrencia ocorrencia = db.Ocorrencias.Find(id);
        if (ocorrencia  == null)
        {
            return HttpNotFound();
        }
        db.SaveChanges();
        return View(ocorrencia);
    }
    
asked by anonymous 15.05.2014 / 15:26

2 answers

4

Following the good practices of MVC, if your project is minimal, you have to be able to insert an occurrence even though the Student screen is not ready.

To insert the occurrence, modify your Controller to the following:

Controllers / OccurrencesController.cs

// http://seusite/Ocorrencias/Adiciona
// Aqui não tem argumentos e não salva nada no banco porque aqui 
// o Controller apenas devolve uma tela parcialmente preenchida.
// Repare que neste caso como não tem Id de Aluno, você vai ter que montar a DropDown.
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Adiciona()
{
    ViewBag.Alunos = db.Alunos.ToList();
    return View();
}

// http://seusite/Ocorrencias/Adiciona/5
// Aqui tem um argumento só, que é o Id do Aluno.
// Neste caso, o Controller também devolve uma tela parcialmente preenchida, 
// só que neste caso o Aluno já vem preenchido.
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Adiciona(long id) /* Esse Id é de Aluno, não de Ocorrencia */
{
    var aluno = db.Alunos.SingleOrDefault(a => a.Id == id);
    var ocorrencia = new Ocorrencia
    {
        Aluno = aluno
    };

    return View(ocorrencia);
}

// É neste caso que você está salvando uma ocorrência de fato por POST.
// Repare que o método aceita um objeto inteiro de ocorrência, e este é o 
// único método que pode salvar alguma coisa, e não o método que você estava fazendo.
[HttpPost]
public ActionResult Adiciona(Ocorrencia ocorrencia)
{
    if (ModelState.IsValid) {
        db.Ocorrencias.Add(ocorrencia);
        db.SaveChanges();
    }

    // Se o Model não for válido, você tem que montar a ViewBag de novo.
    ViewBag.Alunos = db.Alunos.ToList();

    return View(ocorrencia);
}

Views / Occurrences / Create.cshtml

@model CEF01.Models.Ocorrencia

@using (Html.BeginForm())
{
    if (Model.AlunoId != null) 
    {
        @Html.HiddenFor(model => model.AlunoId)
    } else {
        @Html.DropDownListFor(model => model.AlunoId, ((IEnumerable<Aluno>)ViewBag.Alunos).Select(option => new SelectListItem {
            Text = option.Nome, 
            Value = option.Id.ToString(),
            Selected = (Model != null) && (option.Id == Model.AlunoId)
        }), "Selecione...")
    }

    <div class="form-horizontal">
        <h4>Ocorrencia</h4>
        <hr />
        @Html.ValidationSummary(true)

        <div class="form-group">
            @Html.LabelFor(model => model.Tipo, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Tipo)
                @Html.ValidationMessageFor(model => model.Tipo)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Causa, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Causa)
                @Html.ValidationMessageFor(model => model.Causa)
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Observacao, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Observacao)
                @Html.ValidationMessageFor(model => model.Observacao)
            </div>
        </div>

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

So you can easily enter occurrences off the Student screen to finish your Student screen:

http://seusite/Ocorrencias/Create http://seusite/Ocorrencias/Create/IdDoAluno

    
15.05.2014 / 20:50
2

replace

@Html.Partial("_AdicionaOcorrencia", ocorrencia)

by

@{Html.RenderPartial("_AdicionaOcorrencia", ocorrencia);}

Whenever you return a partial view, in the control replace the ActionResult with thePartialViewResult.

With ActionResult it works, but for the sake of combination request and return use the PartialViewResult when it will return a partial view

    
31.01.2016 / 17:41