I am using a class to store data and then using controller and a view to show the data on the screen on a Website using MVC3 however I am coming across an error, help would be appreciated.
Class:
public class SampleData : DropCreateDatabaseIfModelChanges<TicketBookingEntities>
{
protected override void Seed(TicketBookingEntities context)
{
var productions = new List<Production>
{
new Production { Name = "Peter Pan" },
new Production { Name = "Mary Poppins" },
new Production { Name = "Pirates of the Carribean" },
new Production { Name = "Joseph" },
new Production { Name = "Billy Elliot" },
};
var directors = new List<Director>
{
new Director { Name = "Jason Brown" },
new Director { Name = "Dan Elish" },
new Director { Name = "Lee Hall" },
new Director { Name = "Billie Armstrong" },
new Director { Name = "Willy Russell" },
};
new List<Performance>
{
new Performance {Title = "Test", Genre = productions.Single(g => g.Name == "Peter Pan"), Director = directors.Single(a => a.Name == "Jason Brown"), Price = 9.99M, AlbumArtUrl = "/Content/Images/placeholder.gif" },
}.ForEach(a => context.Performances.Add(a));
}
}
}
Controller:
public ActionResult Browse(string genre)
{
var productionModel = storeDB.Productions.Include("Performances")
.Single(g => g.Name == genre);
return View(productionModel);
}
View:
#model Assignment2.Models.Production
#{
ViewBag.Title = "Browse";
}
<h2>Browsing Production: #Model.Name</h2>
<ul>
#foreach (var performance in Model.Performances)
{
<li>
#performance.Title
</li>
}
</ul>
The Error:
Sequence contains no elements
You don't have a list, you only have one element. Take out the foreach loop.
Managed to solve the issue, changed genre to production on the controller
Related
var query = _sqlDbContext.RequestTemplates
.Select(rt => new TemplateViewModel
{
templateName = rt.TemplateName,
requests = _sqlDbContext.RequestTemplateItems
.Where(ti => ti.RequestTemplateID == rt.RequestTemplateID)
.Select(ti => new RequestViewModel
{
category = new CategoryViewModel
{
categoryId = ti.RequestCategoryID,
categoryName = ti.RequestCategory.RequestCategoryName
},
items = new List<ItemViewModel> { new ItemViewModel
{
itemName = ti.ItemName,
dueDate = ti.DueDate,
notes = ti.Notes
}}
})
.ToList()
});
As per above LINQ query I am getting below result :-
"requests":[
{
"category":{
"categoryId":2,
"categoryName":"2"
},
"items":[
{
"itemName":"2 Item 1",
"dueDate":"",
"notes":"Item 1 Note"
}
]
},
{
"category":{
"categoryId":2,
"categoryName":"2"
},
"items":[
{
"itemName":"2 Item 2",
"dueDate":"",
"notes":""
}
]
}
for same category id , items are returning two time . i was unable to find where i need to add grouping to get below output
"requests":[
{
"category":{
"categoryId":2,
"categoryName":"2"
},
"items":[
{
"itemName":"2 Item 1",
"dueDate":"",
"notes":"Item 1 Note"
},
{
"itemName":"2 Item 2",
"dueDate":"",
"notes":"Item 1 Note"
}
]
}
Model information as below
RequestTemplates having list of RequestTemplateItem with primary key RequestTemplateID.
RequestTemplateItem having object of RequestTemplate and RequestCategory with FK_RequestTemplateID and FK_RequestCategoryID.
Haven't tested but something like this should work:
var query = _sqlDbContext.RequestTemplates
.Select(rt => new TemplateViewModel
{
templateName = rt.TemplateName,
requests = _sqlDbContext.RequestTemplateItems
.Where(ti => ti.RequestTemplateID == rt.RequestTemplateID)
.GroupBy(ti => ti.RequestCategoryId)
.Select(group => new RequestViewModel
{
category = new CategoryViewModel
{
categoryId = group.Key,
categoryName = group.First().RequestCategoryName
},
items = group.select(ti => new ItemViewModel
{
itemName = ti.ItemName,
dueDate = ti.DueDate,
notes = ti.Notes
}
})
.ToList()
});
I have two classes:
class Location
{
public string Address { get; set; }
}
class Person
{
public string Address { get; set; }
public string Name { get; set; }
}
And then I create two lists of objects:
var locations = new List<Location>()
{
new Location()
{
Address = "AA"
},
new Location()
{
Address = "BB"
},
new Location()
{
Address = "CC"
},
new Location()
{
Address = "BB"
}
};
var people = new List<Person>()
{
new Person()
{
Address = "BB",
Name = "Foo"
},
new Person()
{
Address = "CC",
Name = "Bar"
},
new Person()
{
Address = "AA",
Name = "xxx"
},
new Person()
{
Address = "BB",
Name = "yyy"
},
};
What I want is to sort the people list by matching Address property in the locations list. This is the result I would like to have:
xxx
Foo
Bar
yyy
I tried with this code:
var orderedPeopleList = people.OrderBy(p => locations.FindIndex(l => l.Address.Equals(p.Address)));
But it is not working correctly and the two last lines are in the wrong order. What is the best way to do this ordering with linq?
var orderedPeopleList = new List<Person>();
foreach (var location in locations)
{
var foundPeople = people.Where(p => p.Address == location.Address).FirstOrDefault();
if (foundPeople != null)
{
orderedPeopleList.Add(foundPeople);
people.Remove(foundPeople);
}
}
just do it :
locations= locations.OrderBy(x => x.Address).ToList();
var orderedPeopleList=new List<Person>();
for (var i = 0; i < locations.Count(); i++)
{
peopelOrderedList.Add(people.FirstOrDefault(x => x.Address == locations[i].Address && peopelOrderedList.All(c => c.Name != x.Name)));
}
peopelOrderedList.RemoveAll(x => x == null);
If I have objects, lets call them Group that has list of some other objects I will call it Brand, and this object has a list of objects called Model.
Is there a way to get only list of Models using MongoDb c# driver.
I tried using SelectMany multiple times but with no success. If I put more than one SelectMany I always get an empty list.
Code should be self-explanatory.
At the end is comment that explains what confuses me.
class Group
{
[BsonId(IdGenerator = typeof(GuidGenerator))]
public Guid ID { get; set; }
public string Name { get; set; }
public List<Brand> Brands { get; set; }
}
class Brand
{
public string Name { get; set; }
public List<Model> Models { get; set; }
}
class Model
{
public string Name { get; set; }
public int Produced { get; set; }
}
class Program
{
static void Main(string[] args)
{
MongoClient client = new MongoClient("mongodb://127.0.0.1:32768");
var db = client.GetDatabase("test");
var collection = db.GetCollection<Group>("groups");
var fca = new Group { Name = "FCA" };
var alfaRomeo = new Brand { Name = "Alfra Romeo" };
var jeep = new Brand { Name = "Jeep" };
var ferrari = new Brand { Name = "Ferrari"};
var laFerrari = new Model { Name = "LaFerrari", Produced = 4 };
var wrangler = new Model { Name = "Wrangler", Produced = 3 };
var compass = new Model { Name = "Compass", Produced = 8 };
var giulietta = new Model { Name = "Giulietta", Produced = 7 };
var giulia = new Model { Name = "Giulia", Produced = 8 };
var _4c = new Model { Name = "4C", Produced = 6 };
fca.Brands = new List<Brand> { ferrari, alfaRomeo, jeep };
ferrari.Models = new List<Model> { laFerrari };
jeep.Models = new List<Model> { wrangler, compass };
alfaRomeo.Models = new List<Model> { giulietta, giulia, _4c };
collection.InsertOne(fca);
Console.WriteLine("press enter to continue");
Console.ReadLine();
var models = collection.AsQueryable().SelectMany(g => g.Brands).SelectMany(b => b.Models).ToList();
Console.WriteLine(models.Count); //returns 0 I expected 6
Console.ReadLine();
}
}
Try
var models = collection.AsQueryable()
.SelectMany(g => g.Brands)
.Select(y => y.Models)
.SelectMany(x=> x);
Console.WriteLine(models.Count());
Working output (with extra Select())
aggregate([{
"$unwind": "$Brands"
}, {
"$project": {
"Brands": "$Brands",
"_id": 0
}
}, {
"$project": {
"Models": "$Brands.Models",
"_id": 0
}
}, {
"$unwind": "$Models"
}, {
"$project": {
"Models": "$Models",
"_id": 0
}
}])
OP Output without extra Select()
aggregate([{
"$unwind": "$Brands"
}, {
"$project": {
"Brands": "$Brands",
"_id": 0
}
}, {
"$unwind": "$Models"
}, {
"$project": {
"Models": "$Models",
"_id": 0
}
}])
Theres links already on how to use multiple models for a view with different ways to do it, however, I tried those and could not get them to work, what am I doing wrong?
I simply want two form inputs in 1 view, and one model, but one of the form inputs uses a list<'model'> and the other uses 'model', here's what I mean:
UPDATE: copy/paste this code, if you select and submit any check box items you will get an error at #Model.input.passWord and I have no idea why, checkbox items wont show either, need help.
View (Index.cshtml):
#using stupidassTests.Models
#model MyViewModel
#{
ViewBag.Title = "Index";
}
<h2>Password Input</h2>
<div>
<p>Enter Password</p>
#using (Html.BeginForm("Index", "Home", FormMethod.Get))
{
#Html.TextBox("password")
<button type="submit" value="Search"></button>
}
<p>#Model.input.passWord</p> <!--passWord is underlined with red because it conflicts with the List'model'-->
</div>
<h2>Checkbox</h2>
<div>
#using (Html.BeginForm())
{
for (var i = 0; i < Model.inputCollection.Count; i++)
{
<p>
#Html.HiddenFor(n => n.inputCollection[i].Id)
#Html.DisplayFor(n => n.inputCollection[i].Name)
#Html.HiddenFor(n => n.inputCollection[i].Name)
#Html.CheckBoxFor(n => n.inputCollection[i].Checked)
</p>
}
<input id="Submit1" type="submit" value="submit" />
if (ViewBag.Values != null)
{
foreach (var item in ViewBag.Values)
{
<p>#item</p>
}
}
}
So as you can see, copy/paste my code and try to run it, 'password' form input is being shoved out by 'checkbox' input, it seems the two '#model' are conflicting under one model class, how do I fix this?
Controller (HomeController.cs):
public ActionResult Index()
{
return View();
}
[HttpGet, ActionName("Index")]
public ActionResult PasswordInput(string password)
{
FormInputs pss = new FormInputs();
pss.passWord = password;
MyViewModel mvm = new MyViewModel() { input = pss, isList = false };
return this.View("Index", mvm);
}
[HttpGet]
public ActionResult CheckBoxGet()
{
var list = new List<FormInputs>
{
new FormInputs { Id = 1, Name = "Aquafina", Checked = false },
new FormInputs { Id = 2, Name = "Mulshi Springs", Checked = false },
new FormInputs { Id = 3, Name = "Alfa Blue", Checked = false },
new FormInputs { Id = 4, Name = "Atlas Premium", Checked = false },
new FormInputs { Id = 5, Name = "Bailley", Checked = false },
new FormInputs { Id = 6, Name = "Bisleri", Checked = false },
new FormInputs { Id = 7, Name = "Himalayan", Checked = false },
new FormInputs { Id = 8, Name = "Cool Valley", Checked = false },
new FormInputs { Id = 9, Name = "Dew Drops", Checked = false },
new FormInputs { Id = 10, Name = "Dislaren", Checked = false },
};
MyViewModel mvm = new MyViewModel() { inputCollection = list, isList = true };
return this.View("Index", mvm);
}
[HttpPost]
public ActionResult CheckBoxPost(List<FormInputs> list)
{
var selected = list.Where(x => x.Checked).Select(x => x.Name);
ViewBag.Values = selected;
MyViewModel mvm = new MyViewModel() { inputCollection = list, isList = true };
return this.View("Index", mvm);
}
Model (FormInputs.cs):
public class MyViewModel
{
public FormInputs input;
public List<FormInputs> inputCollection;
public bool isList;
}
public class FormInputs
{
public string passWord = "";
public int Id { get; set; }
public string Name { get; set; }
public bool Checked { get; set; }
public List<string> checkBox = new List<string>();
}
So just as a summary, because I'm a beginner at MVC, how do I re-work this code (btw copy/paste it) so that both form inputs can co-exist in 1 view?
You can use viewmodel.
Use ViewModel
For view model you have to create a class and in this class you will define all models as properties of this class.Here are two classes.
public class EmployeeDetails
{
[Required]
[Display(Name = "Name")]
public string Name { get; set; }
}
public class Employee
{
public int Id { get; set; }
}
Here is viewmodel
public class ViewModel
{
public Employee emp { get; set; }
public EmployeeDetails empdet{ get; set; }
}
Now in Controller you will do like this
public ActionResult About()
{
ViewModel vm = new ViewModel();
vm.emp = new Employee();
vm.empdet = new EmployeeDetails();
return View(vm);
}
And in view you will receive it like this
#model ViewModel
This might be a good example to use the Composite Pattern. You can have a ViewModel with two properties:
public class MyViewModel{
public FormInputs input;
public List<FormInputs> inputCollection;
public bool isList;
}
And arrange the data accordingly:
public ActionResult PasswordInput(string password)
{
FormInputs pss = new FormInputs();
pss.passWord = password;
MyViewModel mvm = new MyViewModel(){input = pss, isList = false}
return this.View("Index", mvm);
}
AND
public ActionResult CheckBoxGet()
{
var list = new List<FormInputs>
{
new FormInputs { Id = 1, Name = "Aquafina", Checked = false },
new FormInputs { Id = 2, Name = "Mulshi Springs", Checked = false },
new FormInputs { Id = 3, Name = "Alfa Blue", Checked = false },
new FormInputs { Id = 4, Name = "Atlas Premium", Checked = false },
new FormInputs { Id = 5, Name = "Bailley", Checked = false },
new FormInputs { Id = 6, Name = "Bisleri", Checked = false },
new FormInputs { Id = 7, Name = "Himalayan", Checked = false },
new FormInputs { Id = 8, Name = "Cool Valley", Checked = false },
new FormInputs { Id = 9, Name = "Dew Drops", Checked = false },
new FormInputs { Id = 10, Name = "Dislaren", Checked = false },
};
MyViewModel mvm = new MyViewModel(){inputCollection = list , isList = true}
return this.View("Index", mvm);
}
AND in view, use this:
#model MyViewModel
Check the isList property before using the input/inputCollection
I got the requirement to serialize my C# class RoomType like the below
public class RoomType
{
public string name { get; set; }
public string url { get; set; }
public string desc { get; set; }
}
to the below json format like this
"room_types" :
{
"Fenway Room" :
{
"url" : "http://www.partner-site.com/hotel_commonwealth/fenway_room",
"desc" : "One king bed with pillowtop mattress, Frette Italian linens, down bedding, multiple pillows. View of Fenway Park."
},
"Commonwealth Room" :
{
"url" : "http://www.partner-site.com/hotel_commonwealth/commonwealth_room",
"desc" : "One king bed with pillowtop mattress, Frette Italian linens, down bedding, multiple pillows. View of Commonwealth Avenue."
}
}
How to get the "Fenway Room" and "Commonwalth Room" to in this json format?
I tried the suggestion but still can't get how the anonymous fit into what i needed in the ActionResult. Here's my not working code now:
var rooms = new List<HarRoomType>()
{
new HarRoomType()
{
}
};
var anonymous = new
{
type = rooms.ToDictionary(x => x.name, x => new {x.currency, x.discounts})
};
var response = new HotelAvailabilityResponse()
{
api_version = 4,
hotel_ids = new List<int>()
{
1,
2
},
start_date = "2014-02-21",
hotels = new List<HarHotel>()
{
new HarHotel()
{
hotel_id = 1,
room_types = anonymous
},
new HarHotel()
{
hotel_id = 2,
room_types = new List<HarRoomType>()
}
}
};
return Json(response, JsonRequestBehavior.AllowGet);
You need to shape the data as a dictionary:
RoomType[] rooms = ...
var serializeThis = new {
room_types = rooms.ToDictionary(
x => x.name,
x => new { x.url, x.desc }
)
};
JavaScriptSerializer js = new JavaScriptSerializer();
List<RoomType> roomTypes = new List<RoomType>(){
new RoomType{ desc="desc 1", name="Fenway Room", url="blah.com"},
new RoomType{ desc="desc 2", name="Commonowealth Room", url="blah.com"},
};
If you don't care about having the name show up as a property, then:
var json = js.Serialize(roomTypes.ToDictionary(x => x.name));
If you do care about having the name show up and don't want it to:
var json2 = js.Serialize(roomTypes.ToDictionary(x => x.name, x => new { desc = x.desc, url = x.url }));
Use this:
var anonymous= new {
type= rooms.ToDictionary(
x => x.name,
x => new { x.url, x.desc }
)