How to populate an array in side a model for postback - c#

I have a model that contains a List of Milestone, I want that list to be populated (inside the model) with a given set of Textboxes in the webpage.
public class Project
{
public string ProjectNumber { get; set; }
public IList<Parameter> Parameters;
public IList<Milestone> MilestoneList = new List<Milestone>();
}
And inside my Html.BeginForm("Edit", "Home", FormMethod.Post, new { Project = Model })) I have the following TextBox.
#for (int i = 0; i < Model.MilestoneList.Count; i++)
{
<td style="align-content: center;">#Html.TextBoxFor(model=>model.MilestoneList[i].Value)</td>
}
My problem in my controller below the milestonelist is always null in model Project
[HttpPost]
public ActionResult Edit(Project project)
{
helper.CreateProject(project, System.Web.HttpContext.Current.User.Identity.Name);
return View();
}
So how should I program so the list inside the model will be populated through TextBoxes?

Your using fields in the model, not properties, so the DefaultModelBinder cannot set the value. Change you model to
public class Project
{
public string ProjectNumber { get; set; }
public IList<Parameter> Parameters { get; set; }
public IList<Milestone> MilestoneList { get; set; }
}
and initialize the collection in in the controller.

Related

CheckBoxFor resetting the model to null in Razor

I'm iterating a list to set the values for multiple Html.CheckBoxFor controls, but after submitting the form, I get a null value for the model itself in the controller parameter. Should I replace Html.CheckBoxFor with Html.HiddenFor for instance, the whole model binding works and FunctionViewModel is passed to the controller properly.
Model
public class FunctionViewModel
{
//... (this class is huge)
public MeasuringViewModel MeasuringViewModel { get; set; }
}
Classes used by the model
public class MeasuringViewModel
{
//... (this class is also huge)
public List<BatchItem> BatchToCancel { get; set; }
}
public class BatchItem
{
public bool IsCancel { get; set; }
public VMeasuringService VMeasuringService { get; set; }
public BatchItem(VMeasuringService vMeasuringService)
{
IsCancel = false;
VMeasuringService = vMeasuringService;
}
}
Controller
[HttpPost]
public ActionResult CancelBatch(FunctionViewModel viewModel)
{
// viewModel is null should I use CheckBoxFor
return View();
}
Form
#using (Html.BeginForm("CancelBatch", "Services", FormMethod.Post, new { Area = "Functions", #id = "cancelForm" }))
{
for(int i = 0; i < Model.MeasuringViewModel.BatchToCancel.Count; i++)
{
#Html.CheckBoxFor(m => m.MeasuringViewModel.BatchToCancel[i].IsCancel)
}
<input type="submit" id="btSubmit" title="Post" alt="Post" value="Post" />
}
So, what's wrong with it?
You get null because none of the control ids matching with your model properties, Check by Inspecting your html in browser that, is control ids generated by Razor are matching with your model properties?
secondly in this situation where you cannot give specific ids to your controls then you can get your control value in your controller action using FormCollection like given bellow:
[HttpPost]
public ActionResult CancelBatch(FormCollection fc)
{
// viewModel is null should I use CheckBoxFor
return View();
}

Pass parameter from Htmldropdownlistfor to controller

I have a model passed from controller to view in my asp.net mvc5 website. Then I show the dropdownlist using the model and I want to pass an id back when submitting the form. Here is my model :
public class SiteDirectionModel
{
public int id { get; set; }
public string name { get; set; }
}
Then in the model, I use a List<SiteDirectionModel> to which I add new instances of each item I need. I fill up both these lists and then pass my model to the view.
#model List<SiteDirectionModel>
#using (Html.BeginForm("GetSiteRF", "Create", FormMethod.Post))
{
#Html.DropDownListFor(x => x.name,new SelectList(Model.name,"Sites"));
<input type="button" value="Selectionner" class="btn btn-primary"/>
}
Then how to retrieve the ids for each name ? And how to pass it as a parameter to my controller? Such that I would have :
public ActionResult GetSiteRF(int id)
{
int newId = id;
//Call method to searchId ...
return View("CreateADUser");
}
I have given how to bind and get value from dropdown. Please use your own BL in this.
Your model should be like this.
public class Something
{
public int Id { get; set; }
public string Name { get; set; }
}
public class SiteDirectionModel
{
public SelectList MyDropDown { get; set; }
public int SelectedValue { get; set; }
}
You BL should be like this.
public List<Something> GetListofSomething()
{
//your logic.
}
Your Get method should be like this.
public ActionResult MyGetMethod()
{
SiteDirectionModel model = new SiteDirectionModel();
model.MyDropDown = new SelectList(GetListofSomething(), "key_field_name", "value_field_name", "default_value");
}
Then finally HTML
#Html.DropDownListFor(x => x.SelectedValue,Model.MyDropDown)

