Okay, so I'm in the middle of an ASP.NET project in work at the minute and it's all going well. So far I have all the models, views and controllers made and they all work perfectly, but now I have been told that I need to make a class (lets just call it results to make life easy here) to display all the data. This is an example I was given for what the displayed results would look like:
There are multiple different displays at the moment for different things like a person, travel insurance, car insurance etc. and the only common things between each different display are the full name, contact email, contact number, contact address and recorded time stamp. It's the additional data that changes for each display depending on what is being requested, i.e., person displays all the information stored about the person like full name, age, DOB, mobile number, home address and so on while travel insurance displays all information stored about the travel insurance for the person who is asking like the trip type, trip destination, group type (single/couple/family/friends), travelers ages and so on..
My question is this: how do I create this results class to display the required data? Do I need another controller, model and view or do I just need to create a class called Result and put everything into that? (I think I just have to create a class but I am not sure, hence why I am asking) Also, how do I make it in such a way that different things are displayed in the additional data depending on what the person searched for? Like I don't need all the additional data about car insurance appearing when a person searched their travel insurance - does this mean I will need multiple forms of the results class which all refer to a different searchable thing or can everything go in the one class?
Apologies if this is awfully worded and/or a bad question - I did try looking for something to help myself before posting here but I couldn't find anything. I'm also quite new to the whole ASP.NET front so apologies if I'm missing anything obvious.
Create a base Model class and put all the common properties to be displayed in that, and derive other Model classes from that class with their specific properties in them. You can pass Person object to the view where Person's info need to be displayed and TravelInsurance object where Travel Insurance's info needs to be displayed.
public class ModelBase
{
public string FullName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
public DateTime TimeStamp { get; set; }
}
public class Person : ModelBase
{
public string DateOfBirth { get; set; }
public string MobileNumber { get; set; }
}
public class TravelInsurance : ModelBase
{
public string TripType { get; set; }
public string TripDestination { get; set; }
}
If that does not sound like the way to go, you can have a generic Model class with a generic Data property within it:
public class Model<T>
{
public string FullName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
public DateTime TimeStamp { get; set; }
public T Data { get; set; }
}
public class Person
{
public string DateOfBirth { get; set; }
public string MobileNumber { get; set; }
}
public class TravelInsurance
{
public string TripType { get; set; }
public string TripDestination { get; set; }
}
where you can pass objects to your view like this:
var x = new Model<Person> { FullName = "...", Data = new Person { } };
OR
var x = new Model<TravelInsurance> { FullName = "...", Data = new TravelInsurance { } };
Related
What's the easiest way to reformat data shown in the second view ?
I use .Net in the backend and Angular in the frontend.
I have a method that returns collection of attendances that has a collection of users with their statuses, and I can filter them to only query data in a date range.
I have no idea how to get the same data to get shown by users, since database structure is as follows:
Training has many schedules.
Schedules have Many Attendances.
Attendances have many Attendants and every Attendant has his status.
Now its easy to show data by attendances, but its impossible for me to figure out how to show data by attendants(users) to show all their attendances.
Is there any example someone could provide on something similar and how to do it in Asp, or angular.
I have tried creating new dto models, but I cant get neccessary data without using many queries, and mapping data too many times.
I have searched similar questions but didn't find anything relevant.
EDIT:
I am looking for the simplest solution.
I would like to know how to solve this both ways, and I can't decide which way is better ?
Here is the current method, which works for the first view:
public ICollection<AttendanceModel> ScheduleLog(int scheduleId, SearchAttendancesModel searchAttendances)
{
if (searchAttendances == null)
throw new ArgumentNullException("searchAttendances");
if (searchAttendances.Attendants == null)
throw new ArgumentNullException("searchAttendances.Attendants");
if (searchAttendances.AttendantStatuses == null)
throw new ArgumentNullException("searchAttendances.AttendantStatuses");
var query = _context
.Attendances
.Where(x=>x.ScheduleId==scheduleId)
.AsQueryable();
if (searchAttendances.FromDate != DateTime.MinValue)
{
query = query.
Where(x => x.Date >= searchAttendances.FromDate);
}
if (searchAttendances.ToDate != DateTime.MinValue)
{
query = query.
Where(x => x.Date <= searchAttendances.ToDate);
}
return query.ToList().Select(x => x.MapToAttendanceModel()).ToList();
}
It gets me the neccesary data to show for the first view, which I can easily show with tables thoru ng-repeat, but as I already said, I have many difficulties grouping data by user instead of by schedule, and then showing that data(all attendances per user) instead of all users per attendance.
Here is how my models look like:
This is schedule that has all the attendances:
public class ScheduleModel
{
public int Id { get; set; }
[Required]
public DateTime StartDate { get; set; }
[Required]
public DateTime EndDate { get; set; }
public string Description { get; set; }
public virtual ICollection<AttendanceModel> Attendances { get; set; }
}
This is attendance that has date for attendance and collection of attendants each of which have user and their status.
public class AttendanceModel
{
public int Id { get; set; }
[Required]
public DateTime Date { get; set; }
[Required]
public virtual ICollection<AttendantModel> Attendants { get; set; }
}
This is one Attendant that has user and status for that attendance
public class AttendantModel
{
public int Id { get; set; }
public virtual LookupModel ApplicantStatus { get; set; }
public virtual UserModel User { get; set; }
}
I'm quite stuck with ASP MVC Model's, Now I understand how to create a simple model so I could set some values like this:
namespace build_01.Models
{
public class NewBooking
{
public int bookingID { get; set; }
public string bookingName { get; set; }
}
}
Now what I'm trying to do is have a Model that has all the bookingNames for example such as:
namespace build_01.Models
{
public class BookingNames
{
public string administrator { get; set; }
public string normal { get; set; }
public string user { get; set; }
}
}
However, what I would like to do is get this data from a database, for example I could have adminsistrator, normal, user, superuser, banned or whatever I like but the idea is that this information in the database can be changed. The bookingNames can be added, edited or deleted.
So let's say I just added superuser and banned to the database my model would now look like this for when I send it to the view and submit a form from the view to send to the HTTPPOST controller:
namespace build_01.Models
{
public class BookingNames
{
public string administrator { get; set; }
public string normal { get; set; }
public string user { get; set; }
public string superuser { get; set; }
public string banned { get; set; }
}
}
In my view I'm basically making checkboxes based on this information however I need to be able to set and get the values in a model so I can access them in my HTTPOST controller.
Now i've had a look at the Entity Framework but that doesn't seem to be what I want.
Is it possible to be able to create a model with the actual rows or even a column from a row in order to send it to the view to create a form for those columns so that I can return the values to the HTTPPOST in order to input data into a row in a table?
If so how can I approach this?
I got 2 Models with 1-1 relationship.
public class CustomerModel
{
public int Id { get; set; }
public string Name { get; set; }
public AddressModel Address { get; set; }
}
public class AddressModel
{
public int Id { get; set; }
public string Street { get; set; }
}
Now I need a view that I can link the Address model with the customer, so, in the create of the customerModel, it bring the address create too, and linked, like in the post the address will be in the customer field.
#model Mvc.Models.CustomerModel
#Html.EditorForModel(Model)
#Html.EditorFor(x => x.Address)
If you create your view like that, you will then able to post back to an action result that takes a CustomerModel and the binding should work correctly
You'll probably want to do a bit more with custom annotations etc. as I doubt you'll want the user to be able to edit the Address id, but that should point you in the right direction
I'm tying myself in knots - and thought it best to take a big step back, and back to basics.
I understand I should be using a ViewModel, so that is what I'm trying to contruct.
My demo app will have 4 sections (4 different parts of a form to complete):
Get Date/Number of days from user
Use that data to query the database, and return a list of qualifying records - each of these will have a unique ID of TypeID - and for each of these, they should also have 2 dynamic DropDownLists associated with them (so that whatever is selected in ListBox3 for each of the lists, corresponds to the TypeID3 (and whatever ID that has)
user will then be able to select Extras, again from a drop down list populated dynamically
users Name/Add/Tel will be collected
My "View" of what the ViewModel needs to look like/hold is:
I beleive my viewModel should look something like this:
public class SearchViewModel
{
public DateTime Date{ get; set; }
public int Days { get; set; }
public IQueryable<TypeID> TypeIDs { get; set; }
public IQueryable<LB1Item> LB1Items { get; set; }
public IQueryable<LB2Item> LB2Items { get; set; }
public IQueryable<Extras> Extras { get; set; }
public string Name { get; set; }
public string Add { get; set; }
public string Tel { get; set; }
public string email { get; set; }
}
First of all - is this how you would construct a ViewModel for what I've described above? I'm not certain of the DropDown Boxes, as for each form, there could be 1, 2, 3....10, 11, 12 for each TypeID retrieved - based on the Date selected.
Each of the drop down boxes for LB1Item and LB2Item - need to have their selected values stored against the TypeID for each line also.
This is what I think the class should look like for 1 drop down:
public class LB1Item
{
public String TypeName { get; set; }
public long TypeID { get; set; }
public int NumSelected { get; set; }
public int TypeCount { get; set; }
public IEnumerable<SelectListItem> CarsAvail
{
get
{
return new SelectList(
Enumerable.Range(0, TypeCount+1)
.OrderBy(typecount => typecount)
.Select(typecount => new SelectListItem
{
Value = typecount.ToString(),
Text = typecount.ToString()
}
), "Value", "Text");
}
}
}
Does that look ok also? Or am I overcomplicating what I'm trying to achieve?
I'd also like, after POSTing back the data after each stage (1, 2, 3, 4) to be actively populating the ViewModel with the selected values - and passing it back down to the view, so that I can retrieve it for the next Step.
What I want to end up with is something like this:
Date: 01/09/2012
Days: 4
{ List:
TypeID: 3059 ListBox1: 2 ListBox2: 8748,
TypeID: 2167 ListBox1: 7 ListBox2: 2378,
TypeID: 4983 ListBox1: 4 ListBox2: 5873
}
{List:
ExtraID: 4324,
ExtraID: 3878,
ExtraID: 4872,
ExtraID: 7698,
ExtraID: 2873
}
Name: Mark
Add: My town
Tel: 0912378
Email: me#me.com
Thanks for any help/pointers/samples...
Mark
For this type of solution I would separate out each section you want to render as individual views and use Ajax calls using Jquery ajax method. I would also use KnockoutJS to handle the views in your client. So you will essentially have two ViewModels, one in JavaScript in the client and one in MVC for returning the pieces you need as JSON for the Ajax calls from the client. Section 1 of your view is entered by the user into the client so you do not need it on the Controller side. Section 1 is basically the data used to query for Section 2. No need to make your collections IQueryable either since you will not being querying the lists that are returned. Your ViewModel on the Controller side might look something like this:
public class Section2
{
public List<TypeID> TypeIDs { get; set; }
public List<LB1Item> LB1Items { get; set; }
public List<LB2Item> LB2Items { get; set; }
}
public class Section3
{
public List<Extras> Extras { get; set; }
}
public class Section4
{
public string Name { get; set; }
public string Add { get; set; }
public string Tel { get; set; }
public string email { get; set; }
}
So the steps that would be taken are that when an event is thrown that the date and days have been entered by the user an Ajax call is made back to a controller with entered data and days to query for the information that will populate Section 2. The controller returns the Section2 ViewModel as JSON and it is rendered in the HTML using Knockout. Then when the user selects from the lists in Section 2 an event is thrown to query the controller again to return the information needed to populate Section 3, and the cycle is repeated.
There is an excellent example on using Knockout to do exactly what you are trying to do here.
I have following domain objects in my application:
[Serializable]
public class Supplier
{
public virtual string SupplierType { get; set; }
public virtual string SupplierCode { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
public virtual string Rating { get; set; }
public virtual string WebsiteURL { get; set; }
public virtual IList<Address> Address { get; set; }
}
[Serializable]
public class CargoSupplier : Supplier
{
public virtual IList<Image> Images { get; set; }
public virtual string OpeningTime { get; set; }
public virtual string ClosingTime { get; set; }
public virtual IList<Product> Products { get; set; }
}
I have to goto two seperate repositories for getting descriptive content (from database) and pricing (from external webservice) and will have two seperate enumerations populated with data (descriptive content & pricing):
IEnumerable<CargoSupplier> cargoSuppliers_Pricing
IEnumerable<CargoSupplier> cargoSuppliers_Content
cargoSuppliers_Content will have all fields populated with data EXCEPT IList<Product> and cargoSuppliers_Pricing will have SupplierType, SupplierCode and IList<Product> fields populated with data. Combination of "SupplierType" amd "SupplierCode" would be the key.
Now I have to merge the content and pricing into one enumeration so I can return IEnumerable<CargoSupplier> cargoSuppliers to my Controllers & Views. What is the best way to merge/consolidate these two lists into one?
Are you looking for Union or am i missing something in the question?
var mergedList = list1.Union(list2).ToList();
remember to import the System.Linq namespace
It sounds like you don't want one list that just contains all the items in either list - it sounds like you need to merge individual items. Something like this:
var query = from pricing in cargoSuppliers_Pricing
join content in cargoSuppliers_Content
on pricing.SupplierCode equals content.SupplierCode
select new CargoSupplier
{
// Copy properties from both objects here
};
Within the "select" part you would take the pricing parts from "pricing" and the content parts from "content", building a CargoSupplier object which has both bits.
Is that what you were after?
Use Enumerable.Concat:
Concatenates two sequences.
Example:
var result = cargoSuppliers_Content.Concat(cargoSuppliers_Pricing);
Seen the Union() extension method? That should do what your after
IEnumerable<CargoSupplier> allCargoSuppliers = cargoSuppliers_Pricing.Union(cargoSuppliers_Content);