How to display selectedlist selected value by id? - linq

I have Category model
public class Category
{
//[PlaceHolder("Select file")]
//[UmbracoRequired("Form.Label.Import.SelectFile")]
//[UmbracoDisplay("Form.Label.Import.SelectFile")]
//[Required]
public int Id { get; set; }
public string Name { get; set; }
}
and a list of categories created in my controller
List<Category> items = new List<Category>();
Category list should be used in the (strongly typed) view where I have a foreach loop displaying another model Course eg.
<td>
#Html.DisplayFor(modelItem => item.Students)
</td>
<td>
#Html.DisplayFor(modelItem => item.AdmissionInfo)
</td>
<td>
#Html.DisplayFor(modelItem => item.CategoryId)
</td>
So instead of
#Html.DisplayFor(modelItem => item.CategoryId)
it should display a Name property of the Category type depending on the CategoryId value of Course model
SelectList categories = new SelectList((IEnumerable<MvcImport.Models.Category>)ViewData["categories"], "Id", "Name", item.CategoryId);
Eg.
#Html.DisplayFor(categories.Where(m => m.Id == item.CategoryId).FirstOrDefault())
But that last line does not work.
Not sure how to call just the value.
(I DO NOT want to display a dropdown, just the selected value)
Thanks

You can try this way :
#Html.DisplayFor(modelItem => categories.First(m => m.Id == item.CategoryId).Name)
or more safely (formatted for readability) :
#Html.DisplayFor(modelItem => categories.Where(m => m.Id == item.CategoryId)
.Select(m => m.Name)
.FirstOrDefault())

This one worked for me:
#Html.DropDownListFor(x =>item.RequestTypeID, new SelectList(ViewBag.RequestTypes, "Value", "Text", item.RequestTypeID))

Related

Error when joining two tables using linq in mvc4

This is my controller, in select new what should I use? If I use any class name the it is showing error like name don't find in this model?
Here the controller code:
public class HomeController : Controller
{
Database1Entities db = new Database1Entities();
public ActionResult Index()
{
return View();
}
public ActionResult details()
{
var myParts = (from p in db.emps
join d in db.depts on p.Eid equals d.Eid
select new
{
name =p.name,
address = p.address,
number=d.number,
sub=d.sub
}).ToList();
return View(myParts);
}
}
}
My index page what should I give in model if I give the class name or table name if I give class name then I have two class the which class i give in above model
here this Index page code:
#model IEnumerable<two2.Models.mass>
#{
ViewBag.Title = " Deaprtment name ";
}
<h2>Index</h2>
#{
ViewBag.Title = "Department";
}
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.name)
</th>
<th>
#Html.DisplayNameFor (model => model.address)
</th>
<th>
#Html.DisplayNameFor (model => model.sub)
</th>
<th>
#Html.DisplayNameFor (model => model.mark)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.name)
</td>
<td>
#Html.DisplayFor(modelItem => item.address)
</td>
<td>
#Html.DisplayFor(modelItem => item.sub)
</td>
<td>
#Html.DisplayFor(modelItem => item.mark)
</td>
</tr>
}
</table>
and my view page
in index page it is showing object not found
and in foreach statement it is showing error
#model two2.Models.mass
#{
ViewBag.Title = "deatils";
}
#using (#Html.BeginForm())
{
#Html.LabelFor(model => model.name)
#Html.TextBoxFor(model => model.name)
<br /><br />
#Html.LabelFor(model => model.address)
#Html.PasswordFor(model => model.address)
<br /><br />
<br /><br />
#Html.LabelFor(model => model.sub)
#Html.PasswordFor(model => model.sub)
<br /><br />
<br /><br />
#Html.LabelFor(model => model.mark)
#Html.PasswordFor(model => model.mark)
<br /><br />
<button>Login</button>
}
I don't know what should I use such that my be class name or table name and how to display on view
You should use same class name in Action also which is used in View like:
public ActionResult details()
{
var myParts = (from p in db.emps
join d in db.depts on p.Eid equals d.Eid
select two2.Models.mass
{
Eid = p.Eid,
name = p.name,
address = p.address,
number = d.number,
mark = d.mark, // <- you need to pass mark as it is used in View
sub = d.sub
}).ToList();
return View(myParts);
}
If you are using in View:
#model IEnumerable<two2.Models.mass>
Class two2.Models.mass is one type of ViewModel and it should contain only those fields which are needed in View:
namespace two2.Models
{
public class mass
{
public int Eid { get; set; }
public string name { get; set; }
public string address { get; set; }
public int number { get; set; }
public string sub { get; set; }
public int mark { get; set; }
}
}

