1
As the post Edit object list with POST form in MVC C# I was able to make my application display the values. However, trying to save the data gives the error:
The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
In Portuguese, for documentation:
Falha na operação: a relação não pôde ser alterada porque uma ou mais propriedades da chave estrangeira não é nula. Quando uma alteração é feita em uma relação, a propriedade relacionada da chave estrangeira é definida como um valor nulo. Se a chave estrangeira não der suporte a valores nulos, uma nova relação deverá ser definida, a propriedade da chave estrangeira deverá ser atribuída a outro valor não nulo ou o objeto não relacionado deverá ser excluído.
This is my implementation:
Model
public class ProdutoPadrao : IEntidadeBase
{
[Key]
public int ProdutoPadraoID { get; set; }
[Display(Name = "Descrição")]
public string Descricao { get; set; }
[Display(Name = "Detalhe")]
public string Detalhe { get; set; }
public virtual ICollection<ProdutoPadraoCaracteristica> ListaProdutoCaracteristica { get; set; }
}
public class ProdutoPadraoCaracteristica : IEntidadeBase
{
[Key]
public int ProdutoPadraoCaracteristicaID { get; set; }
public int ProdutoPadraoID { get; set; }
public string Descricao { get; set; }
public int TipoCaracteristicaID { get; set; }
[ForeignKey("ProdutoPadraoID")]
public virtual ProdutoPadrao ProdutoPadrao { get; set; }
}
Controller GET
[ControleDeAcesso(TipoAcao.Normal)]
[Authorize]
public ActionResult Detalhar(int id)
{
using (var db = new ERPContext())
{
var produtoPadrao = db.ProdutoPadrao.Include("ListaProdutoCaracteristica").Where(w => w.ProdutoPadraoID == id).ToList().FirstOrDefault();
var retorno = EntidadeBaseExt.ValidarRegistro(produtoPadrao, TipoAcao.Visualizar);
if (retorno != "")
{
TempData["MsgRetornoError"] = retorno;
return RedirectToAction("Index", "Home");
}
ViewBag.ListaCaracteristica = new SelectList(ListagemPadrao.ListaTipoCaracteristica(), "Key", "Texto");
ViewBag.ListaUnidadeMedida = new SelectList(db.UnidadeMedida.ToListERP().Select(l => new ItemLPesquisa { Key = l.UnidadeMedidaID, Texto = l.Descricao }).ToArray(), "Key", "Texto");
return View(produtoPadrao);
}
}
Controller POST
[Authorize]
[HttpPost]
[ControleDeAcesso(TipoAcao.Normal)]
public ActionResult Detalhar(string btnSubmit, ProdutoPadrao model)
{
if (!ModelState.IsValid)
{
return View(model);
}
using (var db = new ERPContext())
{
var produtoPadrao = db.ProdutoPadrao.Include("ListaProdutoCaracteristica").Where(w => w.ProdutoPadraoID == model.ProdutoPadraoID).ToList().FirstOrDefault();
var retorno = FlexGestor.Helpers.EntidadeBaseExt.ValidarRegistro(produtoPadrao, TipoAcao.Gravar);
if (retorno != "")
{
TempData["MsgRetornoError"] = retorno;
return RedirectToAction("Index", "Home");
}
model.ListaProdutoCaracteristica = null;
if (btnSubmit != "Excluir")
UpdateModel(produtoPadrao);
FlexGestor.Helpers.EntidadeBaseExt.AtribuirValores(produtoPadrao, btnSubmit);
db.Entry(produtoPadrao).State = EntityState.Modified;
db.SaveChanges();
if (btnSubmit == "Excluir")
return RedirectToAction("Index", controller);
return RedirectToAction("Detalhar", controller, new { id = model.ProdutoPadraoID });
}
}
View Principal
@model FlexGestor.Models.ProdutoPadrao
@using (Html.BeginForm())
{
<div class="row">
@Html.TituloPagina("Visualizando Produto Padrão", "Clique para abrir a ajuda", "#help_produtoPadrao")
@Html.HiddenFor(m => m.ProdutoPadraoID)
<div class="col-md-12">
@Html.LabelFor(m => m.Descricao) @Html.ValidationMessageFor(m => m.Descricao)
@Html.TextBoxFor(m => m.Descricao, new { @class = "form-control" })
</div>
<div class="col-md-12">
@Html.LabelFor(m => m.Detalhe) @Html.ValidationMessageFor(m => m.Detalhe)
@Html.TextAreaFor(m => m.Detalhe, new { @class = "form-control", @rows = "4" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.ListaProdutoCaracteristica)
<div class="controls">
<ul id="PhonesEditor" style="list-style-type: none">
@if (Model.ListaProdutoCaracteristica != null)
{
foreach (var item in Model.ListaProdutoCaracteristica)
{
Html.RenderPartial("_CustomerPhonesEditor", item);
}
}
</ul>
</div>
<p><a id="addAnother" class="small-button">AddPhone</a></p>
</div>
<div class="row">
<div class="col-md-12">
@Html.BotaoTelaDetalhar()
</div>
</div>
}
View Detail
@model FlexGestor.Models.ProdutoPadraoCaracteristica
@using (Html.BeginCollectionItem("ListaProdutoCaracteristica"))
{
@Html.HiddenFor(m => m.ProdutoPadraoID)
@Html.HiddenFor(m => m.ProdutoPadraoCaracteristicaID)
<div class="col-md-3">
@Html.LabelFor(m => m.TipoCaracteristicaID) @Html.ValidationMessageFor(m => m.TipoCaracteristicaID)
@Html.DropDownList("TipoCaracteristicaID", (SelectList)ViewBag.ListaCaracteristica, String.Empty,
new { @class = "form-control" })
</div>
<div class="col-md-9">
@Html.LabelFor(m => m.Descricao) @Html.ValidationMessageFor(m => m.Descricao)
@Html.TextBoxFor(m => m.Descricao, new { @class = "form-control" })
</div>
<div class="form-group">
<div class="controls">
<a onclick="$(this).parent().parent().parent().remove();" class="small-button" style="float: left;">Delete</a>
</div>
</div>
}
Just clarify one thing: in which line of these sources is the error?
– Leonel Sanches da Silva
@Gypsy omorrisonmendez sorry, I forgot to say... On this line
db.SaveChanges();
– Tiedt Tech
What does this function?
UpdateModel()
– Leonel Sanches da Silva
He takes the data from
model
and arrow the values in the object. If I’m not mistaken, it’s . Net or Entity Framework.– Tiedt Tech
Can you please put it in the question?
– Leonel Sanches da Silva
@Gypsy I checked and she’s from class
System.Web.Mvc
. I think the problem is because I am using MVC 4 and EF 4. It will be if I upgrade it might be that it works?– Tiedt Tech
I don’t think that’s it. I think the method
UpdateModel()
changes something that should not.– Leonel Sanches da Silva
@Ciganomorrisonmendez what I find funny is if there is nothing on the list, it saves right. ? However if you have a record already on
ListaProdutoCaracteristica
gives the error. I’ll see if I can find some way to take the record the son records.– Tiedt Tech