Drop down is not maintaining its State and showing only selected value - asp.net-mvc-3

I want to select year from my drop down list and that year will be passed to my procedure in the where clause and will get the results. It works fine but on the view the selected value is only visible.
Example If I select 2015 from my drop down list which has 2015 and 2016 values then on the view only 2015 is visible on the drop down.
Records are perfectly fetched.
Model
public class Data
{
[Key]
public string DataName { get; set; }
public int Year { get; set; }
}
Controller
public ActionResult Test()
{
VMNews objnews = new VMNews();
if (Request["ddlYear"] != null)
{
string selectedValue = Request["ddlYear"];
objnews.DataName = db.Database.SqlQuery<Data>("usp_year #Year",new SqlParameter("#Year",selectedValue)).ToList();
}
Response.Write("Nothing Selected");
return View("Index",objnews);
}
View
using (Html.BeginForm("Test","Home"))
{
#Html.DropDownList("ddlYear", new SelectList(Model.MovieName, "Year", "Year"), "ALL")
<button type="submit">Button</button>
}
}
Problem is there at the view level only, I had used the HTTPPost option on the controller and on the view ForMethod.POST but it didnt worked.

If I get this straight, u want to add a listItem with more than 1 value?
In this case you should concat data into a sigle string value
(remove public int Year { get; set; }/ add public string Year { get; set; } ) and then split it on the POST (ActionResult Test) and use them on your procedure.

Related

How to update hierarchical ViewModel?

I am stuck with this problem.
I have a model AssessmentModel defined like this:
public class AssessmentModel
{
public Respondent Respondent { get; set; }
public List<CompetencyModel> Competencies { get; set; }
}
public class CompetencyModel
{
public int Id { get; set; }
public string Name { get; set; }
public List<ResultModel> Results { get; set; }
}
public class ResultModel
{
public int Id { get; set; }
public int Score { get; set; }
}
All I need is to set value to the Score property of ResultModel.
Score is the only editable property here.
And I have just 1 View only, this view has a #model List, it displays a list of CompetencyModel items with Edit button for each one.
When I click the Edit button, the Id of CompetencyModel is passed to the same View, and the View draws an Edit form for ResultModel items that belong to the selected CompetencyModel.
However the form for ResultModel items exists on the same View, and the model of the View is still #model List.
How can I get to the Score property by using bindable Html.EditorFor(m=>m.Score) helper for each ResultModel item?
The View is defined like this:
#model List<CompetencyModel>
#foreach(var comp in Model)
{
<p>#comp.Name</p>
Edit
}
In the controller I set ViewBag.CurrentId = comp.Id, and at the bottom of the View:
if(ViewBag.CurrentId != null) //draw a form for ResultModel items
{
// What should I do now?
// how cant I use Html.EditorFor(m=>...) if the Model is still List<CompetencyModel>
}
I need to get to a single ResultModel entity to set a value to a Score property.
Thank you.
You should be able to get this done using Linq. Consider having the following code segment in the your last if statement
var result = Model.Results.FirstOrDefault(r => r.Id == ViewBag.CurrentId);
I dont have a IDE with me, so watchout for syntext errors

implementing dropdownlist in asp.net mvc 3