Get selected CheckBox values in controller

I have a dormitory adding page and this dormitories can have features so I want to use CheckBox list for this.
There is a list of all features a dormitory can have.
public class DormFeatureModel
{
[Key]
public int FeatureID { get; set; }
public string FeatureName { get; set; }
public List<DormHasFeatureModel> DormHasFeature { get; set; }
}
Here, too, are features that a dormitory has.
public class DormHasFeatureModel
{
[Key]
public int HasFeatureID { get; set; }
[Required]
public int FeatureID { get; set; }
[Required]
public int DormID { get; set; }
public virtual DormModel Dorm { get; set; }
public virtual DormFeatureModel DormFeature { get; set; }
}
I can get features list in razor as checkbox
but I can't get selected checkboxes id list(so, FeatureID)
How can I get list in controller ?
First, add a ViewModel that correlates the Checked boolean with the FeatureId.
public class SelectedFeatureViewModel {
public bool Checked { get; set; } // to be set by user
public int FeatureID { get; set; } // to be populated by GET action
public string FeatureName { get; set; } // to be populated by GET action
}
The GET action creates the main ViewModel and initializes the list of available features (DormOptions).
public class CreateDormViewModel {
// used to render the checkboxes, to be initialized in GET controller action
// also used to bind the checked values back to the controller for POST action
public ICollection<SelectedFeatureViewModel> DormOptions { get; set; }
}
In the Razor markup, bind the checkboxes to the DormOptions collection:
#model CreateDormViewModel
#using (Html.BeginForm("CreateDorm", "DormAdministration", FormMethod.Post)) {
// use for loop so modelbinding to collection works
#for (var i = 0; i < Model.DormOptions.Count; i++) {
<label>#Model.DormOptions[i].FeatureName</label>
#Html.CheckBoxFor(m => m.DormOptions[i].Checked)
// also post back FeatureId so you can access it in the controller
#Html.HiddenFor(m => m.DormOptions[i].FeatureID)
// post back any additional properties that you need to access in the controller
// or need in order to redraw the view in an error case
#Html.HiddenFor(m => m.DormOptions[i].FeatureName)
}
}
In the CreateDorm POST action, the checkbox values are bound to the ViewModel property you gave in the CheckBoxFor lambda, i.e. the Checked property in the DormOptions collection.
[HttpPost]
public ActionResult CreateDorm(CreateDormViewModel postData) {
var selectedFeatureIds = new List<int>();
foreach (var option in postData.DormOptions) {
if (option.Checked) {
selectedFeatureIds.Add(option.FeatureID);
}
}
// ...
}
You can get the list by using the name of the checkboxes, let say your name of the checkboxes is chklstfeatureid then in controller you can get list like below
public actionresult createdorm(list<int> chklstfeatureid)
{
}
Thanks

Dynamically generated drop down list using #html.dropdownlistfor helper in mvc 4 loosing selection of items on page post back

I am very new in MVC, however i am able to display and get proper value at Controller from dynamically generated DropdownList using #html.dropdownlistfor helper (with Razor View Engine), but getting problem to return view with selected dropdownlist items on post back.
Following my Code:
Model:
public class CollectionViewModel
{
public List<TempAccount> temp { get; set; } // for Prepare UI
public List<Trn_Loans> colls { get; set; }
[Display(Name="Date")]
public DateTime TrnDate { get; set; }
public int TrnTypesId { get; set; }
public string expectedReceiveableAmount { get; set; }
public int ReqRouteNumber { get; set; }
}
View:
#model SFSW.ViewModels.CollectionViewModel
#Html.DropDownListFor(m => m.colls[i].Executive1Id, (IEnumerable<SelectListItem>)ViewBag.ExecutiveDDN1, String.Empty)
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CollectionViewModel modelCollection)
{
....on ModelState.false
ViewBag.ExecutiveDDN1 = new SelectList(db.ddl_VerifiedBy, "ddl_VerifiedById", "Name", String.Empty);
return View(modelCollection);
}
Proper ID in #Model.colls[i].Executive1Id is coming upto postback view but dropdownlist itmes not selects from this this ID.
thanks for any help.

How to Pass Details Model from Controller to View

