jeudi 1 mai 2014

c# - liste de Checkbox dans ASP.NET MVC. Je ne peux pas récupérer les données d'une liste - Stack Overflow ou IEnumerable


I have a problem with an application using ASP.NET MVC 4, I'm trying to show in a view to create an entity called CompositePiece, a List of items (which are CompositePieces too) from my database, then, the user could select one or more of them, and the items selected would be in a collection in the 'father' CompositePiece, at first, my class CompositePiece:


namespace Garbi.Models{
public class CompositePiece
{
[Key]
public int CompositePieceId { get; set; }

[Required(ErrorMessage = "Introduzca un nombre para la pieza")]
[Display(Name = "Nombre de la pieza")]
public string CompositePieceName { get; set; }

public virtual ICollection<CompositePiece> Components { get; set; }

public int ProcessId { get; set; }
public int LevelOfHierarchy { get; set; }

public CompositePiece(PieceModel model)
{
this.Components = new List<CompositePiece>();
this.CompositePieceName = model.PieceModelName;
LevelOfHierarchy = 0;
}

public CompositePiece()
{
this.Components = new List<CompositePiece>();
LevelOfHierarchy = 0;
}

public CreateOrEditCompositePieceViewModel ToCreateOrEditCompositePieceViewModel(string processName)
{
return new CreateOrEditCompositePieceViewModel
{
CompositePieceName = this.CompositePieceName,
ProcessId = this.ProcessId,
ProcessName = processName
};
}
}
}

I have created a ViewModel to pass the data to a view, the ViewModel is:


namespace Garbi.ViewModels.CompositePieces
{
public class CreateOrEditCompositePieceViewModel
{

[Required(ErrorMessage = "Introduzca un nombre para la pieza")]
[Display(Name = "Nombre de la pieza")]
public string CompositePieceName { get; set; }

public virtual IEnumerable<SelectListItem> Components { get; set; }
public string[] SelectedComponentsId { get; set; }

public int ProcessId { get; set; }
public string ProcessName { get; set; }

public int LevelOfHierarchy { get; set; }

public void AddComponentsList(IEnumerable<CompositePiece> dataProvider, CompositePiece fatherPiece)
{
List<SelectListItem> auxList = new List<SelectListItem>();
foreach (CompositePiece piece in dataProvider)
{
SelectListItem item = new SelectListItem
{
Text=piece.CompositePieceName,
Value = piece.CompositePieceId.ToString(),
Selected = fatherPiece.Components.Contains(piece)
};
auxList.Add(item);
}
Components = new List<SelectListItem>(auxList);
}

public CompositePiece ToCompositePiece()
{
return new CompositePiece
{
CompositePieceName = this.CompositePieceName,
LevelOfHierarchy = this.LevelOfHierarchy,
ProcessId = this.ProcessId
};
}
}
}

Mi View is:


@model Garbi.ViewModels.CompositePieces.CreateOrEditCompositePieceViewModel

@{
ViewBag.Title = "Crear pieza compuesta";
}

<div class="advertise">Crear pieza compuesta para @Model.ProcessName</div>

@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)

<fieldset>
<legend>Nueva pieza compuesta</legend>


<div class="editor-label">
@Html.LabelFor(model => model.CompositePieceName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.CompositePieceName)
@Html.ValidationMessageFor(model => model.CompositePieceName)
</div>
<div class="editor-field">
@foreach (var item in Model.Components)
{
<div class="checkbox">
@Html.CheckBoxFor(i => item.Selected, item.Value)
@Html.HiddenFor(i => item.Value)
@item.Text
@Html.HiddenFor(i => item)
</div>
}
</div>

@Html.HiddenFor(model => model.Components)
@Html.HiddenFor(model => model.LevelOfHierarchy)
@Html.HiddenFor(model => model.ProcessId)
@Html.HiddenFor(model => model.ProcessName)

<p>
<input type="submit" value="Crear" />
</p>
</fieldset>

<div class="back">
@Html.NavLink("Process_"+@Model.ProcessId, "Page1", "Volver")
</div>
}

And at last, I want to show you the methods of my controller, they are:


