ID value not passed to different action method - asp.net-mvc

In my project, there are two controllers namely Home controller and Hotel controller.I have used view model to combine two model classes.Bellow I have Add my controllers.
Home Controller
public ActionResult Index(){
List<ImageData> details = new List<ImageData>();
var sp_details = (from s in db.service_provider
join p in db.pictures on s.SPID equals p.SPID
join c in db.cities on s.City_ID equals c.City_ID
select new { s.SPID, s.Sp_name, s.Sp_rate, s.service_type, c.Cityname, p.pic }).OrderByDescending(s => s.Sp_rate).Where(p => p.service_type == "Restaurant").Take(3).ToList();
foreach (var item in sp_details)
{
ImageData SpView = new ImageData(); // ViewModel
SpView.SPID = item.SPID;
SpView.Sp_name = item.Sp_name;
SpView.Cityname = item.Cityname;
SpView.Sp_rate = item.Sp_rate;
SpView.pic = item.pic;
details.Add(SpView);
}
return View(details);
}
Hotel controller
public ActionResult Details(int id = 0)
{
List<ImageData> details = new List<ImageData>();
var sp_details = (from s in db.service_provider
join p in db.pictures on s.SPID equals p.SPID
join c in db.cities on s.City_ID equals c.City_ID
where s.SPID == id
select new ImageData()
{
Sp_name = s.Sp_name,
Sp_location = s.Sp_location,
Cityname = c.Cityname,
service_type = s.service_type,
Sp_description = s.Sp_description,
Sp_rate = s.Sp_rate,
Sp_web = s.Sp_web,
Cnt_wh = s.Cnt_wh,
pic = p.pic
});
if (details == null)
{
return HttpNotFound();
}
return View(sp_details);
}
below is part of Index view.I have passed id value to Details action method in Hotel Controller.
<p class="name">#Html.ActionLink(item.Sp_name, "Details","Hotel", new { id = item.SPID })</p>
but value not passed and not display details of Details Action method in Hotel Controller.Since I'm new to mvc 4 I couldn't able to find the mistake.

Try explicitly including an additional null parameter that would represent your htmlAttributes parameter and would match this overload to ensure that your object was properly passed along as route parameters :
#Html.ActionLink(item.Sp_name, "Details","Hotel", new { id = item.SPID }, null)
The ActionLink() helper doesn't contain an overload that only accepts the Text, Action, Controller and RouteValues, which you have supplied, so this extra parameter is necessary.

Related

how to return selected columns based on user choice

