I'm using the BeginCollectionItem to save a list of data in my add method.
For this, I created a ViewModel
with the main data to the list that I want to save, in the POST method
I have ViewModel
TypePresitionVenueViewModel that has the following attributes:
public class TipoPrestacaoVencimentoViewModel
{
[Key]
public int TipoPrestacaoId { get; set; }
[Required(ErrorMessage = "Digite o nome da Prestação.")]
public string Descricao { get; set; }
[Display(Name = "Tipo de vencimento")]
[Required(ErrorMessage = "Escolha o tipo de Prestação.")]
public string TipoVencimento { get; set; }
[Display(Name = "Responsável TCE")]
public string Responsave { get; set; }
[Display(Name = "Quantidade de Arquivos")]
public int? QuantidadeArquivos { get; set; }
[Required(ErrorMessage = "Digite o ano da prestação!")]
[Display(Name = "Ano Vigência")]
public string AnoVigencia { get; set; }
public virtual ICollection<AnexoPrestacaoViewModel> Anexos { get; set; }
}
And I'll pass on a collection of Attachments :
public class AnexoPrestacaoViewModel
{
public int AnexoPrestacaoId { get; set; }
public string Titulo { get; set; }
public string Sequencia { get; set; }
public byte[] Arquivo { get; set; }
public DateTime DataArquivo { get; set; }
}
In my Add method, I send a new product to View
, like this:
public ActionResult Adicionar()
{
var recipePrestacao = new TipoPrestacaoVencimentoViewModel();
return View(recipePrestacao);
}
And saved with POST like this:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Adicionar(TipoPrestacaoVencimentoViewModel tipoPrestacao)
{
if (ModelState.IsValid)
{
_prestacaoDB.Adicionar(tipoPrestacao);
TempData["MensagemSuccess"] = "Prestação adicionada com sucesso!";
return RedirectToAction("Index");
}
return View(tipoPrestacao);
}
And I have a method to add new item in View
:
public ActionResult GetNewPrestacao()
{
return PartialView("_Anexo", new AnexoPrestacaoViewModel());
}
My View
is as follows:
@model PrestacaoWeb.Application.ViewModels.TipoPrestacaoVencimentoViewModel
@{
ViewBag.Title = "Adicionar Tipos de Prestações de Conta";
}
<style>
body .modal-admin {
width: 900px;
margin-left: 120px;
}
</style>
@using (Html.BeginForm("Adicionar", "Prestacao", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<div class="modal-dialog modal-admin">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">@ViewBag.Title</h4>
</div>
<br/>
<div class="col-md-offset-1">
<div class="bs-example">
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#dadosPrestacao">Prestação</a></li>
<li><a data-toggle="tab" href="#Anexo">Anexos</a></li>
</ul>
<div class="tab-content">
<div id="dadosPrestacao" class="tab-pane fade in active">
@Html.Partial("_DadosPrestacao")
</div>
<div id="Anexo" class="tab-pane fade">
<fieldset>
<legend>Anexos</legend>
<div class="new-anexo">
@Html.EditorFor(model => model.Anexos)
</div>
<div style="padding: 10px 0px 10px 0px">
<a id="add-anexo" href="javascript:void(0);">Add Anexo</a>
</div>
</fieldset>
</div>
</div>
</div>
<hr />
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<div class="col-md-6">
<input type="submit" value="Salvar" class="btn btn-primary" id="submitbtn" />
</div>
@Html.ActionLink("Cancelar", "Index", "Prestacao", null, new
{
@id = "btnAddPrestacao",
@class = "btn btn-danger"
})
</div>
</div>
</div>
</div>
</div>
</div>
}
@section Scripts
{
<script type="text/javascript">
$(function () {
$('#add-anexo').click(function () {
$.ajax({
url: '@Url.Action("GetNewPrestacao")',
type: 'POST',
success: function (data) {
$('.new-anexo').append(data);
}
});
return false;
});
});
</script>
}
And the PartialView
that uses the BeginCollectionItem like this:
@model PrestacaoWeb.Application.ViewModels.AnexoPrestacaoViewModel
@using (Html.BeginCollectionItem("Anexos"))
{
<div>
<div class="form-group">
@Html.LabelFor(model => model.Titulo, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-7">
@Html.EditorFor(model => model.Titulo, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Titulo, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Sequencia, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-7">
@Html.EditorFor(model => model.Sequencia, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Sequencia, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.DataArquivo, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-7">
@Html.EditorFor(model => model.DataArquivo, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.DataArquivo, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Arquivo, new { @class = "col-sm-2 control-label", @align = "right" })
<div class="col-md-10">
@Html.TextBoxFor(x => x.Arquivo, new { type = "file" })
@Html.ValidationMessageFor(model => model.Arquivo, String.Empty, new { @class = "help-block" })
</div>
</div>
</div>
}
The problem is that when I run my application, I get a System.NullReferenceException
from Collection.cshtml
. Here is the complete error:
Referência de objeto não definida para uma instância de um objeto.
Descrição: Ocorreu uma exceção sem tratamento durante a execução da atual solicitação da Web. Examine o rastreamento de pilha para obter mais informações sobre o erro e onde foi originado no código.
Detalhes da Exceção: System.NullReferenceException: Referência de objeto não definida para uma instância de um objeto.
Erro de Origem:
Linha 2:
Linha 3: <ul>
Linha 4: @foreach (object item in Model)
Linha 5: {
Linha 6: <li>
Arquivo de Origem: c:\Users\renilson.meneguci\Documents\Visual Studio 2013\Projects\UEM_ES\Fontes\PrestacaoWeb\src\PrestacaoWeb.UI\Views\Shared\EditorTemplates\Collection.cshtml Linha: 4
Rastreamento de Pilha:[NullReferenceException: Referência de objeto não definida para uma instância de um objeto.]
ASP._Page_Views_Shared_EditorTemplates_Collection_cshtml.Execute() in c:\Users\ti\Documents\Visual Studio 2013\Projects\UEM_ES\Fontes\PrestacaoWeb\src\PrestacaoWeb.UI\Views\Shared\EditorTemplates\Collection.cshtml:4
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +279
System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +125
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +124
System.Web.Mvc.Html.TemplateHelpers.ExecuteTemplate(HtmlHelper html, ViewDataDictionary viewData, String templateName, DataBoundControlMode mode, GetViewNamesDelegate getViewNames, GetDefaultActionsDelegate getDefaultActions) +727
System.Web.Mvc.Html.TemplateHelpers.TemplateHelper(HtmlHelper html, ModelMetadata metadata, String htmlFieldName, String templateName, DataBoundControlMode mode, Object additionalViewData, ExecuteTemplateDelegate executeTemplate) +1332
System.Web.Mvc.Html.TemplateHelpers.TemplateHelper(HtmlHelper html, ModelMetadata metadata, String htmlFieldName, String templateName, DataBoundControlMode mode, Object additionalViewData) +109
System.Web.Mvc.Html.TemplateHelpers.TemplateFor(HtmlHelper1 html, Expression1 expression, String templateName, String htmlFieldName, DataBoundControlMode mode, Object additionalViewData) +157
System.Web.Mvc.Html.EditorExtensions.EditorFor(HtmlHelper1 html, Expression1 expression) +94
ASP._Page_Views_Prestacao_Adicionar_cshtml.Execute() in c:\Users\ti\Documents\Visual Studio 2013\Projects\UEM_ES\Fontes\PrestacaoWeb\src\PrestacaoWeb.UI\Views\Prestacao\Adicionar.cshtml:67
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +279
System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +125
System.Web.WebPages.StartPage.ExecutePageHierarchy() +142
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +109
System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +379
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +108
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult) +890
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList1 filters, ActionResult actionResult) +97
System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +241
System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +29
System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +111
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +53
System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +19
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +51
System.Web.Mvc.Async.WrappedAsyncVoid'1.CallEndDelegate(IAsyncResult asyncResult) +111
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +606
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +288
Note: I'm following the template