I am accessing Data in Controller using a WCF Service.
public ActionResult Index()
{
DataRerieveClient _proxy = new DataRerieveClient();
var orderDetails = _proxy.GetProductDetails(null);
return View();
}
Now how to pass the orderdetails from Controller to view and how to access them in View.
Edit:
I have a Model :
public class OrderDetails
{
public int OrderId { get; set; }
public int ProductId { get; set; }
public decimal UnitPrice { get; set; }
public int quanity { get; set; }
public decimal Discount { get; set; }
}
and _proxy.GetProductDetails(null) returns List<ServiceType.OrderDetails>
Do I need a Local Model at all in this scenario?
How do I display the List values in a table in my view?
Edit2:
public class AutoMapperConfig
{
public static void Configure()
{
Mapper.Map(ServiceOrders.OrderDetails, NorthWindMVCWCF.Models.OrderDetails);
}
}
Now getting the Error
'NorthWindMVCWCF.ServiceOrders.OrderDetails' is a 'type', which is not valid in the given context
'NorthWindMVCWCF.Models.OrderDetails' is a 'type', which is not valid in the given context
I prefer to create view models, I would do it as follows:
Create View Models
public class OrderDetailViewModel
{
public int OrderId { get; set; }
public int ProductId { get; set; }
public decimal UnitPrice { get; set; }
public int Quanity { get; set; }
public decimal Discount { get; set; }
}
public class OrderDetailsViewModel
{
public OrderDetailsViewModel()
{
OrderDetails = new List<OrderDetailsViewModel>();
}
public List<OrderDetailsViewModel> OrderDetails { get; set; }
}
Manual projection
You could create an OrderDetails view model and project an instance manually as follows:
var orderDetailsViewModel = new OrderDetailsViewModel();
foreach(var orderdetail in orderDetails)
{
orderDetailsViewModel.Add(new OrderDetailsViewModel { OrderId = orderDetail.OrderId, ProductId = orderDetail.ProductId, UnitPrice = orderDetail.UnitPrice, Quanity = orderDetail.quantity, Discount = orderDetail.Discount });
}
AutoMapper alternative projection
Install AutoMapper, run the following from the package manager console:
Install-Package AutoMapper
Create an AutoMapperConfig.cs in the App_Start folder with the mappings, similar to below:
public static class AutoMapperConfig
{
public static void Configure()
{
Mapper.CreateMap<OrderDetails, OrderDetailViewModel>();
}
}
In your global asax call the configure method:
protected void Application_Start()
{
...
AutoMapperConfig.Configure();
...
}
Then map in your controller:
var orderDetailsViewModel = new OrderDetailsViewModel();
orderDetailsViewModel.OrderDetails = Mapper.Map<List<OrderDetails>, List<OrderDetailsViewModel>>(orderDetails);
I prefer to use the AutoMapper approach as the mapping is defined globally and can be reused within your app.
Returning your view model
Your view model would then be passed back as follows:
return View(orderDetailsViewModel);
Razor output
You access it in your view by adding a model reference at the top:
#model OrderDetailsViewModel
Then output the properties as follows, I've only included OrderId but you can just add the fields the same way:
<table>
<tr>
<th>OrderId</th>
</tr>
#foreach(var orderDetail in Model.OrderDetails)
{
<tr>
<td>#orderDetail.OrderId</td>
</tr>
}
</table>
You have create ViewModel for that.
For example in your model folder create a class:
public class MyViewModel // Whatever name you want to give
{
//My fields which I want to pass to View
publis string Field1{get;set;}
etc
etc
}
public ActionResult Index()
{
DataRerieveClient _proxy = new DataRerieveClient();
var orderDetails = _proxy.GetProductDetails(null);
List<MyViewModel> viewModelList = new List<MyViewModel>();
foreach(var orderDetail in orderDetails)
{
MyViewModel viewModel = new MyViewModel(); //Create an object of your ViewModel
viewModel.Field1 = orderDetails.Field1; //set all feilds like that
viewModelList.Add(viewModel);
}
return View(viewModelList); // Pass View Model to View
}
Note: You have to create View for your ViewModel
Like
#model `List<MyViewModel>`
then use this ViewModel to access properties.
To know more about what is ViewModel, refer to the link below:
http://sampathloku.blogspot.ae/2012/10/how-to-use-viewmodel-with-aspnet-mvc.html
in the Controller class write :
public ActionResult Index()
{
DataRerieveClient _proxy = new DataRerieveClient();
var orderDetails = _proxy.GetProductDetails(null);
return View(orderDetails);
}
i assume your project name is MvcApplication2 and your class name is in Model Folder. so add follow code in top of View (sample.cshtml) :
#model MvcApplication2.Models.OrderDetail
ok , you can use this code to access properties of DataRecieveClient :
<div class="display-label">
#Html.DisplayNameFor(model => model.F1)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.F1)
</div>
Sorry for poor english.!

Categories

Resources