I am teaching myself asp .net mvc3. I have researched a lot but the more I read the more confused I become. I want to create a page where users can register their property for sale or rent.
I have created a database which looks like this:
public class Property
{
public int PropertyId { get; set; }
public int PropertyType { get; set; }
ยทยทยท
public int Furnished { get; set; }
...
}
Now, I want dropdownlistfor = PropertyType and Furnished.
Property type would be
1 Flat
2 House
3 Detached House
...
Furnished would be:
1 Furnished
2 UnFurnished
3 PartFurnished
...
Now, I am really not sure where to keep this information in my code. Should I have 2 tables in my database which store this lookup? Or should I have 1 table which has all lookups? Or should I just keep this information in the model?
How will the model bind to PropertyType and Furnished in the Property entity?
Thanks!
By storing property types and furnished types in the database, you could enforce data integrity with a foreign key, rather than just storing an integer id, so I would definitely recommend this.
It also means it is future proofed for if you want to add new types. I know the values don't change often/will never change but if you wanted to add bungalow/maisonette in the future you don't have to rebuild and deploy your project, you can simply add a new row in the database.
In terms of how this would work, I'd recommend using a ViewModel that gets passed to the view, rather than passing the database model directly. That way you separate your database model from the view, and the view only sees what it needs to. It also means your drop down lists etc are strongly typed and are directly in your view model rather than just thrown into the ViewBag. Your view model could look like:
public class PropertyViewModel
{
public int PropertyId { get; set; }
public int PropertyType { get; set; }
public IEnumerable<SelectListItem> PropertyTypes { get; set; }
public int Furnished { get; set; }
public IEnumerable<SelectListItem> FurnishedTypes { get; set; }
}
So then your controller action would look like:
public class PropertiesController : Controller
{
[HttpGet]
public ViewResult Edit(int id)
{
Property property = db.Properties.Single(p => p.Id == id);
PropertyViewModel viewModel = new PropertyViewModel
{
PropertyId = property.Id,
PropertyType = property.PropertyType,
PropertyTypes = from p in db.PropertyTypes
orderby p.TypeName
select new SelectListItem
{
Text = p.TypeName,
Value = g.PropertyTypeId.ToString()
}
Furnished = property.Furnished,
FurnishedTypes = from p in db.FurnishedTypes
orderby p.TypeName
select new SelectListItem
{
Text = p.TypeName,
Value = g.FurnishedTypeId.ToString()
}
};
return View();
}
[HttpGet]
public ViewResult Edit(int id, PropertyViewModel propertyViewModel)
{
if(ModelState.IsValid)
{
// TODO: Store stuff in the database here
}
// TODO: Repopulate the view model drop lists here e.g.:
propertyViewModel.FurnishedTypes = from p in db.FurnishedTypes
orderby p.TypeName
select new SelectListItem
{
Text = p.TypeName,
Value = g.FurnishedTypeId.ToString()
};
return View(propertyViewModel);
}
}
And your view would have things like:
#Html.LabelFor(m => m.PropertyType)
#Html.DropDownListFor(m => m.PropertyType, Model.PropertyTypes)
I usually handle this sort of situation by using an enumeration in code:
public enum PropertyType {
Flat = 1,
House = 2,
Detached House = 3
}
Then in your view:
<select>
#foreach(var val in Enum.GetNames(typeof(PropertyType)){
<option>val</option>
}
</select>
You can set the id of the option equal to the value of each item in the enum, and pass it to the controller.
EDIT: To directly answer your questions:
You can store them as lookups in the db, but for small unlikely to change things, I usually just use an enum, and save a round trip.
Also look at this approach, as it looks better than mine:
Converting HTML.EditorFor into a drop down (html.dropdownfor?)

select the value to populate html.dropdownlist

