Passing data from Controller to model in MVC 3 - asp.net-mvc-3

is there a way to pass data from controller to model?
the scenario of my project is that, it has two tables in database, and in View there are two text boxes , the data of one text box is save to one table while data of another table is save to another table , i want to show the data of both tables in another single View . for that reason i want to send both textbox values from controller to model then want to show the data from that model to the view.
can someone please help how can i implement it ?

You need to create a view model and use that. view model's are simple POCO classes which are specific to the view.
public class CustomerInfo
{
public string Name {set;get;}
public string AddressLine {set;get;}
}
And in your GET Action, you can create an object of this, read the data from 2 tables and set the property values of our view model and send to the view
public ActionResult View(int id)
{
var vm = new CustomerInfo();
var db=new YourDbContext();
var customer=db.GetCustomer(id); // read from first table
var address=db.GetAddress(id); // read from second table
vm.Name = customer.FirstName;
vm.AdddressLine = address.AddressLine1;
return View(vm);
}
And your view will be strongly typed to this view model
#model CustomerInfo
<h2>#Model.Name</h2>
<h3>#Model.AddressLine1</h3>
If you are trying to save this information to the db tables, You may have a form in your view
#model CustomerInfo
#using(Html.BeginForm("Edit","Home"))
{
<label>Name</label> #Html.TextBoxFor(f=>f.Name)
<label>Name</label> #Html.TextBoxFor(f=>f.AddressLine)
<input type="submit" />
}
and in your HttpPost action
[HttpPost]
public ActionResult Edit(CustomerInfo model)
{
// read the values from model and save to 2 tables
var c=new Customer { FirstName=model.Name};
var a=new Address{ AddressLine1=model.AddressLine};
var db=new YourDbContext();
db.Customers.Add(c);
db.Addresses.Add(a);
db.SaveChanges();
return RedirecToAction("Success");
}
If you want to save a collection of items, You may refer this answer or this.

Related

How could i dynamically bind data in checkbox in mvc3 razor

I am working in mvc3 razor.
i want checkbox input in razor view for all catagories stored in database.
how could i bind it? please help
Suppose your model is having a field to hold all the checkbox text like.
public class MyClass
{
public string SelectedOptions {get;set;}
public List<String> CheckList {get;set;}
}
Write a controller Action method like
public ActionResult ShowCheckBoxList()
{
MyClass Options= new MyClass();
Options.CheckList = new List<String>();
// Here populate the CheckList with what ever value you have to
// either if you are getting it from database or hardcoding
return View(Options);
}
you have to create a view by right clicking the above method and choose Add View. Make sure you keep the name same as the method name also you the strongly typed view by choosing the MyClass Model from the dropDown, scaffolding template is optional use it as per your scenario.
Now in your View you can use this populated check box text as
#foreach(var optionText in Model.CheckList)
{
#Html.CheckBox(#Model.SelectedOptions, false, new {Name = "SelectedOptions", Value = #optionText})
#Html.Label(#optionText , new { style = "display:inline;" })
}
Keep this in a form and make sure you also specify a Action to be called on post of the form.
Make your action name same as the previous action (it is [GET] meaning before post), Now we create same method for [POST]
[HTTPPOST]
public ActionResult ShowCheckBoxList(MyClass data) // here you will get all the values from UI in data variable
{
//data.SelectedOptions will have all the selected values from checkbox
}

System.Data.Objects.ObjectSet`1 instead of database table

I have database CarsDB, with Table Car in it. I whant to see the car table, but getting only System.Data.Objects.ObjectSet`1 instead of database table
public CarsBDEntities db = new CarsBDEntities();
public ActionResult Index()
{
ViewBag.Carlist = db.Cars.ToString();
return View();
}
I have make a table, then created a model from it. Using entity frameworkd and ado.net.
You don't want to use ToString; if you just return db.Cars instead, that will give you an IEnumerable that you can work with.
var cars = db.Cars;
return View(cars);
You can use this to make a Webgrid that will display your data. Razor view:
#model IEnumerable<Namespace.Models.Cars>
#{
var grid = new WebGrid(Model);
}
#grid.GetHtml()
You're trying to convert an ObjectSet to a string, which is why your getting "System.Data.Objects.ObjectSet". You'll need to pull the data out of the table to view it. For instance, something like:
string firstCarMake = db.Cars.FirstOrDefault().Make.ToString();

MVC3 Razor - Models and Views

