Rendering Partials in ASP.NET MVC

Asked

Viewed 2,534 times

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 within another. Only, 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 where the code that calls the 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 respective files:

Students:

  • _Add occurrence.cshtml
  • Adds.cshtml
  • Details.cshtml
  • Edits.cshtml
  • Index.cshtml
  • Removes.cshtml

Occurrences:

  • Adds.cshtml
  • Details.cshtml
  • Edits.cshtml
  • Index.cshtml
  • Removes.cshtml

Shared:

Inside Shared I have the directory Editortemplates and it contains:

  • Collection.cshtml

Dentro de 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);
    }
  • Tries @Html.Partial("/Alunos/_AdicionaOcorrencia", ocorrencia)

  • 2

    And what mistake it makes?

  • I’ve done it this way. And if I put it this way, it gives error saying that it does not find the file. I have already put the partial up in the Shared folder and it does not think at all. And it just does not give any error, only it does not appear the partial. Only the text that there in the div inside the Else.

  • So, there’s nothing at all, because I didn’t populate the occurrences part because I couldn’t render the partial to test and register something. It’s strange, because it should be rendering, because this partial is to register and not to list... I didn’t even do it yet, because I’m trying to understand why in a being appearing nothing.

  • I don’t understand anything anymore. You’re not passing items on the model, so how do you expect him not to go to Else?

  • What happens is, I can not register anything in the model, because the partial view I did to make the registration does not load, that’s why I did not register anything. Or rather, let me try another way, @Cesarmiguel would I be able to do a partial view to list ? And then render this other partial to register ?

  • Check the Model.Occurrences come without data. Put a breackpoint in the controller and see if it comes with data

  • I’ve done it too. And it doesn’t stop, it goes right through, it’s like I don’t have the breakpoint. I don’t understand anything. Do I have to create a partial class for it to render ? I’ve been researching and I saw that there is this partial class.

  • Put your controller code in the question to take a look

  • Changes made, present controller !

  • Do you have any student data in the comic book? You must not have

  • The table is already there. But I didn’t register anything because I’m not able to open the partial view... In other words, I have the Students table, which already has data, and the table of occurrences that has nothing. But the student table already has the reference for the occurrences as well as the occurrences has the reference for students. But the case is that I’m not able to render the partial to register and I don’t know why.

  • So it’s explained! You’re making a query where you check for students in the occurrences, as you don’t have the Model goes to empty... When you check in the view the Model no if, and as it has nothing goes to Else. Go to the database and make there an occurrence to the "nail" and you will see that it can. You should follow some tutorials before doing a project in your head...

  • Is there a link that I can use as a reference so I do this action there in the bank ?

Show 9 more comments

2 answers

4


Following MVC good practices, if your project is minimal, you have to be able to enter an occurrence even if you don’t have the Students screen ready.

To enter 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 insert occurrences off the Student screen to finish your Student screen:

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

2

substitute

@Html.Partial("_AdicionaOcorrencia", ocorrencia)

for

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

whenever returning a partial view, in the control override the Actionresult porPartialViewResult.

With Actionresult it works, but for the sake of combination of request and return use Partialviewresult when returning a partial view

Browser other questions tagged

You are not signed in. Login or sign up in order to post.