I have two classes as follows
public class ODCTE_Major
{
public int ODCTE_MajorId { get; set; }
public string OfficialMajorName { get; set; }
public string MajorCode { get; set; }
... More unrelated code ....
}
AND
public class CareerMajor
{
...lots of unrealted code to this question left out
public int ODCTE_MajorId { get; set; }
public virtual ODCTE_Major ODCTE_Major { get; set; }
}
I added a controller with CRUD methods and in the create.cshtml there is this line
<div class="editor-field">
#Html.DropDownList("ODCTE_MajorId", String.Empty)
#Html.ValidationMessageFor(model => model.ODCTE_MajorId)
</div>
The select list populates it with the OfficialMajorName from ODCTE_Major. I need the select list to populate with the MajorCode or a value that looks like MajorCode - OfficialMajorName.
Could someone provide assistance for how this is done, please?
Thanks.
Add this to ODCTE_Major:
public string MajorDisplayName
{
get { return string.Format("{0} - {1}", MajorCode, OfficialMajorName); }
}
This is just a read only property used to create the display text in the format you want the menu to use.
Then in CareerMajor, add:
public IEnumerable<ODCTE_Major> Majors{ set; get; } // Thank you Shyju!
This will give you a place in your view model to pass the list of Majors you want in your menu to the view.
Then in your action method when you're creating a CareerMajor view model to send to the view, populate the new IEnumberable with the ODCTE_Major entities you'd like displayed in your menu.
On the view page:
#Html.DropDownListFor(m => m.ODCTE_MajorId, new SelectList(Model.Majors, "ODCTE_MajorId", "MajorDisplayName", Model.ODCTE_MajorId), "Select One")
This creates a SelectList to populate the drop down with. The SelectList constructor is saying use ODCTE_MajorId as the value for a SelectListItem in the menu, and to use MajorDisplayName as the text to actually display in the menu. It sets the selected value, if there is one, and adds a null item with the text "Select One" to the top of the menu. Feel free to take that final argument out if you don't want the null text.
Have your ViewModel hold a Collection property to represent all available Majors (for poulating the Dropdown)
public class CareerMajor
{
//other proiperties
public int ODCTE_MajorId { get; set; }
public IEnumerable<ODCTE_Major> Majors{ set; get; }
}
And in your GET Action, fill it and send it to your strongly typed view
pubilc ACtionResult Create()
{
var viewModel=new CareerMajor();
viewModel.Majors=db.GetllAllMajors(); // getting a list of ODCTE_Major objects
return View(viewModel);
}
and in the View, use the DropDownListFor HTML Helper method.
#model CareerMajor
#Html.BeginForm())
{
#Html.DropDownListFor(m=>m.ODCTE_MajorId,
new SelectList(Model.Majors,"ODCTE_MajorId ","MajorCode"),"select one..")
//other elements
}
In your controller action:
ViewBag.ODCTE_MajorId = new SelectList(availableMajors, "ODCTE_MajorId", "MajorCode");
*second and third parameters are the names of the value and text fields respectively
Then in your view:
#Html.DropDownList("ODCTE_MajorId", String.Empty)
where availableMajors is an IEnumerable that contains the majors you want to list.

What is the behaviour when returning a query result through a function and then continuing to query on that result?

