I am trying add a model with respect to users (ApplicationUser) and for that i created a model my problem is the data is not displaying in view (username for particular post)
Model
public class OrganizationViewModel
{
public ApplicationUser AppUser { get; set; }
public int OrganizationId { get; set; }
public string Name { get; set; }
}
Controller
public ActionResult Create(OrganizationViewModel organizationviewmodel)
{
var getuserid = User.Identity.GetUserId();
var userid = db.Users.Single(s => s.Id == getuserid);
var organizationvmodel = new Organization
{
AppUser = userid,
Name = organizationviewmodel.Name
};
db.Organizations.Add(organizationvmodel);
db.SaveChanges();
return RedirectToAction("Index");
}
But in view which means index.cshtml when i try to populate it as a list its empty just like this output image
View
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.AppUser.UserName)
#ViewBag.UserName
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.OrganizationId }) |
#Html.ActionLink("Details", "Details", new { id = item.OrganizationId }) |
#Html.ActionLink("Delete", "Delete", new { id = item.OrganizationId })
</td>
</tr>
}
Please give me a good solution because i am very new to asp.net mvc
Related
I wanted to redirect "Edit" Actionlink to a another page from Index.cshtml page and the directions in the tab shows "http://localhost:49712/Home/Edit/id". The data are shown in "Index.cshtml" in a table but not all data is shown (just some of it). Then, when I want to edit the data, the edit page shows "HTTP Error 404.0 - Not Found". I think this is because of the attributes got clash or anything?
This is the "Index.cshtml" for the table:-
foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ID)
</td>
<td>
#Html.DisplayFor(modelItem => item.NUMBER)
</td>
<td>
#Html.DisplayFor(modelItem => item.TITLE)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.ID}) |
#Html.ActionLink("Details", "Details", new { id = item.ID}) |
#Html.ActionLink("Delete", "Delete", new { id = item.ID})
</td>
</tr>
}
This is the edit part in controller":-
// GET: Home/Edit/5
public async Task<ActionResult> Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Tests test= await db.Test.FindAsync(id);
if (test== null)
{
return HttpNotFound();
}
return View(test);
}
// POST: Home/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "ID,YEAR,LANGUAGE,COUNTRY,SUBJECT,NUMBER,TITLE] Tests test)
{
if (ModelState.IsValid)
{
db.Entry(test).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(test);
}
This is my model:-
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class Tests
{
public string ID{ get; set; }
public Nullable<int> YEAR { get; set; }
public string LANGUAGE { get; set; }
public string COUNTRY { get; set; }
public string SUBJECT { get; set; }
public string NUMBER { get; set; }
public string TITLE { get; set; }
}
}
As you can see, some of the attributes does not shown in data table in "Index.cshtml", but all of them will be shown in edit page. How can I do this? Any help from anyone would be highly appreciated.
I'm having some troubles with Models and ViewModels.
I need list all bills and the users in the same view. (users in a dropdown list)
Also: When to use IEnumerable<T>? Because depending I change the view change the error message.
Model
public class Bill
{
public int Id { get; set; }
public string Title { get; set; }
public DateTime Date { get; set; }
public string Category { get; set; }
public double Amount { get; set; }
public Card Card { get; set; }
public int CardId { get; set; }
}
ViewModel
public class UserBills
{
public IEnumerable<ApplicationUser> User { get; set; }
public Bill Bill { get; set; }
}
View
#*#model IEnumerable<Nucontrol.Models.Bill>*#
#model IEnumerable<Nucontrol.ViewModels.UserBills>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Bill.Card.Number)
</td>
<td>
#Html.DisplayFor(modelItem => item.Bill.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.Bill.Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.Bill.Category)
</td>
<td>
#Html.DisplayFor(modelItem => item.Bill.Amount)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Bill.Id }) |
#Html.ActionLink("Details", "Details", new { id = item.Bill.Id }) |
#Html.ActionLink("Split", "Split", new { id = item.Bill.Id }, new { data_target = "#myModal", data_toggle = "modal" })
</td>
</tr>
}
<!-- List all users -->
#Html.DropDownListFor(m => User.Identity.Name, new SelectList(User.Identity.Name, "Id", "Name"), "", new { #class = "form-control" })
Controller
public ActionResult Index()
{
var users = _context.Users.ToList();
var bills = _context.Bills.ToList();
var viewModel = new UserBills
{
User = users
};
return View(viewModel);
}
You have some issues in sample code provided:
1) The DropDownListFor uses User.Identity.Name property as model binding, which actually derived from IIdentity.Name which is getter-only property. Declare another property with setter available which holds user ID in your viewmodel.
2) Passing UserBills viewmodel into view which bound to IEnumerable<UserBills> model may cause InvalidOperationException. You need to use either passing IEnumerable<UserBills> from controller or define #model UserBills.
3) I suggest you use IEnumerable<SelectListItem> to create DropDownListFor items from IEnumerable<ApplicationUser> generated by identity data context and pass it to view (see also IdentityUser properties).
Here is initial solution based from my thought:
Model
public class UserBills
{
public int UserId { get; set; }
public IEnumerable<SelectListItem> Users { get; set; }
public IEnumerable<Bill> Bills { get; set; }
}
Controller
public ActionResult Index()
{
var users = _context.Users.ToList();
var bills = _context.Bills.ToList();
var viewModel = new UserBills
{
Users = users.Select(x => new SelectListItem() { Value = x.Id.ToString(), Text = x.UserName.ToString() }),
Bills = bills
}
return View(viewModel);
}
View
#model Nucontrol.ViewModels.UserBills
#foreach (var item in Model.Bills)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Card.Number)
</td>
<!-- other properties -->
</tr>
}
#Html.DropDownListFor(m => m.UserId, Model.Users, "", new { #class = "form-control" })
NB: Since you're getting selected user ID from viewmodel binding, it is possible to create HttpContext.User instance and setting User.Identity.Name property from that ID.
I have a simple list view with list of tasks.
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.TaskText)
</td>
<td>
#Html.DisplayFor(modelItem => item.TillDate)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id = item.Id })
<select id="TaskState">
<option>Active</option>
<option>Stoped</option>
<option>Complete</option>
</select>
</td>
</tr>
}
And class for Task:
public class Task
{
public int Id { get; set; }
public string TaskText { get; set; }
public DateTime TillDate { get; set; }
public TaskState State { get; set; }
}
public enum TaskState
{
Active=1,
Stoped,
Complete
}
Now, I want to change Task state by selecting it from drop down list, but can't figure out how to conect it with model. How can I do it?
If you are using ASP.NET MVC 5.1 you can use the EnumDropDownListFor() helper
#Html.EnumDropDownListFor(model => model.State)
I'm trying to display data on my index view from from my models that are associated with each other based on id's. I.e. display client name, asset name that belongs to this client, and address of this client, etc...
Here's my model:
Client model:
public class Client : Person {
public ICollection<OccupancyHistoryRecord> OccupancyRecords { get; set; }
public ICollection<RentHistoryRecord> RentRecords { get; set; }
}
Asset model:
public class Asset {
public int Id { get; set; }
[Display(Name = "Asset Name")]
public string Name { get; set; }
[Display(Name = "Asset Type")]
public string Type { get; set; }
public FullAddress Address { get; set; }
[Display(Name = "Asking Rent")]
public string AskingRent { get; set; }
public ICollection<OccupancyHistoryRecord> OccupancyRecords;
public ICollection<RentHistoryRecord> RentRecords;
}
Occupancy Record:
public class OccupancyHistoryRecord {
public int Id { get; set; }
public int AssetId { get; set; }
public int ClientId { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
}
Client Controller:
public ActionResult Index()
{
var clients = db.Clients.Include(c => c.OccupancyRecords) // how to get the asset name instead of the id)
.Include(c => c.HomeAddress)
.Include(c => c.WorkAddress);
return View(clients.ToList());
}
Index View:
#model IEnumerable<RentalManagement.Models.Client>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.OccupancyRecords)
</th>
<th>
#Html.DisplayNameFor(model => model.HomeAddress)
</th>
<th>
#Html.DisplayNameFor(model => model.WorkAddress)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.OccupancyRecords)
</td>
<td>
#Html.DisplayFor(modelItem => item.HomeAddress.StreetAddress)
</td>
<td>
#Html.DisplayFor(modelItem => item.WorkAddress.StreetAddress)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Id }, null) |
#Html.ActionLink("Assets", "Details", "Assets", new { id = item.Id}, null) |
#Html.ActionLink("Details", "Details", new { id=item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
Right now it's displaying the occupancy record's Id. What I want is to display the asset name based on the occupancy's AssetId.
Thanks.
You need to change your :
public ActionResult Index()
{
var clients = db.Clients.Include(c => c.OccupancyRecords) // how to get the asset name instead of the id)
.Include(c => c.HomeAddress)
.Include(c => c.WorkAddress);
return View(clients.ToList());
}
code as below:
public ActionResult Index()
{
var clients = db.Clients.Include(c => c.OccupancyRecords.Select(s => new { AssetId = s.AssetId, AssetName = /* Find AssetName By Id here */ }))
.Include(c => c.HomeAddress)
.Include(c => c.WorkAddress);
return View(clients.ToList());
}
I have a BookingView class in Model:
public class BookingView
{
[Required]
[Display(Name = "Attraction")]
public int Attraction { get; set; }
[Required]
[Display(Name = "Date")]
public string Date { get; set; }
[Required]
[Display(Name = "Username")]
public string Username { get; set; }
}
Table against this model in DB is Tickets.
I need to write a function in another class in model named BookingManager to get all Ticket Records.
public IEnumerable<BookingView> GetAllBookings()
{
var a = from o in dre.Tickets select o;
return a.ToList();
}
I want to display these records in view named ViewAllBookings:
#model IEnumerable<VirtualTickets.Models.ViewModel.BookingView>
#{
ViewBag.Title = "ViewAllBookings";
}
<h2>ViewAllBookings</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
Attraction
</th>
<th>
Date
</th>
<th>
Username
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Attraction)
</td>
<td>
#Html.DisplayFor(modelItem => item.Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.Username)
</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>
}
</table>
The function gives complie time error in function GetAllBookings on return statement. If I change return type to Ticket then I get runtime error as expected because in view ViewAllBookings it is expecting IEnumerable List of records having type BookingView.
Please provide a solution to this situation. I am really confused how to deal with this.
Thanks
It looks like your setup requires converting the entity class Ticket into the view model BookingView. I guess you need something like this:
return a.AsEnumerable().Select(ticket => new BookingView
{
Attraction = ticket.SomeProperty,
// etc
})
.ToList();
You have to write method that maps Ticket to BookingView and use it like this:
public IEnumerable<BookingView> GetAllBookings()
{
var a = from o in dre.Tickets select o;
return a.AsEnumerable().Select(Map).ToList();
}
private BookingView Map(Ticket ticket)
{
var bookingView = new BookingView();
//mapping code goes here
return bookingView;
}
I am not sure if your Tickets table actually has the same columns as the BookingView class in your code, but if theere's a mapping between the table and your class, your solution would be:
var a = from o in dre.Tickets
select new BookingView { Attraction= o.Attraction,
Date=o.Date,
Username = o.UserName } ;
return a.ToList();
Yes it is obvious that you are getting this error because you are returning a Ticket object and your view needs a list of BookingView objects. The 2 don't match, i.e. they are not the same.
Your BookingManager should return your tickets to the controller. Here is an alternative way of how I would have done it.
You could change your view model to look like this:
public class BookingViewModel
{
public List<Ticket> Tickets { get; set; }
}
Your BookingManager can contain the following method to return your tickets:
public class BookingManager : IBookingManager
{
// References to your database context
public IEnumerable<Ticket> GetAllTickets()
{
return databaseContext.Tickets;
}
}
In your booking controller you can inject an instance of IBookingManager with a dependency injection framework like AutoFac:
public class BookingController : Controller
{
private readonly IBookingManager bookingManager;
public BookingController(IBookingManager bookingManager)
{
this.bookingManager = bookingManager;
}
public ActionResult Index()
{
BookingViewModel viewModel = new BookingViewModel
{
Tickets = bookingManager.GetAllTickets().ToList()
};
return View(viewModel);
}
}
And then on your view:
#model YourProject.ViewModels.Tickets.BookingViewModel
#foreach (var ticket in Model.Tickets)
{
// Display ticket details here
}
I hope this helps.