Posting to a list<modeltype> MVC3

I am trying to get my view to post a List back to the action however it keeps coming in as null.
So my Model has a List of WeightEntry objects.
Exercise Model
public class Exercise
{
public List<WeightEntry> Entries { get; set; }
public int ExerciseID { get; set; }
public int ExerciseName { get; set; }
}
WeightEntry Model
public class WeightEntry
{
public int ID { get; set; }
public int Weight { get; set; }
public int Repetition { get; set; }
}
My View contains the ExerciseName and a forloop of WeightEntry objects
#model Mymvc.ViewModels.Exercise
...
<span>#Model.ExerciseName</span>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<table class="left weight-record">
<tr>
<th>Reps</th>
<th>Weight</th>
</tr>
#foreach (var item in Model.Entries)
{
<tr>
<td>
#Html.EditorFor(x => item.Repetition)
</td>
<td>
#Html.EditorFor(x => item.Weight)
</td>
</tr>
}
</table>
<input type="submit" value="Save" />
}
The Controller Action (Post) Does nothing at the moment. I am just trying to get the binding working before I add the save code.
[HttpPost]
public ActionResult WeightEntry(Exercise exercise)
{
try
{
//Add code here to save and check isvalid
return View(exercise);
}
catch
{
return View(exercise);
}
}
I have seen a few little tricks with adding a numerator to the form elements' names used in MVC2 but I was wondering if MVC3 was any different? I was hoping it would all bind nicely with ID's being 0 or null but instead the whole List is null when I inspect it after the form posts. Any help is appreciated.
Thanks.
Replace the following loop:
#foreach (var item in Model.Entries)
{
<tr>
<td>
#Html.EditorFor(x => item.Repetition)
</td>
<td>
#Html.EditorFor(x => item.Weight)
</td>
</tr>
}
with:
#for (var i = 0; i < Model.Entries.Count; i++)
{
<tr>
<td>
#Html.EditorFor(x => x.Entries[i].Repetition)
</td>
<td>
#Html.EditorFor(x => x.Entries[i].Weight)
</td>
</tr>
}
or even better, use editor templates and replace the loop with:
#Html.EditorFor(x => x.Entries)
and then define a custom editor template that will automatically be rendered for each element of the Entries collection (~/Views/Shared/EditorTemplates/WeightEntry.cshtml):
#model WeightEntry
<tr>
<td>
#Html.EditorFor(x => x.Repetition)
</td>
<td>
#Html.EditorFor(x => x.Weight)
</td>
</tr>
The the generated input elements will have correct names and you will be able to successfully fetch them back in your POST action.

MVC3 textbox submits null value?

