Submit form with Get method in MVC3? - c#

I have the following form:
#model Teesa.Models.SearchModel
#using (Html.BeginForm("Index", "Search", FormMethod.Get, new { id = "SearchForm" }))
{
<div class="top-menu-search-buttons-div">
#if (!MvcHtmlString.IsNullOrEmpty(Html.ValidationMessageFor(m => m.SearchText)))
{
<style type="text/css">
.top-menu-search-text
{
border: solid 1px red;
}
</style>
}
#Html.TextBoxFor(q => q.SearchText, new { #class = "top-menu-search-text", id = "SearchText", name = "SearchText" })
#Html.HiddenFor(q=>q.Page)
<input type="submit" value="search" class="top-menu-search-submit-button" />
</div>
<div id="top-menu-search-info" class="top-menu-search-info-div">
Please Select one :
<hr style="background-color: #ccc; height: 1px;" />
<div class="top-menu-search-info-checkbox-div">
#Html.CheckBoxFor(q => q.SearchInBooks, new { id = "SearchInBooks", name = "SearchInBooks" })
<label for="SearchInBooks">Books</label>
</div>
<div class="top-menu-search-info-checkbox-div">
#Html.CheckBoxFor(q => q.SearchInAuthors, new { id = "SearchInAuthors" })
<label for="SearchInAuthors">Authors</label>
</div>
<div class="top-menu-search-info-checkbox-div">
#Html.CheckBoxFor(q => q.SearchInTags, new { id = "SearchInTags" })
<label for="SearchInTags">Tags</label>
</div>
}
and the following Controller and Models :
namespace Teesa.Models
{
public class SearchModel
{
[Required(ErrorMessage = "*")]
public string SearchText { get; set; }
public bool SearchInTags { get; set; }
public bool SearchInAuthors { get; set; }
public bool SearchInBooks { get; set; }
public int Page { get; set; }
public List<SearchBookModel> Result { get; set; }
public List<SimilarBookModel> LatestBooks { get; set; }
}
public class SearchBookModel
{
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public string Summary { get; set; }
public List<Tags> Tags { get; set; }
public string StatusName { get; set; }
public string SubjectName { get; set; }
public string ThumbnailImagePath { get; set; }
public string BookRate { get; set; }
public string RegistrationDate { get; set; }
public int NumberOfVisit { get; set; }
}
}
[HttpGet]
public ActionResult Index(SearchModel model)
{
FillSearchModel(model);
if (ModelState.IsValid)
{
string page = model.Page;
DatabaseInteract databaseInteract = new DatabaseInteract();
model.Result = new List<SearchBookModel>();
List<Book> allBooks = databaseInteract.GetAllBooks();
List<Book> result = new List<Book>();
#region
if (model.SearchInTags)
{
var temp = (from item in allBooks
from tagItem in item.Tags
where tagItem.Name.Contains(model.SearchText)
select item).ToList();
result.AddRange(temp);
}
if (model.SearchInBooks)
{
var temp = (from item in allBooks
where item.عنوان.Contains(model.SearchText)
select item).ToList();
result.AddRange(temp);
}
if (model.SearchInAuthors)
{
var temp = (from item in allBooks
where item.Author.Contains(model.SearchText)
select item).ToList();
result.AddRange(temp);
}
#endregion
#region Paging
string itemsPerPage = databaseInteract.GetItemsPerPage();
int ItemInPage = int.Parse(itemsPerPage);
var pagingParams = Helpers.SetPagerParameters(page, ItemInPage, result);
ViewBag.AllPagesCount = pagingParams.AllPagesCount;
ViewBag.CurrentPageNumber = pagingParams.CurrentPageNumber;
ViewBag.CountOfAllItems = pagingParams.CountOfAllItems.ToMoneyFormat().ToPersianNumber();
result = pagingParams.ListData as List<Book> ?? result;
#endregion
foreach (var item in result)
{
var bookRate = (item.BookRate == null || item.BookRate.Count == 0)
? 0.0
: item.BookRate.Average(q => q.Rate);
model.Result.Add(new SearchBookModel
{
Author = item.Author,
Id = item.Id,
.
.
.
});
}
}
else
{
model.Result = new List<SearchBookModel>();
}
return View(model);
}
When I submit the form I see the following query strings(Notice the duplicate names) :
http://localhost:2817/Search?SearchText=book&Page=2&SearchInBooks=true&SearchInBooks=false&SearchInAuthors=true&SearchInAuthors=false&SearchInTags=true&SearchInTags=false
But it has to be something like this :
http://localhost:2817/Search?SearchText=book&Page=2&SearchInBooks=true&SearchInAuthors=true&SearchInTags=true
How can I fix it ?
Thanks

