The ViewData item that has the key 'distic_id' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>' - asp.net-mvc-4

In my MVC project when run and I press edit option in in view at that time this error occur
The ViewData item that has the key 'distic_id' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'
In my view code
#Html.DropDownListFor(m => m.distic_id, Model.disticlist)
model is
public class city
{
public List<SelectListItem> disticlist { get; set; }
public int city_id { get; set; }
[Required]
[Display(Name = "enter the District name")]
public string city_name { get; set; }
[Required]
[Display(Name = "select district ")]
public int distic_id { get; set; }
}

if you want to get city or dist list in a drop down list please see the following code
1) Remove your code
2) Create one Model like this
3) if this drop down is used in more than one page CREATE ONE CONTROLLER like CommanController
4) write one method in this controller
See Below code
First need to create Model like this
public class Industry
{
public string Id { get; set; }
public string industryName { get; set; }
public string regexindustry { get; set; }
}
public class IndustryModel
{
public SelectList industryList { get; set; }
}
In Controller
Two Step 1 is Create one method it return type is List
and Call this method in any ActionReslut with the use of object
ViewBag.list=obj.getIndustryList();
public List<Industry> getIndustryList()
{
List<Industry> objindustry = new List<Industry>();
var connString = new SqlConnection(ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString);
SqlCommand sqlComm = new SqlCommand("sp_selIndustryMaster", connString);
connString.Open();
sqlComm.CommandType = CommandType.StoredProcedure;
SqlDataReader sqldr = sqlComm.ExecuteReader();
int count = 0;
while (sqldr.Read())
{
if (count == 0)
{
objindustry.Add(new Industry { Id ="", industryName = "Select Industry" });
count++;
}
else
{
objindustry.Add(new Industry { Id = Convert.ToString(sqldr["industryCode"]), industryName = sqldr["subindustry"].ToString() });
}
}
return objindustry;
}
IN VIEW
#Html.DropDownListFor(model => model.txtindustry, new SelectList(ViewBag.List, "Id", "industryName", 0))
please use it your problem may be solve,

Related

Entity Framework virtual ICollections

I'm new to .NET Core Entity Framework (code-first), but do daily progress.
I am now stuck on a probably small mistake and can't go on.
I have a class list that I am trying to fill and in there there is a virtual ICollection from another list, to be filled at the same time.
These are my classes
public class UgInfo
{
public Guid UserGroupId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<UInfo> UInfo { get; set; }
}
public class UInfo
{
public string UserEmail { get; set; }
public string UserName { get; set; }
}
This is where the error occurs:
Invalid Initializer member declarator"
Code:
var ugList = (from ug in _context.Usergroups
join uug in _context.UserUsergroup on ug.UserGroupId equals uug.UsergroupId
join u in _context.Users on uug.UserId equals u.UserId
select new UgInfo
{
UserGroupId = uug.UsergroupId,
Description = ug.Description,
Name = ug.Name,
new UInfo //Error
{
UserName = u.UserName,
UserEmail = u.Email
}
}).ToList();
return ugList;
Could there be anyone who can help a beginner?
Well, you're missing the member name you're attempting to initialize, for one. Then, you need to initialize it with a collection type, not a single UInfo instance:
...
Name = ug.Name,
UInfo = new List<UInfo>
{
new UInfo
{
...
}
}
You have ICollection<UInfo> as property, and you are using new UInfo in the code. It should be new List<UInfo>.

How to bind custom model class in mvc