I have an action that creates a List and returns it to my view..
public ActionResult GetCustomers()
{
return PartialView("~/Views/Shared/DisplayTemplates/Customers.cshtml", UserQueries.GetCustomers(SiteInfo.Current.Id));
}
And in the "~/Views/Shared/DisplayTemplates/Customers.cshtml" view I have the following:
#model IEnumerable<FishEye.Models.CustomerModel>
#Html.DisplayForModel("Customer")
Then I have in the "~/Views/Shared/DisplayTemplates/Customer.cshtml" view:
#model FishEye.Models.CustomerModel
#Model.Profile.FirstName
I am getting the error:
The model item passed into the dictionary is of type System.Collections.Generic.List`1[Models.CustomerModel]', but this dictionary requires a model item of type 'Models.CustomerModel'.
Shouldn't it display the Customer.cshtml for every item in the collection in the Customers.cshtml?
Help!
I am not sure why you are calling a partial view like this. If it is a Customer Specific view, why not put it under Views/Customer folder ? Remember ASP.NET MVC is more of Conventions. so i would always stick with the conventions (unless abosultely necessary to configure myself) to keep it simple.
To handle this situation, i would do it in this way,
a Customer and CustomerList model/Videmodel
public class CustomerList
{
public List<Customer> Customers { get; set; }
//Other Properties as you wish also
}
public class Customer
{
public string Name { get; set; }
}
And in the action method, i would return an object of CustomerList class
CustomerList customerList = new CustomerList();
customerList.Customers = new List<Customer>();
customerList.Customers.Add(new Customer { Name = "Malibu" });
// you may replace the above manual adding with a db call.
return View("CustomerList", customerList);
Now there should be a view called CustomerList.cshtml under Views/YourControllerName/ folder. That view should look like this
#model CustomerList
<p>List of Customers</p>
#Html.DisplayFor(x=>x.Customers)
Have a view called Customer.cshtml under Views/Shared/DisplayTemplates with this content
#model Customer
<h2>#Model.Name</h2>
This will give you the desired output.
Your view is expecting a single model:
#model FishEye.Models.CustomerModel // <--- Just one of me
You're passing it an anonymous List:
... , UserQueries.GetCustomers(SiteInfo.Current.Id) // <--- Many of me
You should change your view to accept the List or determine which item in the list is supposed to be used before passing it into the View. Keep in mind, a list with 1 item is still a list and the View is not allowed to guess.

How to Post Partial View Data?

Any input much appreciated :)
I want to know one thing whether I can post multiple partial views data in MVC?(means i want to update partial views data to DATABASE)
Here is the Example:
Model:-
public class PassengerViewModel
{
public List<PassengerModel> Passengers { get; set; }
public ContactModel Contact { get; set; }
}
Controller:-
[RequiredAuthentication]
public ActionResult Passenger()
{
var passengrViewMdl = new PassengerViewModel()
{
Contact = new ContactModel(),
Passengers = psngrService.LoadPassengers(Convert.ToInt32(Session["LPORefNO"]))
};
return View(passengrViewMdl);
}
[HttpPost]
public ActionResult Passenger(PassengerViewModel passengerViewModel)
{
Here i want to update Passengers & Contact information
}
View:-
#model QR.LPO.Core.Models.PassengerViewModel
#{
ViewBag.Title = "Add Passengers";
}
#using (Html.BeginForm())
{
#Html.Partial("_Passenger", Model.Passengers);
#Html.Partial("_PassengerContact", Model.Contact);
<input type="submit" value="Submit" />
}
Thanks.
Yes, indeed you can, but, controller usually works only with one model per request, so either your model should have declared within it properties of both partial submodels, or submodels themselves.
This is possible due to HTML specifications, all data on form, which has submit buttom is send to submit action url.
This will almost work as you have it - there's nothing inherent to partials that would prevent this, in the end the html that's output is all that's important.
The problem with your code is that presumably the model of your _Passenger view is of type Passengers and the model of your _PassangerContact view is of type Contact. What this means is that if you standard HtmlHelper extensions (like Html.Textbox(...) or Html.TextboxFor(...) the fields they generate will not have full names like Contact.Name, but instead just names relative to their model, like Name. This will cause modelbinding to fail in your post action.
You can solve this in a number of ways.
Simply use the same model type (PassengerViewModel) in your sub-views, and write code like #Html.TextboxFor(m => m.Contact.Name).
Instead of using Html.Partial, use Html.EditorFor(...). This passes the proper prefix information into the child view so the field names are generated properly.
Explicitly set the prefix yourself
Like this:
#{
var childViewData = new ViewDataDictionary(this.ViewData);
childView.TemplateInfo.HtmlFieldPrefix = "Contact";
}
#Html.Partial("_PassengerContact", Model.Contact, childViewData)
You could also look at creating a Html.PartialFor overload yourself, as described in this stackoverflow question: ASP.NET MVC partial views: input name prefixes

ASP.Net MVC 3 ViewModel with Drop Down Lists

I am developing an ASP.Net MVC 3 web application. The app currently is connected to a database that has several tables, two of which are Category(catId, Name) and Site(siteID, Name).
I wish to create a view that has two drop down lists, one for each of the tables mentioned, so that the user can select from and then run a report. To do this I have created a viewModel to represent the two drop down lists
public class ReportSiteCategorySearchViewModel
{
public SelectList categoryList { get; set; }
public SelectList siteList { get; set; }
}
Then in my controller that returns the viewModel I have the following
public ActionResult getEquipmentByCategoryAndSite()
{
ReportSiteCategorySearchViewModel viewModel = new ReportSiteCategorySearchViewModel
{
categoryList = new SelectList(categoryService.GetAllCategories().ToList(), "categoryID", "categoryTitle"),
siteList = new SelectList(siteService.GetAllSites().ToList(), "siteID", "title")
};
return View(viewModel);
}
I then pass to a view which takes this viewModel and writes out the values to the drop downs
<div>
<label for="ddlSite">Sites</label>
#Html.DropDownList("ddlSite", Model.siteList, "All Sites")
<label for="ddlCatgeory">Categories</label>
#Html.DropDownList("ddlCatgeory", Model.categoryList, "All Categories")
</div>
This works, however, I am not sure this is the best way to do it. I am just wondering is my method correct, is there a better way to do this? Ie, what if I needed 5/6 more drop down lists from other tables, should I just add to the current viewModel etc?
Any feedback would be much appreciated.
Thank You.
You can create a viewModel of type List<SelectList> In your controller, add each table (as a SelectList as you're doing) to this model. Then pass the view the model, which is a list of SelectLists.
Then you can iterate through each value in your view:
<div>
#foreach(SelectList SL in Model)
{
<label for="ddl"+SL>SL.Title</label>
#Html.DropDownList("ddl"+SL.Title, sl.list, sl.items")
}
You may need to modify your list of SelectList to include the 'Title' or 'items' field. By doing it this way you can keep adding elements to the List, and you won't need to update the view.

Resources