retain values on postback in Asp.net mvc - c#

I have a data in following pattern;
as shown in image attached,
I want to repopulate all these values and controls on Postback.
I am using asp.net MVC
If i should use a list then how can i tackle the multiple values of subject to be saved in one column but on view displayed in different column
currently using forms collection:
int rows=request.Form["rows"];
int colmn=requst.form["comn"];
var list1=new list<mymodel>{
new mymodel {}}
;
for (var row = 1; row <= noOfRows; row++)
{
list1.Add(new mymodel()
{
name= Request.Form["name-row"].ConvertToInt()
rollno= Request.Form["rollno-row"].ToString(),
});
for (int colmn = 1; colmn <= noOfColmns - 1; colmn++)
{
list1.Add(new mymodel()
{
subject = Request.Form["subj-row-colmn"].ConvertToInt()
});
}
}
let me know if something else is needed
Important Note:
I think i am not able to explain what i want,so i have narrowed a problem ,
To be more precise i have created a list ,i have populated a list
as
var list1=new list<mymodel>{
new mymodel {}}
list1.Add(new mymodel()
{
name= Request.Form["name-row"].ConvertToInt(),
rollno= Request.Form["rollno-row"].ToString(),
subj=new list{}
});
,now i want to loop through this list to get all my values back
in the given format.
Q:how to get values from this list using loop(foreach or for) in the desired format?

You will need to bind values to a view model, i.e., List<MyVM> vm on postback. Then, each view model needs to keep a state for the CRUD. It can be a simple key / value pair, like:
public class MyVM
{
#region Properties
#endregion
public Dictionary<string, VMState> States;
}
public class VMState
{
public bool Create { get; set; }
public bool Read { get; set; }
public bool Update { get; set; }
public bool Delete { get; set; }
}

Related

How do I dynamically assign a value to an MVC grid based on the value from another column in the row

I have a dataset currently that has 4 columns for values lets call them odd_low, odd_high, and even_low, even_high and I want to have two columns in the grid (LOW and HIGH) and have the values set based on the value of another column which will simply be 'O' or 'E' - This column is named side
Here's a quick sample (right now the column is bound to the odd fields only)
columns.Add(model => model.ODD_LOW).Titled("Low House #").Sortable(sortable);
columns.Add(model => model.ODD_HIGH).Titled("High House #").Sortable(sortable);
columns.Add(model => model.SIDE).Titled("Side").Sortable(sortable);
My guess is that I'll need to accomplish this using a script, but I'm not sure how to dynamically access the rows and fields.
I don't see the need for a dynamic datagrid in the scenario you discribed.
When using MVC, it's a good practice to use a ViewModel object to represent data. This way, your controller is resposible for getting the data from your business / service layer and map the result to your ViewModel object.
Using this aproach you can create an object with your view's properties and just bind it to your gridview and other controlls.
Your ViewModel object would look like this:
public class MyViewModelItem {
public int LowHouse { get; set; }
public int HighHouse { get; set; }
public char Side { get; set; }
}
public class MyViewModel {
// Your other view's properties
public List<MyViewModelItem> List { get; set; }
}
And your controller like this:
public class MyController : Controller {
private readonly IMyService myService;
public MyController()
{
myService = new MyService(); // Consider Dependency Injection
}
public ActionResult Index() {
var data = myService.List();
var myModel = MapMyModel(data);
return View(myModel);
}
private MyViewModel MapMyModel(IEnumerable<YOUR_ENTITY> data) {
var myModel = new MyViewModel();
myModel.List = new List<MyViewModelItem>();
foreach (var item in data)
{
myModel.List.Add(new MyViewModelItem {
LowHouse = item.ODD_LOW,
HighHouse = item.ODD_HIGH,
Side = [your logic]
})
}
}
}
References:
Use ViewModels to manage data & organize code in ASP.NET MVC applications
ASP.NET MVC View Model Patterns

Wpf - How to control observable collection updates