Html.Checkbox (and the related For... methods) generate a hidden input for false, and the checkbox for true. This is to ensure that model binding works consistently when binding.
If you must get rid of "false" items resulting from the hidden inputs, you'll need to construct the checkbox inputs yourself (using HTML and not the helper).
<input type="checkbox" id="SearchInBooks" name="SearchInBooks">

Why dont your create a Post Method with a matching name to the Get method. This will ensure that the code is much easier to debug. As you will not have a huge function to go through trying to find problems like this.
I cannot find a where your getting the duplicate url query strings from though.
This will also allow you to bind your results back to the model.

If you want the model binding to happen successfully then you have to go with this way because that is the nature of the Html.CheckBox/Html.CheckBoxFor methods they will render a hidden field as well.
I would suggest rather go with POST to make your life easy. If you still want to use GET then you have to use checkbox elements directly but you have to take care of the model binding issues. Not all the browsers returns "true" when the checkbox is checked for ex. firefox passes "on" so the default model binder throws an error.
Other alternate options is you can go for custom model binder or you can submit the form using jquery by listening to the submit event.

Related

Mixed up my Two Models, Null Reference in Post Request (ASP.NET MVC)

I'm trying to present a table with a list of rows from the database, as well as a small form option for the user to add an additional db row. I made two Models in order to both hold the table rows and capture the form. I'm not having problems with the table model, just the form model.
So I'm confident the problem is in my Controller; I am new to MVC and this is the first time I've seen two models in the same VM... I've been going back and forth making small changes to things, but I keep getting a Null Reference Error in my Controller.
VM:
namespace User.ViewModel
{
public class UploadDocumentTemplatesViewModel
{
public string TemplateName { get; set; }
public string Comments { get; set; }
}
public class TemplateModel
{
public UploadDocumentTemplatesViewModel NewTemplate { get; set; }
public List<UploadDocumentTemplatesViewModel> Templates { get; set; }
}
}
View (UploadDocumentTemplates.cshtml):
#using (Html.BeginForm("AddNewTemplate", "User", FormMethod.Post, new { enctype = "multipart/form-data", id = "NewTemplateForm"}))
{
#Html.AntiForgeryToken()
<div>
<input type="text" class="form-control" rows="5" id="TemplateName" value="#Model.NewTemplate.TemplateName">
<label for="comments">Comments:</label>
<textarea class="form-control" rows="5" id="comments" name="#Model.NewTemplate.Comments"></textarea>
<button id="AddTemplate" onclick="AddNewTemplate()" name="Add Template">Add Template</button>
</div>
}
<table>
<tbody>
#{ foreach (var template in Model.Templates)
{
<tr id="tr_#template.DocumentTemplateId">
<td>#template.TemplateName</td>
<td>#template.Comments </td>
<td>#template.IsActive </td>
}
<script>
function AddNewTemplate() {
$("#NewTemplateForm").submit();
}
</script>
Controller:
public class UserController : Controller
{
public ActionResult UploadDocumentTemplates()
{
var model = entity.DocumentTemplates.Select(x => new UploadDocumentTemplatesViewModel()
{
DocumentTemplateId = x.DocumentTemplateId,
TemplateName = x.TemplateName,
Comments = x.Comments,
});
var _obj = new TemplateModel();
var templatelist = _entities.GetTemplates();
_obj.Templates = new List<UploadDocumentTemplatesViewModel>();
foreach (var template in templatelist)
{
_obj.Templates.Add(new UploadDocumentTemplatesViewModel()
{
TemplateName = template.TemplateName,
Comments = template.Comments,
});
}
_obj.NewTemplate = new UploadDocumentTemplatesViewModel();
return View(_obj);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddNewTemplate(TemplateModel vModel)
{
var template = new DocumentTemplates();
template.TemplateName = vModel.NewTemplate.TemplateName;
template.Comments = vModel.NewTemplate.Comments;
entity.DocumentTemplates.Add(template);
entity.SaveChanges();
return View("~/User/UploadDocumentTemplates.cshtml", vModel);
}
}
I hit a Null Reference at this line in my Post method in the Controller:
template.TemplateName = vModel.NewTemplate.TemplateName;
The vModel.NewTemplate.TemplateName is null. Can anyone help me with this?
Thank you so much!
SOLUTION:
The NRE did get fixed with Andy's help (see answer). My further issue was fixed after I populated the new VM with the fields I was using in my form.
namespace Example.Areas.ViewModel
{
public class UploadDocumentTemplatesViewModel
{
public long DocumentTemplateId { get; set; }
public string TemplateName { get; set; }
public string Comments { get; set; }
}
public class TemplateModel
{
public string TemplateName { get; set; }
public string Comments { get; set; }
public HttpPostedFileBase TemplateFile { get; set; }
public List<UploadDocumentTemplatesViewModel> Templates { get; set; }
}
}
In the controller I populated the TemplateModel and sent that to the View:
public ActionResult UploadDocumentTemplates()
{
var templateList = Repository.GetTemplates();
var _obj = new TemplateModel
{
Templates = templateList.Select(x => new UploadDocumentTemplatesViewModel()
{
DocumentTemplateId = x.DocumentTemplateId,
TemplateName = x.TemplateName,
Comments = x.Comments
}).ToList()
};
return View(_obj);
}
Then I put #using Example.Areas.ViewModel.TemplateModel on my View and used Model.Templates for the table, and Model.TemplateName and Model.Comments in the form.
Add a breakpoint in the line where you hit the Null Reference and check if vModel.NewTemplate has a valid instance.
You can add a constructor in TemplateModel class to create a new instance of UploadDocumentTemplatesViewModel()
namespace User.ViewModel
{
public class UploadDocumentTemplatesViewModel
{
public string TemplateName { get; set; }
public string Comments { get; set; }
}
public class TemplateModel
{
public TemplateModel()
{
NewTemplate = new UploadDocumentTemplatesViewModel();
}
public UploadDocumentTemplatesViewModel NewTemplate { get; set; }
public List<UploadDocumentTemplatesViewModel> Templates { get; set; }
}
}
OR
create an instance after instantiating template:
var template = new DocumentTemplates();
template.NewTemplate = new UploadDocumentTemplatesViewModel();

Adding comment to post in ASP.NET MVC

EDIT: I am trying to add a comment to a post in my mvc application but my action does not seem to work. When I reach the Action I want to pass on an Id from a Post (the Id from the table/model FormalBlog) but the newPost.Post = model.Post is null and when the action reaches the db.SaveChanges it throws an System.Data.Entity.Validation.DbEntityValidationException.
Below is my action and my PostIndexViewModel:
public ActionResult Comment(PostIndexViewModel model, FormalBlog Post)
{
var userName = User.Identity.Name;
var author = db.Users.SingleOrDefault(x => x.UserName == userName);
Comment newPost = new Comment();
newPost.Author = author;
newPost.Text = model.Text;
newPost.Post = model.Post;
db.Comments.Add(newPost);
db.SaveChanges();
return RedirectToAction("ShowBlogs", "Blog");
}
}
public class PostIndexViewModel
{
public string Id { get; set; }
public ICollection<FormalBlog> FormalBlogs { get; set; }
public FormalBlog NewFormalBlog { get; set; } = new FormalBlog();
public Category NewCategory { get; set; } = new Category();
public ICollection<Category> Categories { get; set; }
public List<SelectListItem> SelectedCategories { get; set; }
public int[] CategoryIds { get; set; }
public Category CategoryN { get; set; }
public ICollection<Meeting> Meetings { get; set; } //testrad
// public int Id { get; set; }
public string Text { get; set; }
public ApplicationUser Author { get; set; }
public Comment NewComment { get; set; }
public FormalBlog Post { get; set; }
}
and here is the code for my view:
#model XP_Scrum_Grupp2.Controllers.PostIndexViewModel
#using (Html.BeginForm("Comment", "Blog", new { formal = Model }, FormMethod.Post, new { id = Model.Id }))
{
<div class="comment-form-container">
<form class="comment-form" data-action="#Url.Action("Comment", "Blog")">
#Html.HiddenFor(m => m.Id)
<div>#Html.DisplayFor(m => m.Author)</div>
<div>
<div>#Html.LabelFor(m => m.Text)</div>
#Html.TextAreaFor(m => m.Text, new { Class = "comment-text", rows = "3", cols = "50" })
</div>
<div class="comment-result" style="display: none;">
<span class="comment-result-text">An error occurred</span>
</div>
<div>
<button type="submit" class="comment-form-submit">Submit comment</button>
</div>
</form>
</div>
}
Your view does not assign any value to model.NewComment. So when you access model.NewComment.Text it will throw Null reference exception since model.NewComment is null.
You assign new text to model's Test property. So you should use model.Text instead of model.NewComment.Text
public ActionResult Comment(PostIndexViewModel model)
{
var userName = User.Identity.Name;
var author = db.Users.SingleOrDefault(x => x.UserName == userName);
Comment newPost = new Comment();
newPost.Author = author;
newPost.Text = model.Text;
newPost.Post = model.Post;
db.Comments.Add(newPost);
db.SaveChanges();
return RedirectToAction("ShowBlogs", "Blog");
}
You are not posting the any data as model.NewComment.Text so the error occures because of NewComment object is null.
#Html.TextAreaFor(m => m.Text, new { Class = "comment-text", rows = "3", cols = "50" })
So, try to change it;
newPost.Text = model.NewComment.Text;
to
newPost.Text = model.Text;