I am creating a dynamic list of text boxes. when the user submits the value in the fields come back null. I think I'm missing something.
This is my product model:
public class EnqProduct
{
public string Id { get; set; }
public string Product { get; set; }
public string Quantity { get; set; }
}
This is the page model which includes a list of the above.
public IList<EnqProduct> EnqProduct { get; set; }
This is how I am setting the model:
IList<EnqProduct> items2 = Session["enquiry"] as IList<EnqProduct>;
var EnquiryModel = new Enquiry {
EnqProduct = items2
};
return View(EnquiryModel);
and this is how I display the fields:
foreach (var item in Model.EnqProduct)
{
<tr>
<td>
<span class="editor-field">
#Html.TextBox(item.Id, item.Product)
#Html.ValidationMessageFor(m => m.A1_Enquiry)
</span>
<br><br>
</td>
<td>
<span id = "field" class="editor-field">
#Html.TextBox(item.Id, item.Quantity)
</span>
<br><br>
</td>
</tr>
}
When the user submits the fields go back to the controller null?
I would recommend you using editor templates and replace your foreach loop with the following:
#model Enquiry
<table>
<thead>
<tr>
<th>product name</th>
<th>quantity</th>
</tr>
</thead>
<tbody>
#Html.EditorFor(x => x.EnqProduct)
</tbody>
</table>
and then define an editor template which will automatically be rendered for each element of the EnqProduct collection (~/Views/Shared/EditorTemplates/EnqProduct.cshtml):
#model EnqProduct
<tr>
<td>
#* We include the id of the current item as hidden field *#
#Html.HiddenFor(x => x.Id)
<span class="editor-field">
#Html.EditorFor(x => x.Product)
#Html.ValidationMessageFor(x => x.Product)
</span>
</td>
<td>
<span id="field" class="editor-field">
#Html.EditorFor(x => x.Quantity)
</span>
</td>
</tr>
Now when you submit the form you will get correct values:
public class HomeController: Controller
{
public ActionResult Index()
{
var model = new Enquiry();
model.EnqProduct = ...
return View(model);
}
[HttpPost]
public ActionResult Index(Enquiry model)
{
// the model.EnqProduct will be correctly populated here
...
}
}
As far as the correct wire format that the default model binder expects for your input fields I would recommend you taking a look at the following article. It will allow you to more easily debug problems in the feature when some model is not properly populated. It suffice to look with FireBug and the name of the values being POSTed and you will immediately know whether they are OK or KO.

How can the roles for individual users be listed, selected and edited with membership info

I'm trying to create an admin section to manage users using .net MVC3 in vs 2010. I've figured out how to create and edit new users and roles separately. But I am struggling to figure out how to add roles when I create or edit a new user. This is as far as I've gotten:
In my Model:
public class UserModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email address")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
public class IndexViewModel
{
public IEnumerable<UserModel> Users { get; set; }
public IEnumerable<string> Roles { get; set; }
}
In my Controller
public ActionResult Index()
{
return View(
new IndexViewModel
{
Users = Membership.GetAllUsers().Cast<MembershipUser>().Select(x => new UserModel
{
UserName = x.UserName,
Email = x.Email,
}),
Roles = Roles.GetAllRoles()
});
}
And in the View:
#model IEnumerable<BBmvc.Areas.Tools.Models.IndexViewModel>
//...
#foreach (var item in Model) {
foreach (var user in item.Users)
{
<tr>
<td>
#Html.DisplayFor(modelItem => user.UserName)
</td>
<td>
#Html.DisplayFor(modelItem => user.Email)
</td>
<td>
#Html.DisplayFor(modelItem => user.Password)
</td>
<td>
#Html.DisplayFor(modelItem => user.ConfirmPassword)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { /* id=user.PrimaryKey */ }) |
#Html.ActionLink("Details", "Details", new { /* id=user.PrimaryKey */ }) |
#Html.ActionLink("Delete", "Delete", new { /* id=user.PrimaryKey */ })
</td>
</tr>
}
}
I am seeing this error:
The model item passed into the dictionary is of type
'BBmvc.Areas.Tools.Models.IndexViewModel', but this dictionary
requires a model item of type 'System.Collections.Generic.IEnumerable
I'm confused. Am I on the right track? Right now I'm simply trying to get the roles to display on the page ... eventually I need them to be filtered for each user so that only the roles a user is in will be listed.
EDIT:
The answer below fixed the viewmodel problem I was having. The ultimate solution to displaying roles for each user wasn't that involved. I added a list to the UserModel:
public IEnumerable<string> UserRoles { get; set; }
Filled it in the Controller:
public ActionResult Index2()
{
var model = Membership.GetAllUsers().Cast<MembershipUser>().Select(x => new UserModel
{
UserName = x.UserName,
Email = x.Email,
UserRoles = Roles.GetRolesForUser(x.UserName)
});
return View(model);
}
And then displayed it in the view:
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.UserName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Email)
</td>
<td>
#foreach (var role in item.UserRoles)
{
#role
}
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
Thanks to everyone!
As you are returning just 1 object of type IndexViewModel you need to change your #model to #model BBmvc.Areas.Tools.Models.IndexViewModel.
As this single object is holding a list of users and roles... you need to change the view:
#model BBmvc.Areas.Tools.Models.IndexViewModel
//...
#foreach (var user in Model.Users)
{
<tr>
<td>
#Html.DisplayFor(modelItem => user.UserName)
</td>
<td>
#Html.DisplayFor(modelItem => user.Email)
</td>
<td>
#Html.DisplayFor(modelItem => user.Password)
</td>
<td>
#foreach (var role in Model.Roles.Where(x => x.idUser == user.idUser))
{
<span>#role.Name</span> |
}
</td>
<td>
#Html.ActionLink("ViewRoles", "View Roles", new { id=user.PrimaryKey }) |
#Html.ActionLink("Edit", "Edit", new { id=user.PrimaryKey }) |
#Html.ActionLink("Details", "Details", new { id=user.PrimaryKey }) |
#Html.ActionLink("Delete", "Delete", new { id=user.PrimaryKey })
</td>
</tr>
}
This way, you can have the roles of the user, and clicking on "View Roles" or "Setup Roles" (use the link text that best suite your problem) you can have a list of the roles of that user. There you can add/edit/delete roles for the selected user.
You need to change the #model
From: #model IEnumerable<BBmvc.Areas.Tools.Models.IndexViewModel>
To: #model BBmvc.Areas.Tools.Models.IndexViewModel.
The code in your controller is just returning an instance of IndexViewModel, not an IEnumerable (in other words a collection/list/array/whatever) of IndexViewModel's.