public ActionResult ComposePieces(int processId)
{
context = new EFDbContext();
Process process = context.ProcessesPaginable.FindEntityById(processId);
CreateOrEditCompositePieceViewModel model = new CreateOrEditCompositePieceViewModel
{
ProcessId = process.ProcessId,
ProcessName = process.ProcessName,
LevelOfHierarchy = 0
};
IEnumerable<CompositePiece> totalPieces = context.CompositePiecesPaginable.FindAllCompositePiecesOfAProcess(processId).Where(p => p.LevelOfHierarchy == 0);
model.AddComponentsList(totalPieces, model.ToCompositePiece());
return View(model);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ComposePieces(CreateOrEditCompositePieceViewModel model)
{
context = new EFDbContext();
CompositePiece compositePieceToAdd = model.ToCompositePiece();
CompositePiece aux;
[...]
}

My problem comes when I call the view, I can see perfectly the collection of items, each of them with its checkbox, but when I check some of them, put the CompositePiece's name and click at Submit button, I recover the new CreateOrEditCompositePieceViewModel with its new name, but my attribute Components is empty. I think I am having a mistake of base, but I don't know where is the error, and why I have this problem.


Thank you for your time and sorry for my bad english.



I have a problem with an application using ASP.NET MVC 4, I'm trying to show in a view to create an entity called CompositePiece, a List of items (which are CompositePieces too) from my database, then, the user could select one or more of them, and the items selected would be in a collection in the 'father' CompositePiece, at first, my class CompositePiece:


namespace Garbi.Models{
public class CompositePiece
{
[Key]
public int CompositePieceId { get; set; }

[Required(ErrorMessage = "Introduzca un nombre para la pieza")]
[Display(Name = "Nombre de la pieza")]
public string CompositePieceName { get; set; }

public virtual ICollection<CompositePiece> Components { get; set; }

public int ProcessId { get; set; }
public int LevelOfHierarchy { get; set; }

public CompositePiece(PieceModel model)
{
this.Components = new List<CompositePiece>();
this.CompositePieceName = model.PieceModelName;
LevelOfHierarchy = 0;
}

public CompositePiece()
{
this.Components = new List<CompositePiece>();
LevelOfHierarchy = 0;
}

public CreateOrEditCompositePieceViewModel ToCreateOrEditCompositePieceViewModel(string processName)
{
return new CreateOrEditCompositePieceViewModel
{
CompositePieceName = this.CompositePieceName,
ProcessId = this.ProcessId,
ProcessName = processName
};
}
}
}

I have created a ViewModel to pass the data to a view, the ViewModel is:


namespace Garbi.ViewModels.CompositePieces
{
public class CreateOrEditCompositePieceViewModel
{

[Required(ErrorMessage = "Introduzca un nombre para la pieza")]
[Display(Name = "Nombre de la pieza")]
public string CompositePieceName { get; set; }

public virtual IEnumerable<SelectListItem> Components { get; set; }
public string[] SelectedComponentsId { get; set; }

public int ProcessId { get; set; }
public string ProcessName { get; set; }

public int LevelOfHierarchy { get; set; }

public void AddComponentsList(IEnumerable<CompositePiece> dataProvider, CompositePiece fatherPiece)
{
List<SelectListItem> auxList = new List<SelectListItem>();
foreach (CompositePiece piece in dataProvider)
{
SelectListItem item = new SelectListItem
{
Text=piece.CompositePieceName,
Value = piece.CompositePieceId.ToString(),
Selected = fatherPiece.Components.Contains(piece)
};
auxList.Add(item);
}
Components = new List<SelectListItem>(auxList);
}

public CompositePiece ToCompositePiece()
{
return new CompositePiece
{
CompositePieceName = this.CompositePieceName,
LevelOfHierarchy = this.LevelOfHierarchy,
ProcessId = this.ProcessId
};
}
}
}

Mi View is:


@model Garbi.ViewModels.CompositePieces.CreateOrEditCompositePieceViewModel

@{
ViewBag.Title = "Crear pieza compuesta";
}

<div class="advertise">Crear pieza compuesta para @Model.ProcessName</div>

@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)

<fieldset>
<legend>Nueva pieza compuesta</legend>


<div class="editor-label">
@Html.LabelFor(model => model.CompositePieceName)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.CompositePieceName)
@Html.ValidationMessageFor(model => model.CompositePieceName)
</div>
<div class="editor-field">
@foreach (var item in Model.Components)
{
<div class="checkbox">
@Html.CheckBoxFor(i => item.Selected, item.Value)
@Html.HiddenFor(i => item.Value)
@item.Text
@Html.HiddenFor(i => item)
</div>
}
</div>

@Html.HiddenFor(model => model.Components)
@Html.HiddenFor(model => model.LevelOfHierarchy)
@Html.HiddenFor(model => model.ProcessId)
@Html.HiddenFor(model => model.ProcessName)

<p>
<input type="submit" value="Crear" />
</p>
</fieldset>

<div class="back">
@Html.NavLink("Process_"+@Model.ProcessId, "Page1", "Volver")
</div>
}

And at last, I want to show you the methods of my controller, they are:


public ActionResult ComposePieces(int processId)
{
context = new EFDbContext();
Process process = context.ProcessesPaginable.FindEntityById(processId);
CreateOrEditCompositePieceViewModel model = new CreateOrEditCompositePieceViewModel
{
ProcessId = process.ProcessId,
ProcessName = process.ProcessName,
LevelOfHierarchy = 0
};
IEnumerable<CompositePiece> totalPieces = context.CompositePiecesPaginable.FindAllCompositePiecesOfAProcess(processId).Where(p => p.LevelOfHierarchy == 0);
model.AddComponentsList(totalPieces, model.ToCompositePiece());
return View(model);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ComposePieces(CreateOrEditCompositePieceViewModel model)
{
context = new EFDbContext();
CompositePiece compositePieceToAdd = model.ToCompositePiece();
CompositePiece aux;
[...]
}

My problem comes when I call the view, I can see perfectly the collection of items, each of them with its checkbox, but when I check some of them, put the CompositePiece's name and click at Submit button, I recover the new CreateOrEditCompositePieceViewModel with its new name, but my attribute Components is empty. I think I am having a mistake of base, but I don't know where is the error, and why I have this problem.


Thank you for your time and sorry for my bad english.


0 commentaires:

Enregistrer un commentaire