I am new in MVC. I am working on a project where i have created a model class and also context class which is working good if i view the record in normal view.
but if i try to get the data in group by "Series_Name" and bind it into same model class it gives error. here is my code
Here is Model class and DBContextClass
[Table("tblvideo")]
public class TVSerial
{
[Key]
public Int64 Video_ID { get; set; }
public string Series_Name { get; set; }
public string Season_No { get; set; }
public string Episode_No { get; set; }
public string Episode_Name { get; set; }
public string Time_Duration { get; set; }
public string File_Url_480p { get; set; }
public string File_Url_720p { get; set; }
public string Description { get; set; }
public bool Is_Active { get; set; }
public string Image_Url_Small { get; set; }
public string Image_Url_Big { get; set; }
}
public class TvSerialContext : DbContext
{
public DbSet<TVSerial> TvSerials { get; set; }
}
Here is controller class:
public class TvSerialController : Controller
{
public ActionResult ListAllTvSerial()
{
try
{
TvSerialContext tvContext = new TvSerialContext();
List<TVSerial> tv = tvContext.TvSerials.ToList();
return View(tv);
}
catch (Exception ex)
{
return Content(ex.Message);
}
}
}
Above code works as expected, but if i am doing this :
public ActionResult ListAllSeason(string serial)
{
try
{
TvSerialContext tvContext = new TvSerialContext();
List<TVSerial> tv = tvContext.TvSerials.Where(tvs => tvs.Series_Name == serial).Distinct().ToList();
return View(tv);
}
catch (Exception ex)
{
return Content(ex.Message);
}
}
it return all rows , i just want single row from every series_name and custom field "Series_Name,Season_No,Image_Url_Big"
i don't know how to achieve this.
getting result :
Expected result:-
You could do this by creating a view model and using a .GroupBy() clause
public class TVSerialVM
{
public string SeriesName { get; set; }
public string SeasonNo { get; set; }
public string ImageUrl { get; set; }
}
and the query to project into your view model
List<TVSerialVM> model = tvContext.TvSerials.Where(t => t.Series_Name == serial)
.GroupBy(t => new { t.Series_Name, t.Season_No, t.Image_Url_Big })
.Select(t => new TVSerialVM
{
SeriesName = t.Key.Series_Name,
SeasonNo = t.Key.Season_No,
ImageUrl = t.Key.Image_Url_Big
}).ToList();
Side note: Your duplicating data in the database (the season number and the image url). You should consider moving the image urls to another table with a relationship to the season number.
The reason you are getting multiple values even though you are using distinct is the Distinct method does not know what "equal" is for TVSerial.
You can use Distinct with IEqualityComparer.
https://msdn.microsoft.com/en-us/library/vstudio/bb338049(v=vs.100).aspx
Distinct is not guaranteed to on custom objects it doesn't know what to compare. I have used this SO in the past to make my custom object work with Distinct.
Creating a distinct list of custom type in C#

Ravendb TransformResults showing null values for properties populated with Load()

I have two documents Ticket and MenuItem i have created index with TransformResults but problem is i am getting null value for Loaded document in transform
public class Ticket
{
public int ID { get; set; }
public int ItemId { get; set; }
public string ItemName { get; set; }
public int Price { get; set; }
}
public class MenuItem
{
public int ID { get; set; }
public string ItemName { get; set; }
public string PriceCategory { get; set; }
}
i have created a index like
public class TicketItemGross : AbstractIndexCreationTask<Ticket, TicketItemGross.TicketItemDetails>
{
public class TicketItemDetails
{
public string ID { get; set; }
public string ItemId { get; set; }
public string ItemName { get; set; }
public int Price { get; set; }
public string PriceCategory { get; set; }
}
public TicketItemGross()
{
Map = docs => from doc in docs
select new
{
ID = doc.ID,
ItemId=doc.ItemId,
ItemName=doc.ItemName,
Price=doc.Price
};
TransformResults = (database, docs) => from m in docs
let d = database.Load<MenuItem>(m.ID)
select new
{
ID = m.ID,
ItemId = m.ItemId,
ItemName = m.ItemName,
Price = m.Price,
PriceCategory=d.PriceCategory
};
}
}
and the problem is that when i query data. I get null for PriceCategory but for all other fields i get correct value
here is query
IEnumerable<TicketItemGross.TicketItemDetails> list;
using (var session = store.OpenSession())
{
list = session.Query<TicketItemGross.TicketItemDetails, TicketItemGross>();
}
This is happening because you are using integer IDs. When you call database.Load in your transform, you'll need to manually convert it to a string ID.
database.Load<MenuItem>("MenuItems/" + m.ID)
This is one of several places where Raven gets confused if you use integer or guid IDs. If you use string ids, you won't have this problem.
Also, you might consider using a results transformer instead. They are easier than index transformers, which are now obsolete.

Entity Framework 6 - child property data not loading