In the parent there is a Observable Collection PendingPayment that has a list of all pending payments of sales with a column amount paid.
Then the user can select a particular sale and open it in new child window.
The thing thats going wrong is if the user just edits the text box paid amount in child window and closes the window without saving the new paid amount to database,the observable collection containing Amount paid column in the parent window gets updated.
What I want is it the collection to get updated only when the values are updated in the database.
This can be achieved by creating a copy of your sale object when the user select it in the list, and then using this copy as the view model of your child view.
You will then be able to set the new values in the original object from your list only once the save button has been clicked and the database update succeed.
An other way to proceed if you need to edit only few of the object properties would be to create and editor object and use it as the child window's view model.
Something like this :
public class Sale
{
public int PaidAmount { get; set; }
public int Some { get; set; }
public int More { get; set; }
public int Properties { get; set; }
}
public class SaleEditor
{
private Sale _sale;
public int PaidAmount { get; set; }
public SaleEditor(Sale sale)
{
_sale = sale;
PaidAmount = sale.PaidAmount;
}
public void Save()
{
// update your data here
_sale.PaidAmount = PaidAmount;
}
}
If you need your original object to update the database, then the save method could first update the object and the revert the changes if DB update failed :
public void Save()
{
var oldAmount = _sale.PaidAmount;
_sale.PaidAmount = PaidAmount;
if (!SalesDB.Update(_sale))
_sale.PaidAmount = oldAmount;
// you could also read back the value from DB
}
Whenever possible (I've never see a reason why it cannot),for listing purpose use proxy or flatted objects, you can implement this using projections query. Then user select an item from a list and the only thing you need to grab is a key to load the full object with its required object graph as the use case might dictate.
Here is a sample implementation using Entity Framework and c# lambda expressions:
Using anonymous object:
var anonymousListProjection = DbContext.PendingPayments.Select( pp=>
new { pp.Order, pp.Amount})
Using a hardcoded proxy:
var hardcodedListProjection = DbContext.PendingPayments.Select( pp=>
new PendingPaymentProxy { Order = pp.Order, Amount = pp.Amount})
//To return an observable:
var observableColl = new ObservableCollection<PendingPaymentProxy>
(hardcodedListProjection.Tolist());
public class PendingPaymentProxy
{
public string Order { get; set; }
public decimal Amount{ get; set; }
}
Apart from avoiding possibles performance problems due to unintentional loading real objects, this way you only have to worry for your list when the user do save in the detail view.

MVC model properties returning default value

Something weird is happening and I am not able to understand why.. here's the scenario -
I have a model with few properties when I populate the model the properties in model does have values set (checked by putting breakpoints). It comes on the view also but it is not being shown on textbox. It is showing the default value (guessing by seeing the item textbox on the page as it has 0).
Below is my model -
public class PriceEnquiryModel
{
[DisplayName("Item")]
public int item { get; set; }
[DisplayName("Description")]
public string description { get; set; }
[DisplayName("UOP")]
public string uop { get; set; }
[DisplayName("UOS")]
public string uos { get; set; }
[DisplayName("Pack Description")]
public string pack_description { get; set; }
[DisplayName("Pack Size")]
public string PackSize { get; set; }
}
This is the controller;s code -
public ActionResult Search(PriceEnquiryModel price)
{
var priceEnquiryModel = new PriceEnquiryModel();
// Read parameter values from form.
int item = Convert.ToInt32(Request.Form["txtSearch"].ToString());
int maxrow = Convert.ToInt32(Request.Form["txtmaxrow"].ToString());
string priceType = !string.IsNullOrWhiteSpace(price.priceType) && price.priceType.ToUpper().Equals("STA") ? "N" : "Y";
// Get the price information
var operationResult = priceBal.SearchPriceEnquiry(0, item, price.price_scheme, priceType, maxrow);
var priceEnquiryDomList = (List<PriceEnquiryDom>)operationResult[0].Result;
// Check if we have something
if (priceEnquiryDomList != null && priceEnquiryDomList.Count > 0)
{
// Parse the model.
priceEnquiryModel = helper.ConvertDomToModel(priceEnquiryDomList[0]);
// Prepare the list.
priceEnquiryModel.PriceEnquiryModelList = new List<PriceEnquiryModel>();
foreach (var priceEnquiryDom in priceEnquiryDomList)
{
var priceEnquiryModelListItem = helper.ConvertDomToModel(priceEnquiryDom);
priceEnquiryModel.PriceEnquiryModelList.Add(priceEnquiryModelListItem);
}
Session["mainModel"] = priceEnquiryModel;
}
// Prepare product drop down list items if searched by product desc
if (TempData.Count > 0 && TempData["Products"] != null)
{
var products = TempData["Products"] as List<ProductSearchByDescModel>;
ViewBag.Products = products;
}
return View("Index", priceEnquiryModel);
}
This is the model on the View (while debugging) -
This is how I am rendering the model on the view -
This is the page after running -
Does anyone has any idea what is going on ? I have done the same thing on multiple pages and all run as expected.
Thanks in Advance.
Rohit
The issue is that your method has parameter PriceEnquiryModel price but then you return a new instance of PriceEnquiryModel (named priceEnquiryModel). The process of model binding includes binding your model and adding its values to ModelState (along with any validation errors).
When you return the view, the html helper methods use the values from ModelState (not the models values) so attempting to change the values (which I assume is what priceEnquiryModel = helper.ConvertDomToModel(priceEnquiryDomList[0]); is doing) is ignored by the helpers.
For an explanation of why this is the default behavior, refer the second part of this answer
One option to call ModelState.Clear() before setting new values for the properties of PriceEnquiryModel

How data can be bound in windows phone 8

I want to bind the data in to list, the data can be parsed through xml and stored in local variables.
Next I want to bind these data in to list and stored in isolated storage. Please help me out.
if (e.Result != null)
{
string serviceDate, name, taskname;
XDocument doc;
doc = XDocument.Parse(e.Result);
foreach (var absentDate in doc.Element("Classworks").Descendants("Classwork"))
{
serviceDate = absentDate.Element("ClassworkDate").Value.ToString();
name = absentDate.Element("Subject").Value.ToString();
taskname = absentDate.Element("Task").Value.ToString();
}
}
else
{
}
These are the steps you need to perform approximately :
Create a model to represent single data in List, say it MyModel. If MyModel property values is not static (can be changed at runtime), you may also need to implement INotifyPropertyChanged in the model.
Create a property of type ObservableCollectoin<MyModel>, say it MyItemsSource
Put a LongListSelector or similar user control that capable of displaying multiple data on the Page. Bind the control's ItemsSource to MyItemsSource property
Set the Page's DataContext properly.
Populate MyItemsSource in code, you can do this in foreach part shown in question.
Later, when you need to save the data to IsolatedStorage, the data is available in MyItesSource property. Just save it.
Step 1
public class MyModel
{
public string ClassworkDate { get; set; }
public string Subject { get; set; }
public string Task { get; set; }
}
Step 2
public ObservableCollection<MyModel> MyItemsSource { get; set; }
Step 4
public MainPage()
{
InitializeComponent();
MyItemsSource = new ObservableCollection<MyModel>();
this.DataContext = this;
}
Step 5
foreach (var absentDate in doc.Element("Classworks").Descendants("Classwork"))
{
serviceDate = absentDate.Element("ClassworkDate").Value.ToString();
name = absentDate.Element("Subject").Value.ToString();
taskname = absentDate.Element("Task").Value.ToString();
var newModel = new MyModel{
ClassworkDate = serviceDate,
Subject = name,
Task = taskname
};
MyItemsSource.Add(newModel);
}
Above are codes related to logic in steps I explained before. With those codes setup, your data is ready to be bound. Note that in this example I didn't implement INotifyPropertyChanged for brevity.

Grouping RadioButtons in a Single View, and Posting Back the Form Data Correctly

I'm currently working on an MVC application that involves multiple sets of radiobuttons in a single View.
When the View is posted back, I want the form data to be automagically parsed and typed so that the post back method in the controller is passed the options selected for each group of radiobuttons.
Here is some sample code to illustrate the point:
Model
public class SurveyViewModel {
public List<SurveyQuestion> Questions { get; set; }
}
public class SurveyQuestion
{
public string Question { get; set; }
public IEnumerable<SelectListItem> Options { get; set; }
public int Answer { get; set; }
}
public class Option
{
public int Value { get; set; }
public string Text { get; set; }
}
Controller
public ActionResult Survey()
{
List<string> questions = new List<string> { "Question 1", "Question 2", "Question 3" };
SurveyViewModel model = new SurveyViewModel {
Questions = new List<SurveyQuestion>()
};
foreach (string question in questions)
{
List<Option> list = new List<Option>();
list.Add(new Option() { Value = 1, Text = "Answer 1" });
list.Add(new Option() { Value = 2, Text = "Answer 2" });
list.Add(new Option() { Value = 3, Text = "Answer 3" });
SelectList sl = new SelectList(list, "Value", "Text");
model.Questions.Add(new SurveyQuestion {
Question = question,
Answer = 1, // TODO: Get this from DB
Options = sl
});
}
return View(model);
}
View
#foreach (SurveyQuestion question in Model.Questions)
{
<p>#question.Question</p>
#Html.RadioButtonForSelectList(m => question.Answer, question.Options)
}
Helper
http://jonlanceley.blogspot.co.uk/2011/06/mvc3-radiobuttonlist-helper.html
If we were to just stick with standard MVC (no extensions), the Html.RadioButtonFor helper ends up outputting radiobutton groups that repeat a naming convention of Option[0], Option[1], Option[2] etc in the client.
This results in the first option from every group being grouped, the second option from every group being grouped, and so on.
Another way is to just examing the current request form data in the post back Action of the Controller, and parse it manually, but I had hoped to take advantage of MVC's ability to convert incoming data to typed parameters automagically - rather than do this myself.
Thank you for your help
Don't use a foreach loop for collections as the model binder cannot write the correct markup in order for it to bind each item of your collection properly. You need to use a for-loop:
for (var i = 0; i < Model.Questions.Count(); i++)
{
<p>#Model.Questions[i].Question</p>
#Html.RadioButtonForSelectList(m => Model.Questions[i].Answer, Model.Questions[i].Options)
}
You can inspect the markup written using a forloop. Each question is now indexed (e.g. Questions[0].Answer, Questions[1].Answer and so on) and so the model binder can do its job properly. I bet the radiobuttonlist helper won't even work with your current code as it writes out the options with the same name (e.g. question.Answer). So all options are treated as one group.

Categories