1
I am conducting a college project and my knowledge in ASP.Net are not very deep. In my project I came across a relationship Mxm and I cannot usefully implement this situation. The relationship is as follows::
A company registers one or more garbage collection points and at the time of registration it chooses one or more garbage accepted in your collection point.
A type of garbage can be used in the registration of several collection points.
A collection point can associate several types of garbage that are accepted.
I have tried in numerous ways indicated here on this site. I tried this way here and creating the associative class manually, but in scaffolding the Entity does not generate the relation in the view.
Doing as indicated in this link Here, The Entity Framework generated the associative table automatically, but in scaffolding the views were created with no association. In 1xN relations the Entity automatically creates a dropdowlist
to be selected in the view.
In the Mxm relation you should not automatically create a group of
checkbox
or a selection list? (or am I expecting a lot from Entity...).If you cannot generate this Feature automatically, as you would that?
After generating the checkbox group or checklist, how to do to manipulate the associative table? (the table of the class in question the Entity has already created CRUD).
Follows the code:
[Table("PontoDeColeta")]
public class PontoDeColeta
{
public PontoDeColeta()
{
TipoDeLixo = new HashSet<TipoDeLixo>();
}
public int Id { get; set; }
[Required(ErrorMessage = "O prenchimento é obrigatório")]
[Display(Name = "Nome popular*: ")]
public string NomePopular { get; set; }
[Required(ErrorMessage = "O prenchimento é obrigatório")]
[Display(Name = "Endereço do ponto de coleta*: ")]
public string Endereco { get; set; }
//Armazena usuário logado
[HiddenInput(DisplayValue = false)]
public string UsuarioResponsavel { get; set; }
public ICollection<TipoDeLixo> TipoDeLixo { get; set; }
}
[Table("TipoDeLixo")]
public class TipoDeLixo
{
public TipoDeLixo()
{
PontoDeColeta = new HashSet<PontoDeColeta>();
}
//[Key]
//[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required(ErrorMessage ="O prenchimento é obrigatório")]
[Display(Name = "Nome do tipo de lixo*: ")]
public string NomeTipoLixo { get; set; }
[Display(Name = "Este tipo de lixo está ativo? ")]
public bool Ativo { get; set; }
public ICollection<PontoDeColeta> PontoDeColeta { get; set; }
}
Edit: Following the best response of the comment, I had to change my classes in addition to creating the associative class manually.
public class TipoDeLixo{
public Guid Id { get; set; }
[Required(ErrorMessage ="O prenchimento é obrigatório")]
[Display(Name = "Nome do tipo de lixo*: ")]
public string NomeTipoLixo { get; set; }
[Display(Name = "Este tipo de lixo está ativo? ")]
public bool Ativo { get; set; }
public ICollection<PontoDeColetaTipoDeLixo> PontosDeColetaTiposDeLixo { get; set; }
}
public class PontoDeColeta{
public Guid Id { get; set; }
[Required(ErrorMessage = "O prenchimento é obrigatório")]
[Display(Name = "Nome popular*: ")]
public string NomePopular { get; set; }
public ICollection<PontoDeColetaTipoDeLixo> PontosDeColetaTiposDeLixo { get; set; }
}
public class PontoDeColetaTipoDeLixo{
public Guid Id { get; set; }
public virtual TipoDeLixo TipoDeLixo { get; set; }
public Guid TipoDeLixoId { get; set; }
public virtual PontoDeColeta PontoDeColeta { get; set; }
public Guid PontoDeColetaId { get; set; }
}
Na View Create do Pontodecoleta:
@Html.Partial("_TiposDeLixo",Model.PontosDeColetaTiposDeLixo)
I created Partialview _Typodetrash with content:
@model IEnumerable<IdentitySample.Models.PontoDeColetaTipoDeLixo>
<div class="actions">
<a class="btn btn-default btn-sm" id="adicionar-tipo-de-lixo">
Adicionar Tipo de lixo
</a>
<script type="text/javascript">
$("#adicionar-tipo-de-lixo").click(function () {
$.get('/PontosDeColeta/NovaLinhaDeTipoDeLixo', function (template) {
$("#area-tipos-de-lixo").append(template);
});
});
</script>
</div>
<div id="area-tipos-de-lixo">
@if (Model != null)
{
foreach (var lixo in Model)
{
@Html.Partial("_LinhaTipoDeLixo", lixo);
}
}
</div>
Then I created Partiaview _Linhatipodelixo with the content:
@model IdentitySample.Models.PontoDeColetaTipoDeLixo
@using (Html.BeginCollectionItem("TipoDeLixo"))
{
<div class="form-group">
@Html.HiddenFor(model => model.Id)
@Html.HiddenFor(model => model.TipoDeLixoId)
<label class="col-md-1 control-label">Nome</label>
<div class="col-md-5">
@Html.TextBoxFor(model => model.TipoDeLixo.NomeTipoLixo, new { @class = "form-control", placeholder = "Nome" })
@Html.ValidationMessageFor(model => model.TipoDeLixo.NomeTipoLixo, "", new { @class = "text-danger" })
</div>
<div class="col-md-2">
<a class="btn red" onclick="$(this).parent().parent().remove();">Excluir</a>
</div>
</div>
}
And in Pontodecoletacontroller I created Action with the following content:
public ActionResult NovaLinhaDeTipoDeLixo()
{
return PartialView("_TiposDeLixo", new PontoDeColetaTipoDeLixo { Id = Guid.NewGuid() });
}
Then when I run the system, the following error appears:
The model item passed into the dictionary is of type 'IdentitySample.Models.PontoDeColeta', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[IdentitySample.Models.PontoDeColetaTipoDeLixo]'.
EDIT: I took a screen print with the error. CONTROLLER UPDATE Pontodecoletacontroller complete:
namespace IdentitySample.Controllers
{
public class PontosDeColetaController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
// GET: PontosDeColeta
public ActionResult Index()
{
return View();
}
public ActionResult NovaLinhaDeTipoDeLixo()
{
return PartialView("_LinhaTipoDeLixo", new PontoDeColetaTipoDeLixo { Id = Guid.NewGuid() });
}
//Lista os potos de coleta de acordo com parametros passados
public JsonResult Listar(string searchPhrase, int current = 1, int rowCount = 5)
{
var Identificacao = User.Identity.GetUserId().ToString();
var Pontos = (from u in db.PontoDeColeta
where u.UsuarioResponsavel == Identificacao
select u);
string Chave = Request.Form.AllKeys.Where(v => v.StartsWith("sort")).First();
string Ordenacao = Request[Chave];
string Coluna = Chave.Replace("sort[", String.Empty).Replace("]",String.Empty);
var Soma = Pontos.Count();
if (!String.IsNullOrWhiteSpace(searchPhrase))
{
Pontos = Pontos.Where("NomePopular.Contains(@0) OR Endereco.Contains(@0) OR Cidade.Contains(@0) OR Estado.Contains(@0) OR Apelido.Contains(@0)", searchPhrase);
}
string ColunaOrdenacao = String.Format("{0} {1}", Coluna, Ordenacao);
var PontoDeColetaPagina = Pontos.OrderBy(ColunaOrdenacao).Skip((current - 1) * rowCount).Take(rowCount);
return Json(new{
rows = PontoDeColetaPagina.ToList(),
current = current,
rowCount = rowCount,
total = Soma
}
, JsonRequestBehavior.AllowGet);
}
// GET: PontosDeColeta/Details/5
public ActionResult Details(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
PontoDeColeta pontoDeColeta = db.PontoDeColeta.Find(id);
if (pontoDeColeta == null)
{
return HttpNotFound();
}
return PartialView(pontoDeColeta);
}
// GET: PontosDeColeta/Create
public ActionResult Create()
{
var UsuarioLogado = new PontoDeColeta();
UsuarioLogado.UsuarioResponsavel = User.Identity.GetUserId();
return View(UsuarioLogado);
}
// POST: PontosDeColeta/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,NomePopular,Endereco,Cidade,Estado,Latitude,Longitude,Remuneracao,InfoAdicional,Ativo,Apelido,UsuarioResponsavel")] PontoDeColeta pontoDeColeta)
{
if (ModelState.IsValid)
{
pontoDeColeta.Id = Guid.NewGuid();
db.PontoDeColeta.Add(pontoDeColeta);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(pontoDeColeta);
}
// GET: PontosDeColeta/Edit/5
public ActionResult Edit(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
PontoDeColeta pontoDeColeta = db.PontoDeColeta.Find(id);
if (pontoDeColeta == null)
{
return HttpNotFound();
}
pontoDeColeta.UsuarioResponsavel = User.Identity.GetUserId();
return View(pontoDeColeta);
}
// POST: PontosDeColeta/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,NomePopular,Endereco,Cidade,Estado,Latitude,Longitude,InfoAdicional,Ativo,Apelido,UsuarioResponsavel")] PontoDeColeta pontoDeColeta)
{
if (ModelState.IsValid)
{
db.Entry(pontoDeColeta).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(pontoDeColeta);
}
// GET: PontosDeColeta/Delete/5
public ActionResult Delete(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
PontoDeColeta pontoDeColeta = db.PontoDeColeta.Find(id);
if (pontoDeColeta == null)
{
return HttpNotFound();
}
return PartialView(pontoDeColeta);
}
// POST: PontosDeColeta/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(Guid id)
{
PontoDeColeta pontoDeColeta = db.PontoDeColeta.Find(id);
db.PontoDeColeta.Remove(pontoDeColeta);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
I edited the question complementing everything I did based on your answer.
– Victor ProjetoFinal
@Victorprojetofinal Almost certain. See the expansion of my answer.
– Leonel Sanches da Silva
I made the change:
– Victor ProjetoFinal
I made the change:
@using (Html.BeginCollectionItem("PontosDeColetaTiposDeLixo"))
and still noticed that in the controller action was calling the wrong Partialview. The correct isreturn PartialView("_LinhaTiposDeLixo", new PontoDeColetaTipoDeLixo { Id = Guid.NewGuid() });
. But still the system has the same error. I have compared the whole code and saw nothing wrong.– Victor ProjetoFinal
Are you sure it’s this message, exactly written this way?
The model item passed into the dictionary is of type 'IdentitySample.Models.PontoDeColeta', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable
1[Identitysample.Models.Pontodecoletatipodelixo]'. ` I think the types are different. I need the new error message.– Leonel Sanches da Silva
I took a print now and edited the question. Are not the attributes of the classes? It’s the only difference I saw from your example.
– Victor ProjetoFinal
The error is clear. What you are passing to Partial is a variable of the type
PontoDeColeta
, And as much as the name is right, you’re not passingIEnumerable<PontoDeColetaTipoDeLixo>
. Edit your question and also enter the code for Controller.– Leonel Sanches da Silva
I put the complete controller code
– Victor ProjetoFinal
@Victorprojetofinal You fell into one of the most treacherous messages in ASP.NET MVC. See my issue.
– Leonel Sanches da Silva