I am using ASP.NET MVC 3 with Entity Framework 4 using POCOs and want to query a set and select some properties to put into my viewModel. I will sketch a simplified version of my situation:
Situation:
I have an entity BananaTree containing a collection of Banana
public class Banana
{
public int Id { get; set; }
public int Size { get; set; }
public TimeSpan Age { get; set }
public string Description { get; set; }
}
public class BananaTree
{
public int Id { get; set; }
public ICollection<Banana> Bananas { get; set; }
}
I also have a view model BananaListItemViewModel used in the view showing a list of bananas for a certain banana tree. This view is managed by the BananaTreeController
public class BananaListItemViewModel
{
public int Id { get; set; }
public TimeSpan Age { get; set }
}
I have a Details action on the controller like so:
public ActionResult Details(int bananaTreeId)
{
var viewModel = from bananaTree in bananaTreeRepository.BananaTrees
where bananaTree.Id == bananaTreeId
from banana in bananaTree.Bananas
select new BananaListItemViewModel
{
Id = banana.Id,
Age = banana.Age
};
return View(viewModel);
}
What I want to change
This works fine and now I only select the items from the database that I need for my view model. However, I want to take out some more logic from my controller and am trying to do this as much as possible.
I would like to have a function in my repository like so:
IQueryable<Banana> GetBananas(int bananaTreeId)
{
return (from bananaTree in BananaTrees
where bananaTree.Id == bananaTreeId
select bananaTree.Bananas).Single().AsQueryable();
}
and use it like so:
public ActionResult Details(int bananaTreeId)
{
var viewModel = from banana in bananaTreeRepository.GetBananas(bananaTreeId)
select new BananaListItemViewModel
{
Id = banana.Id,
Age = banana.Age
};
return View(viewModel);
}
Question
My question is, in this case, will the two queries be combined and go to the database in one go like in my first example or will this first get all the bananas from the tree completely out of the database and perform the second query on that list? I would prefer the first case. If not, could I rewrite the GetBananas query to get that behaviour (for example like the query below)?
IQueryable<Banana> GetBananas(int bananaTreeId)
{
return from bananaTree in BananaTrees
where bananaTree.Id == bananaTreeId
from banana in bananaTree.Bananas
select banana;
}
Thanks very much in advance.
In your specific case, it will be only one query, if the call to Single() doesn't lead to the query to be executed. Unfortunately, I couldn't find any info on whether it does or does not. The call to AsQueryable does not trigger the execution as long, as the Bananas property really is an IQueryable.
According to http://msdn.microsoft.com/en-us/library/bb156472.aspx, the call to Single doesn't execute your query.
Conclusion:
You code should result in only one query.
In general:
You can pass an IQueryable from one method to another without it being implicitly executed.
The following code will result in only one SQL statement executed at the end, when the call to ToList happens:
IQueryable<Banana> GetBananasByWeight(int weight)
{
return from banana in Bananas where banana.Weight = weight;
}
IQueryable<Banana> FilterByQuality(IQueryable<Banana> bananaQuery, int quality)
{
return bananaQuery.Where(b => b.Quality == quality);
}
public List<Banana> GetBananas(int weight, int quality)
{
var query = GetBananasByWeight(weight);
var filteredBananas = FilterByQuality(query, quality);
return filteredBananas.ToList();
}

LINQ query returning a List<> as a class member

Given the follow data class,
public class EmployeeMenu
{
public int ID { get; set; }
public string HeaderName { get; set; }
public List<string> ItemNames { get; set; }
}
how can I get a sub-query into the ItemNames field?
My current query of
IQueryable<EmployeeMenu> retValue =
from mh in menuHeaders
select new EmployeeMenu
{
ID = mh.ID,
HeaderName = mh.HeaderName,
ItemNames = (from mhi in mh.MenuItems
select mhi.MenuItemName).ToList<string>()
};
doesn't seem to be doing the trick...
The data structure is
MenuHeaders MenuItems
----------- ---------
ID ID
HeaderName <-(FK)--MenuHeaderID
MenuItemName
I ended up just changing from a List to IEnumerable. This fixed it.
Wouldnt you want to just put a where in your sub-select to filter that down to all the menu items with the MenuHeaderID equals mh.HeaderName. You can just .Equals() with the StringComparison type if you want as well.
Here is an example...
IQueryable<EmployeeMenu> retValue =
from mh in menuHeaders
select new EmployeeMenu
{
ID = mh.ID,
HeaderName = mh.HeaderName,
ItemNames = (from mhi in mh.MenuItems
select mhi.MenuItemName where mhi.MenuHeaderID = mh.HeaderName).ToList<string>()
};
My guess is that your not initiliazing the list within your class. I basing this off the experience I was having with Nhibernate.
public class EmployeeMenu
{
public int ID { get; set; }
public string HeaderName { get; set; }
public List<string> ItemNames { get; set; }
public EmployeeMenu()
{
ItemNames=new List<string>();
}
}
Hope this helps.
Okay. Try replacing
(from mhi in mh.MenuItems
select mhi.MenuItemName).ToList<string>()
by
mh.MenuItems
.AsEnumerable()
.Select(mhi => mhi.MenuItemName)
.ToList()
I question if you want a where clause in there somewhere, but this should get you past the runtime exception.
Any time you see an error message of the form "LINQ to Entities does recognize the method ... and this method can not be translated into a store expression" LINQ to Entities is telling you that it can't figure out how to translate part of the expression tree into a SQL statement. This means you need to pull things client side so that LINQ to Entities doesn't try to translate something that it can't translate.

Resources