MVC3 The model item passed into the dictionary is of type '_320.Models.MyViewModel', but

I am passing a viewmodel into a view containing a foreach loop. This viewmodel contains two lists. These lists are filled using Linq.
With the following code, I get the following error: The model item passed into the dictionary is of type '_320.Models.MyViewModel', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[_320.Models.MyViewModel]'.
I want to reach properties contained in the two lists in the ViewModel in my view's foreach loop.
UPDATE
I have been able to display the view by modifying the end of my controller code to:
List<MyViewModel> MyList = new List<MyViewModel>();
MyList.Add(_myViewModel);
return View(MyList);
However, it is an empty view with nothing but headers. When I attempt to change my fields in my view from something like #Html.DisplayFor(modelItem => item.rx.Rx_ID) to #Html.DisplayFor (modelItem => item.Rxes.rx.Rx_ID) it is labeled red. Is it impossible to access a property located that far down in a list?
END OF UPDATE
Model
public class MyViewModel
{
public Patient patient { get; set; }
public Rx rx { get; set; }
public Fill fill { get; set; }
public List<Rx> Rxes { get; set; }
public List<Fill> Fills { get; set; }
Controller
public ActionResult AllFilled()
{
MyViewModel _myViewModel = new MyViewModel();
List<Fill> FillList = db.Fills.Where(p => p.Status == "Filled").ToList();
List<Rx> RxList = new List<Rx>();
Rx myRx = new Rx();
foreach (var item in FillList)
{
myRx = db.Rxes.Single(p => p.Rx_ID == item.Rx_ID);
RxList.Add(myRx);
}
_myViewModel.Fills = FillList;
_myViewModel.Rxes = RxList;
return View(_myViewModel);
}
}
View
#model IEnumerable<_320.Models.MyViewModel>
#{
ViewBag.Title = "AllFilled";
}
<h2>AllFilled</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
NDC
</th>
<th>
Rx_ID
</th>
<th>
Fill_ID
</th>
<th>
Status
</th>
<th>
Filled Date
</th>
<th>
Filled By
</th>
<th></th>
</tr>
{
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.rx.NDC)
</td>
<td>
#Html.DisplayFor(modelItem => item.rx.Rx_ID)
</td>
<td>
#Html.DisplayFor(modelItem =>item.fill.Fill_ID)
</td>
<td>
#Html.DisplayFor(modelItem => item.fill.Status)
</td>
<td>
#Html.DisplayFor(modelItem => item.fill.Filled_Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.fill.Filled_By)
</td>
<td>
#Html.ActionLink("Details", "Details", new { id=item.rx.Rx_ID })
</td>
</tr>
}
</table>
Your view is expecting a model of type IEnumerable<_320.Models.MyViewModel> due to the first line in the view.
#model IEnumerable<_320.Models.MyViewModel>
If you want to use a model object of type MyViewModel (as coded in your controller), change this line to
#model _320.Models.MyViewModel

Resources