The ManagingAgent child property on the Complex entity is not being loaded with data.... possibly the result of too much mulled wine.
I have logged the SQL on the database calls and the SQL is returning the correct data.
LazyLoading is disabled.
public ApplicationDbContext()
: base("DefaultConnection")
{
this.Configuration.LazyLoadingEnabled = false;
}
Aggregate Root
public class Complex
{
public Complex()
{
Forums = new List<Forum>();
ManagingAgent = new ManagingAgent();
}
[Key]
public int ComplexId { get; set; }
[Required]
public string Name { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
public int? PostCodeId { get; set; }
public PostCode PostCode { get; set; }
public int? LocationId { get; set; }
public Location Location { get; set; }
public int? CountyId { get; set; }
public County County { get; set; }
public int? ManagingAgentId { get; set; }
public ManagingAgent ManagingAgent { get; set; }
public int? CountOfUnits { get; set; }
public List<Forum> Forums { get; set; }
}
Attempt 1. using Include...
public List<Complex> GetComplexesByUserId(Guid userId)
{
using (var db = new ApplicationDbContext())
{
db.Database.Log = Logger;
var complexIds = db.UserApartments.Where(r => r.UserId == userId)
.Select(c => c.ComplexId).ToList();
return db.Complexes.Where(c => complexIds.Contains(c.ComplexId))
.Include(m => m.ManagingAgent).ToList();
}
}
Attempt 2 - explicitly loading ..same result (SQL returns data correctly but ManagingAgent isn't populated)
public List<Complex> GetComplexesByUserId(Guid userId)
{
using (var db = new ApplicationDbContext())
{
db.Database.Log = Logger;
var complexIds = db.UserApartments.Where(r => r.UserId == userId)
.Select(c => c.ComplexId).ToList();
var list = new List<Complex>();
foreach (var id in complexIds)
{
var complex = db.Complexes.Find(id);
db.Entry(complex).Reference(m => m.ManagingAgent).Load();
list.Add(complex);
}
return list;
}
}
So, to force the load I am doing this.... not good..
foreach (var id in complexIds)
{
var complex = db.Complexes.Find(id);
var managingAgent = db.ManagingAgents.Find(complex.ManagingAgentId);
complex.ManagingAgent = managingAgent;
list.Add(complex);
}
Remove this line...
ManagingAgent = new ManagingAgent();
...from the constructor of the Complex entity. Then it will work. (Generally don't instantiate reference navigation properties in an entity default constructor. EF calls this constructor via reflection when it materializes the entity and "gets confused" if the navigation property already has a reference. I can't explain the "gets confused" better since I don't know the exact mechanism of object materialization with related entities, but the effect is that the loaded child column values are ignored because there is already an instantiated child entity, but just with the useless default values from the ManagingAgent constructor.)

New records inserted in foreign key table when inserting in parent table

I am new to Asp.net MVC and working on a simple blog application (Asp.Net MVC5, EF6) for learning.
I am using repository pattern for the solution architecture with EF Code first migration, Ninject for DI. On the client side, I am using jQuery Grid for Admin to manage Posts, Categories and Tags.
- Blog.Model: Post.cs, Category.cs, Tags.cs
public class Post
{
[Required(ErrorMessage = "Id is required")]
public int Id { get; set; }
[Required(ErrorMessage = "Title is required")]
[StringLength(500, ErrorMessage = "Title cannot be more than 500 characters long")]
public string Title { get; set; }
[Required(ErrorMessage = "Short description is required")]
public string ShortDescription { get; set; }
[Required(ErrorMessage = "Description is required")]
public string Description { get; set; }
public bool Published { get; set; }
[Required(ErrorMessage = "PostedOn date is required")]
public DateTime PostedOn { get; set; }
public DateTime? ModifiedOn { get; set; }
[ForeignKey("Category")]
public virtual int CategoryId { get; set; }
public virtual Category Category { get; set; }
public virtual IList<Tag> Tags { get; set; }
}
public class Category
{
[Key]
public int CategoryId { get; set; }
[Required(ErrorMessage = "Category Name is required")]
[StringLength(500,ErrorMessage = "Category name length cannot exceed 500")]
public string Name { get; set; }
[Required(ErrorMessage = "Category Name is required")]
[StringLength(500, ErrorMessage = "Category name length cannot exceed 500")]
public string Description { get; set; }
[JsonIgnore]
public virtual IList<Post> Posts { get; set; }
}
public class Tag
{
public int Id { get; set; }
[Required(ErrorMessage = "Name is required")]
[StringLength(500, ErrorMessage = "Name length should not exceed 500 characters")]
public string Name { get; set; }
public string Description { get; set; }
[JsonIgnore]
public IList<Post> Posts { get; set; }
}
- Blog.Repository: BlogRepository, IBlogRepository, BlogContext
public interface IBlogRepository
{
int SavePost(Post post);
//Other methods...
}
public class BlogRepository : BlogContext, IBlogRepository
{
public BlogContext _db;
public BlogRepository(BlogContext db)
{
_db = db;
}
public int SavePost(Post post)
{
_db.Posts.Add(post);
_db.SaveChanges();
return post.Id;
}
//Other implementations...
}
public class BlogContext : DbContext, IDisposedTracker
{
public BlogContext() : base("BlogDbConnection") { }
public DbSet<Post> Posts { get; set; }
public DbSet<Tag> Tags { get; set; }
public DbSet<Category> Categories { get; set; }
public bool IsDisposed { get; set; }
protected override void Dispose(bool disposing)
{
IsDisposed = true;
base.Dispose(disposing);
}
- Blog.Web: AdminController.cs, NinjectWebCommon.cs
AdminController sends/consumes data in Json format.
public class AdminController : Controller
{
private readonly IBlogRepository _blogRepository;
public AdminController(IBlogRepository blogRepository)
{
_blogRepository = blogRepository;
}
//POST: /Admin/CreatePost
[HttpPost, ValidateInput(false)]
public ContentResult CreatePost([ModelBinder(typeof(PostModelBinder))] Post model)
{
string json;
ModelState.Clear();
if (TryValidateModel(model))
{
var id = _blogRepository.SavePost(model);
json = JsonConvert.SerializeObject(
new
{
id = id,
success = true,
message = "Post saved successfully."
});
}
else
{
json = JsonConvert.SerializeObject(
new
{
id = 0,
success = false,
message = "Post not saved."
});
}
return Content(json, "application/json");
}
}
public static class NinjectWebCommon
{
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<BlogContext>().ToSelf(); //This isn't helping either
kernel.Bind<IBlogRepository>().To<BlogRepository>();
}
}
I am using Custom Model Binding because I was getting validation exception while saving post since list of Categories and Tags received from grid do not map to actual objects in the application model. Therefore in the custom model binding, I am populating Post object with actual objects received from grid. This Post object is Sent to controller which Save to database using DbContext and Repository.
public class PostModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var post = (Post)base.BindModel(controllerContext, bindingContext);
**var blogRepository = new BlogRepository(new BlogContext());**//I think here I need to inject the dependency for BlogContext, but don't know how to do that.
if (post.Category != null)
{
post.Category = blogRepository._db.Categories.AsNoTracking().Single(c => c.CategoryId == post.Category.CategoryId);
}
var tags = bindingContext.ValueProvider.GetValue("Tags").AttemptedValue.Split(',');
if (tags.Length > 0)
{
post.Tags = new List<Tag>();
foreach (var tag in tags)
{
var id = int.Parse(tag.Trim());
post.Tags.Add(blogRepository._db.Tags.AsNoTracking().Single(t => t.Id == id));
}
}
if (bindingContext.ValueProvider.GetValue("oper").AttemptedValue.Equals("edit"))
post.ModifiedOn = DateTime.UtcNow;
else
post.PostedOn = DateTime.UtcNow;
return post;
}
}
Issue: When the Post is saved, data context inserts new rows for Category and Tags in their respective tables. The newly created post refers to new Category (Id:22) under Foreign key column.
Post:
Category:
Tag:
I think the reason for this is that when entity is saved it is attached to a different ObjectContext and I need to attach it to current context but do not know how? I found similar question asked before but there isn't an accepted answer to that. Any help would be greatly appreciated.
I was able to resolve above issue by attaching category and tags value to objectcontext manually, which indicates EF the changes it needs to make. This way it doesn't create new entries in Category and Tag's parent tables.
public int SavePost(Post post)
{
//attach tags to db context for Tags to tell EF
//that these tags already exist in database
foreach (var t in post.Tags)
{
_db.Tags.Attach(t);
}
//tell EF that Category already exists in Category table
_db.Entry(post.Category).State = EntityState.Modified;
_db.Posts.Add(post);
_db.SaveChanges();
return post.Id;
}
public void EditPost(Post post)
{
if (post == null) return;
//get current post from database
var dbPost = _db.Posts.Include(p => p.Tags).SingleOrDefault(p => p.Id == post.Id);
//get new list of tags
var newTags = post.Tags.Select(tag => new Tag() { Id = tag.Id, Name = tag.Name, Description = tag.Description }).ToList();
if (dbPost != null)
{
//get category from its parent table and assign to db post
dbPost.Category = _db.Categories.Find(post.Category.CategoryId); ;
//set scalar properties
_db.Entry(dbPost).CurrentValues.SetValues(post);
//remove tags from post in database
foreach (var t in dbPost.Tags.ToList())
{
if (!newTags.Contains(t))
{
dbPost.Tags.Remove(t);
}
}
//add tags to post in database
foreach (var t in newTags)
{
if (dbPost.Tags.All(p => p.Id != t.Id))
{
var tagInDb = _db.Tags.Find(t.Id);
if (tagInDb != null)
{
dbPost.Tags.Add(tagInDb);
}
}
}
}
//save changes
_db.SaveChanges();
}