I'm trying to limit which fields are returned by an API based on a parameter called fields which I accept multiple strings doing this
private readonly string[] fields;
public string[] SelectiveSerializer(string fields)
{
string[] _fields;
var fieldColl = fields.Split(',');
_fields = fieldColl
.Select(f => f.ToLower().Trim())
.ToArray();
return _fields;
}
I want to be able to choose what I return based on whatever the user gives me in _fields. Normal way to do it:
var linq = (from entity in db.users
where entity.ID== id
&& entity.ON== false
select( new {
ID = entity.ID,
FirstName = entity.FirstName,
LastName =entity.LastName,
FotherName = entity.FotherName
}).ToList();
but here I have to specify the fields in Select (ID, FirstName ..etc), which I want it to be dynamic based on what fields[] has. Is there a way to do this?
sort of this (which is wrong):
var linq = (from entity in db.users
where entity.ID== id
&& entity.ON== false
select( new {
foreach (string s in _fields)
{
entity.s;
}
}).ToList();
Use a ternary expression for each assignment
var user = entityContext.Users.Where(u => u.ID == id)
.Select(u => new {
ID = _fields.Contains['id'] ? u.ID : 0,
FirstName = _fields.Contains['firstname'] ? u.FirstName : null,
LastName = _fields.Contains['lastname'] ? u.LastName : null,
otherName = _fields.Contains['othername'] ? u.otherName : null
})
.ToList();
I also would put the field names in a HashSet<string> for a better performance.
var _fields = new HashSet<string>(fields.Split(',').Select(f => f.ToLower().Trim()));
This solution keeps all the properties but sets the unwanted ones to null. If you want to dynamically add properties, see this other SO question: How to dynamically create a class in C#?. But note that this only useful in scenarios where objects of this type are processed dynamically as well.
I was finally able to do this with minimal work.
assuming the filter is a string list. string array.
so to avoid reflection and all that jazz, I iterate over each record and see if the variable is in the filter list, then create a dic entry with (var,val) assuming that no duplicate var in the same record, which can be catch if you want but I don't have this issue.
Then at the end add that dic to a list.
the method accept anonymous type list and a filter list.
public static List<Dictionary<string, object>> filteredList(IEnumerable source, string[] filter)
{
var filteredList = new List<Dictionary<string, object>>();
foreach (var single in source)
{
var type = single.GetType();
var props = type.GetProperties();
var singleRecord = new Dictionary<string, object>();
foreach (var v in props)
{
if (filter.Contains(v.Name))
{
var tempValue = type.GetProperty(v.Name).GetValue(single, null);
singleRecord.Add(v.Name, tempValue);
}
}
filteredList.Add(singleRecord);
}
return filteredList;
}

MVC dropdownlist : Setting the value and text based upon table in database

I have a table in database
I've been able to show the list of TypeName in my dropdownlist in my View
Currently i'm doing this is my controller
[HttpGet]
public ActionResult CreateModule()
{
var moduleTypes = _db.ModuleTypes.Select(moduleType => moduleType.TypeName).ToList();
var model = new CreateModule
{
TypeNames = moduleTypes.Select(m => new SelectListItem
{
Value = m,
Text = m,
})
};
return View(model);
}
and in view
<div class ="input-block-level">#Html.DropDownListFor(model => model.SelectedModuleTypeName, Model.TypeNames)</div>
That results to something like this
based upon my code, I'll get the TypeName from the view in my controller's post method.
How I can I change my code in order to access Id of the TypeName in controller?
Modify your Action:
public ActionResult CreateModule()
{
var moduleTypes = _db.ModuleTypes.Select(moduleType => new { TypeName = moduleType.TypeName, Id = moduleType.Id }).ToList();
var model = new CreateModule
{
TypeNames = moduleTypes.Select(m => new SelectListItem
{
Value = m.Id.ToString(),
Text = m.TypeName,
})
};
return View(model);
}
Select multiple items instead of single
var moduleTypes = _db.ModuleTypes
.Select(
moduleType => new {
Id = moduleType.Id
TypeName = moduleType.TypeName}
).ToList();
var model = new CreateModule
{
TypeNames = moduleTypes.Select(m => new SelectListItem
{
Value = m.Id.ToString(),
Text = m.TypeName,
})
};
The first statement is creating anonymous object using linq, and second statement is using it to create CreateModule

Some errors in controller (asp.net mvc)

I am getting some errors in my controller.
At first, I got Suppliers List, then I got Id for all Suppliers, then I got all Users for every Supplier.
public ActionResult Grid(bool? active)
{
var suppliers = Context.Suppliers.AsNoTracking()
.WhereIf(active != null, e => e.Active == active)
.Select(e => new SupplierRow
{
Id = e.Id,
FullName = e.FullName,
Active = e.Active,
Visits = e.Visits,
})
.ToList();
List<int> supplierIds = new List<int>();
foreach (SupplierRow sr in suppliers)
{
supplierIds.Add(sr.Id);
}
var users = Context.Users.AsNoTracking()
.Where(e => supplierIds.Contains(e.SupplierId))
.Select(e => new UserRow
{
Id = e.Id,
FullName = e.FullName,
Email = e.Email,
Name = e.Name,
Status = e.Status,
Role = e.Role,
SupplierId = e.SupplierId
}).toList();
foreach (UserRow ur in users)
{
foreach (SupplierRow sr in supplier)
{
if (ur.SupplierId == sr.Id)
{
sr.Users.Add(ur);
}
}
}
return PartialView("_Grid", suppliers);
}
here
and here
What's wrong with my code? How to fix that?
The problem is that you are trying to add Guid object to a collection that only accepts int values. Your User.SupplierId is an object of type Guid? (or Nullable<Guid>), while Supplier.Id is Guid. Fix the collection by declaring it as:
List<Guid> supplierIds = new List<Guid>();
Then in you code use:
foreach(SupplierRow sr in suppliers)
{
supplierIds.Add(sr.Id);
}
Do the same thing for users except that you will have to use SupplierId.HasValue and SupplierId.Value to check whether it has a value and to read the value. This is because it is declared as nullable Guid.

MVC C# Select Where

I am trying to add filter by ID for the following:
public ActionResult Index()
{
var model = from o in new MainDBContext().OffLinePayments
select new EditOffLinePayment
{
ID = o.ID,
Amount = o.Amount
};
return View(model);
}
What I would like to do is the following:
public ActionResult Index(long? id)
{
if (id != null)
{
var model = from o in new MainDBContext().OffLinePayments
**Where Assigned_ID == id**
select new EditOffLinePayment
{
ID = o.ID,
Amount = o.Amount
};
return View(model);
}
else
{
var model = from o in new MainDBContext().OffLinePayments
select new EditOffLinePayment
{
ID = o.ID,
Amount = o.Amount
};
return View(model);
}
}
try
var model = from o in new MainDBContext().OffLinePayments
where o.Assigned_ID == id
select new EditOffLinePayment
{
ID = o.ID,
Amount = o.Amount
};
If I understand correctly, your problem is that the compiler doesn't let you write where o.Assigned_ID == id in the query.
That's because id is a Nullable<long>, which is not implicitly convertible to a long (which OffLinePayment.Assigned_ID presumably is).
You need to write where o.Assigned_ID == id.Value instead. Take a look at what the Value property does so that you don't get any surprises.
A cleaner, shorter and much more readable syntax would look like this:
public ActionResult Index(long? id){
using (var ctx = new MainDBContext())
{
var entities = ctx.OfflinePayments.Where(e => !e.HasValue || e.Assigned_ID == id.Value);
var model = entities.Select(e => new EditOfflinePayment { ID = e.ID, Amount = e.Amount }).ToList();
return View(model);
}
}

Seat Reserving system

the Image shows how my tables are setup
Update
I have a working reserve seat and add to booking table now.
//
// POST: /Home/CreateBooking
public ActionResult CreateBooking(String id, DateTime date, DateTime time)
{
ViewData["username"] = User.Identity.Name;
ViewData["performanceDate"] = date;
ViewData["Venue"] = id;
BookingCreate model = new BookingCreate();
model.Seats = (from c in _db.Seat
where c.venue == id
select c);
return this.View(model);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateBooking(BookingCreate bookingCreate, IList<String> seatNumber)
{
Customer theCustomer
= (from c in _db.Customer
select c).First<Customer>(c => c.username == bookingCreate.customer);
//performance details for the performance selected by the user
Performance thePerformance
= (from p in _db.Performance
select p).FirstOrDefault<Performance>(p => p.performanceDate == bookingCreate.performanceDate || p.performanceTime == bookingCreate.performanceTime || p.venue == bookingCreate.venue);
//performance details for the performance selected by the user
Performance seatbooking
= (from p in _db.Performance
select p).FirstOrDefault<Performance>(p => p.performanceDate == bookingCreate.performanceDate || p.performanceTime == bookingCreate.performanceTime || p.venue == bookingCreate.venue);
var now = DateTime.UtcNow;
var bookingToCreate = new Booking();
bookingToCreate.bookingDate = now;
bookingToCreate.bookingTime = now;
bookingToCreate.bookingType = "Web";
bookingToCreate.collect = true;
bookingToCreate.Customer = theCustomer;
bookingToCreate.Performance = thePerformance;
_db.AddToBooking(bookingToCreate);
_db.SaveChanges();
var bookingnumber = (from p in _db.Booking
select p.bookingNo);
foreach (var displaySeat in seatNumber)
{
Seat theseat
= (from c in _db.Seat
select c).FirstOrDefault<Seat>(c => c.seatNumber == displaySeat);
var seatBooking = new SeatBooking();
seatBooking.Booking = bookingToCreate;
seatBooking.Seat = theseat;
_db.AddToSeatBooking(seatBooking);
_db.SaveChanges();
}
return RedirectToAction("ShowsIndex");
}
The code ensures that the correct venue's seats are displayed and that the logged in user and selected performance is chosen.
What i am stuck with is..
I am currently outputting the seats as checkboxes
with
BookingCreate model = new BookingCreate();
model.Seats = (from c in _db.Seat
where c.venue == id
select c);
But I would like for the checkboxes to show what seat number they relate to (at the moment they are just a blank checkbox)
And also how to stop showing seats that have been booked to stop duplication.
Thanks
I would do it this way (providing there are surrogate primary keys Customer.Id and Performance.Id)
public class BookingToCreateVM
{
public int BookingNo{get; set;}
//..etc - all necessary booking fields
public Guid UserId{get; set;}
public Guid PerformanceId{get; set;}
//data for something like dropdowns in view
public IList<Customer> Users{get; set;}
public IList<Performance> Performances{get; set;}
}
and the controller action
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateBooking(BookingToCreateVM bookingToCreateVM)
{
Customer theCustomer
= (from c in _db.Customer
select c).Single<Customer>(c=>c.Id == bookingToCreateVM.UserId);
Performance thePerformance
= (from p in _db.Performance
select p).Single<Performance>(p=> p.Id == bookingToCreateVM.PerformanceId);
var bookingToCreate = new Booking();
bookingToCreate.BookingNo= bookingToCreateVM.BookingNo;
//..etc - initialize all necessary fields
bookingToCreate.Customer = theCustomer;
bookingToCreate.Performance = thePerformance;
_db.AddToBooking(bookingToCreate);
_db.SaveChanges();
return RedirectToAction("ListBookings");
}

Resources