Checkbox List in ASP.NET MVC. I cant retrieve data to a IEnumerable or List

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 also have the same Problem as you do.
When I get the postback, the Navigation properties are not returning, even thought I select them on the form, or hid them.
I think this Problem has to do with the Attribute being virtual, and by so it uses lazy loading.
One Thing that I tried that showed promising, but still did^'t get the Job done is if you add the:
#Html.HiddenFor(model => Model.Components);
Before your foreach Loop.
What happens is that when you look on you postback, you will find the components there, it won't be null anymore, but still the list will be empty, but I think the solution is on this direction.
Anyways, enough of this.
I'm about to do a way around this that should work.
What you do, you create a viewmodel
with your class
plus list of each of the virtual lists
something like this:
public class MyViewModel
{
public MyModelView(CompositePiece cp)
{
CompositePiece = cp;
Components = cp.Components.ToList();
}
public CompositePiece CompositePiece { get; set; }
public List<Component> Components { get; set; }
}
I just saw that on your class you create a list of itself, you probably shouldn't do that.
That's not how you create linked lists in C#
So, if instead you do like this example, you will create an instance of you virtual lists, and this should solve the Problem.
Good luck.

Creating a dropdown in MVC3 C# with ViewModel and easy model binding on POST back.

I have this problem where i want to make 7 dropdowns for each day of the week.
In each one of those dropdowns i wish to add the same data.
My ViewModel:
public class WeekDienstCreateViewModel
{
public WeekDienst weekDienst {get; set;}
public List<DienstPerWeekDienst> diensten { get; set; }
public WeekDienstCreateViewModel() { }
}
My Create Method in Controller:
As u can see I add everything allready except DienstId which is want to add with my dropdowns.
public ActionResult Create(int id)
{
WeekDienst wd = _service.FindWeekDienst(id);
WeekDienstCreateViewModel vm = new WeekDienstCreateViewModel();
vm.diensten = new List<DienstPerWeekDienst>();
vm.weekDienst = wd;
for (int i = 1; i <= 7; i++)
{
DienstPerWeekDienst dpwd = new DienstPerWeekDienst();
dpwd.volgnummer = i;
dpwd.WeekDienstId = wd.Id;
vm.diensten.Add(dpwd);
}
ViewBag.Diensten = _service.DienstenList(wd.AfdelingId);
return View(vm);
}
Classes:
public class DienstPerWeekDienst
{
[Key]
public int Id { get; set; }
[Required]
public int WeekDienstId { get; set; }
[Required]
public int DienstId { get; set; }
[Required]
[Range(1, 7)]
public int volgnummer { get; set; }
[ForeignKey("WeekDienstId")]
public virtual WeekDienst WeekDienst { get; set; }
[ForeignKey("DienstId")]
public virtual Dienst Dienst { get; set; }
public virtual ICollection<WeekDienst> WeekDiensten { get; set; }
}
public class WeekDienst
{
[Key]
public int Id { get; set; }
[Required]
public int AfdelingId { get; set; }
[Required]
[StringLength(5, ErrorMessage = "Value for {0} cannot exceed {1} characters.")]
[RegularExpression(#"^[a-zA-Z0-9]{5}$", ErrorMessage = "Verplicht 5 cijfers lang.")]
public string code { get; set; }
[DisplayName("Template")]
public bool template { get; set; }
[ForeignKey("AfdelingId")]
public virtual Afdeling Afdeling { get; set; }
}
And in my view i wish to create 7 dropdowns where i put in all my "Diensten" (class Dienst, fk in DienstPerWeekDienst). When I choose 1 i wish to add the "DienstId" into the "DienstPerWeekDienst" class.
So in my View i got this:
#foreach (var day in Model.diensten)
{
var currentDay=day;
#Html.DropDownListFor(currentDropDown=>currentDay, new SelectList(ViewBag.Diensten, "Value", "Text"))
}
I Wish to postback the chosen "Diensten" and create the "WeekDienst" but now i am just posting a null "DienstPerDienstWeekCreateViewModel". How am I able to fix this?
Thanks in Advance
FIX (Thanks to Siva Gopal)
I fixed this by doing:
#for (int i = 0; i < #Model.diensten.Count; i++)
{
#Html.HiddenFor(m => (m.diensten[i].volgnummer))
#Html.HiddenFor(m => (m.diensten[i].WeekDienstId))
#Html.DropDownListFor(m=> (m.diensten[i].DienstId), new SelectList(ViewBag.Diensten, "Value", "Text"))
}
You may try using
#foreach (var day in Model.diensten)
{
var currentDay=day;
#Html.DropDownListFor(currentDropDown=>currentDay, new SelectList(ViewBag.Diensten, "PropertyName_Holding_Value", "PropertyName_Holding_DisplayText"), new { })
} //This uses the Lambda Expression. Your dropdown Name/Id would be 1,2,3 etc. based on currentDay value.
OR
#foreach (var day in Model.diensten)
{
var currentDay=day;
var dropdownName=string.Format("diensten[{0}]",day-1); //If you want to model bind the selected dropdown value to input entity in POST request. The final dropdownName format should match the hierarchy of the property inside input entity/object. Even without this name formation, you can still POST the selected value back using Jquery/Javascript.
#Html.DropDownList(dropdownName, new SelectList(ViewBag.Diensten, "PropertyName_Holding_Value", "PropertyName_Holding_DisplayText"), new {})
} //
Note for Value Post back/model bind on full Page submit:
To be able to model bind/POST back values to the server, the html element names corresponding to the properties should be rendered as follows: Suppose if you display Employee.Department.Name, then name of textbox, displaying the Department Name in View should match Department_ReferenceName_Inside_Employee.Name for model binding.
Model:
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
public Department EmpDepartment { get; set; }
public List SubOrdinates { get; set; }
}
public class Department
{
public string Name { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
//Prepare the model and send it to the view
Employee emp = new Employee { EmpDepartment = new Department { Name = "IT" } };
emp.SubOrdinates = new List<Employee> { new Employee { Name = "Emp1" }, new Employee { Name = "Emp2" } };
return View(emp);
}
[HttpPost]
public ActionResult Index(Employee emp)
{ //Put a break-point here and see how the modified values in view are flowing into emp..
return View(emp);
}
public ActionResult About()
{
return View();
}
}
View:
#model MvcApplication.Models.Employee
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.EmpDepartment.Name)
#Html.LabelForModel("SubOrdinates :")
for (int i = 0; i < #Model.SubOrdinates.Count; i++)
{
#Html.TextBoxFor(m => (m.SubOrdinates[i].Name))
}
<input type="submit" name="name" value="Submit" /> }
ViewSource/PageSource:
The above text box syntax will be rendered as :
<input id="EmpDepartment_Name" name="EmpDepartment.Name" type="text" value="IT" /> <!--See above html : name=EmpDepartment.Name -->
<label for="">SubOrdinates :</label>
<input id="SubOrdinates_0__Name" name="SubOrdinates[0].Name" type="text" value="Emp1" />
<input id="SubOrdinates_1__Name" name="SubOrdinates[1].Name" type="text" value="Emp2" /> <!--See above html for how collection item Name(s) are being renderd by view engine-->
<input type="submit" name="name" value="Submit" />
#foreach (var day in Model.diensten)
{
var currentDay = day;
#Html.DropDownListFor(x => currentDay, new SelectList(ViewBag.Diensten, "Value", "Text"), new { #id = "DienstList" })
}
List<MvcApplication1.Models.Country> cntry = db.Countries.ToList();
SelectListItem sss = new SelectListItem();
List<SelectListItem> sltst = new List<SelectListItem>();
sss.Text = "Select";
sss.Value = "0";
sltst.Add(sss);
foreach (MvcApplication1.Models.Country s in cntry){
SelectListItem s1 = new SelectListItem();
s1.Text = s.Country1;
s1.Value = Convert.ToString(s.Id);
sltst.Add(s1);}
#Html.DropDownList("country", sltst, new { #id = "country" })

MVC template editor how to display items from two model

I hope I explain this correctly..
What I am trying to do is build up a session array with a list of products in.
Then display these on a form in text boxes with quantiles next to them and be able to submit them. I think I need to use template editor. But I don't know how to put data into the list of items.
This is how my session variable is currently being populated..
IList<EnqProduct> items2 = Session["enquiry"] as IList<EnqProduct>;
desc = desc.Replace(",", "");
EnqProduct item = new EnqProduct();
item.Id = (items2.Count + 1).ToString();
item.Product = desc;
item.Quantity = "0";
items2.Add(item);
So desc, can be productone, product two etc.
Enquiry Product model:
namespace MvcEditorTemplates.Models
{
public class EnqProduct
{
public string Id { get; set; }
public string Product { get; set; }
public string Quantity { get; set; }
}
}
Normal Enquiry Model:
public class Enquiry
{
public List<EnqProduct> EnqProduct { get; set; }
}
How i am trying to populate the model, but this is static. I need it to be populated from the array items:
var EnquiryModel = new Enquiry {
EnqProduct = items2.Select(c => new EnqProduct()
{
Quantity = c.Quantity,
Product = c.Product
})
};
Enquiry product template view:
#model MvcEditorTemplates.Models.EnqProduct
<div class="fl">
<p>
#Html.LabelFor(x => x.Product)
#Html.TextBoxFor(x => x.Product)
</p>
<p>
#Html.LabelFor(x => x.Quantity)
#Html.TextBoxFor(x => x.Quantity)
</p>
</div>
This is how im trying to get it to be displayed din the view:
#Html.EditorFor(model => model.EnqProduct)
EDIT:
at items2.Select(c => new EnqProduct()
i get a IEnumerbale error something about cast?
Try something like this:
public class ErrorMessage
{
public DateTime ErrorDate { get; set; }
public string ErrorText { get; set; }
public int DexRowId { get; set; }
}
public class Transaction
{
public string TransactionType { get; set; }
public string Processed { get; set; }
public DateTime UpdateDate { get; set; }
public int DexRowID { get; set; }
public string Text { get; set; }
}
public class Result
{
public List<ErrorMessage> errorMessageList { get; set; }
public List<Transaction> transactionList { get; set; }
}
In your controller:
List<Transaction> transactionList = ...;//query to populate your list;
List<ErrorMessage> errorMessageList = ...;//query to populate your list;
Result result = new Result();
result.ErrorMessageList = errorMessageList;
result.TransactionList = transactionList;
return View(result);
and in your view:
#model Models.Result
#{
ViewBag.Title = "Result";
Layout = "~/Views/Shared/_ResultLayout.cshtml";
}
EDIT:
#model IENumerable<MvcEditorTemplates.Models.EnqProduct>
#{
foreach( EnqProduct ep in #model)
{
.... your code comes here.........
}
}

Categories

Resources