How to validate IList foreign key? Entity Framework - c#

Please help solve my problem. I want get message if textbox TagsSites is empty.
My models:
Site:
public int Id { get; set; }
[Required]
public string UserId { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Description { get; set; }
[Required]
public string TypeMenuId { get; set; }
public virtual IList<Page> Pages { get; set; }
[Required]
public virtual IList<TagSite> TagsSites { get; set; }
public virtual TypeMenu TypeMenu { get; set; }
public virtual ApplicationUser User { get; set; }
Tag:
public int Id { get; set; }
public string Name { get; set; }
public virtual IList<TagSite> TagsSites { get; set; }
TagSite:
public int Id { get; set; }
public int SiteId { get; set; }
public int TagId { get; set; }
public virtual Site Site { get; set; }
public virtual Tag Tag { get; set; }
I now get this message for all empty inputs.
How to get message "The TagsSites field is required." ?
Thanks.

What you may want here is the MinLengthAttribute. Implementation looks something like this.
[Required]
[MinLength (1)]
public virtual IList <TagSite> TagSites { get; set; }

You should create a view model for your view with a property for a comma separated tag names and mark it with the Required attribute.
public class CreateSiteVm
{
[Required]
public string Name { set;get;}
[Required]
public string Description { set;get;}
[Required]
public string Tags { set;get;}
[Required]
public int TypeMenuId { set;get;}
public List<SelectListItem> TypeMenus { set;get;}
}
and in your GET action
public ActionResult Create()
{
var vm = new CreateSiteVm();
vm.TypeMenus = dbContext.TypeMenus.Select(x=> new SelectListItem {
Value=x.Id.ToString(),
Text=x.Name}).ToList();
return View(vm);
}
and in your view,
#model CreateSiteVm
#using(Html.BeginForm())
{
<p>#Html.ValidationSummary(false)</p>
<label>Name</label>
#Html.TextBoxFor(f=>f.Name)
<label>Descsription</label>
#Html.TextBoxFor(f=>f.Descsription)
<label>Tags</label>
#Html.TextBoxFor(f=>f.Tags)
<input type="submit" />
}
and in your HttpPost action method, create an object of your entity and set the values from view model object which is your method parameter. You can use Split method to split the comma separated string.
[HttpPost]
public ActionResult Create(CreateSiteVm model)
{
if(ModelState.IsValid)
{
var e=new Site { Name = model.Name, Description = model.Description};
e.TypeMenuId = model.TypeMenuId;
var arr = model.Tags.Split(',');
foreach (var s in arr)
{
e.Tags.Add(new Tag { Name = s});
}
dbContext.Sites.Add(e);
dbContext.SaveChanges();
return RedirectToAction("Index");
}
//to do : Load the dropdown again same as GET
return View(model);
}

Related

How to create a textbox bound to an object

I used Entity Framework to generate my controller and view for my class.
This is what I have:
DemandeController.cs (controller):
public ActionResult Create()
{
Demande model = new Demande();
model.date = DateTime.Now;
model.status = "en cours";
Employe emp = (Employe)Session["currentUser"];
model.Employe = emp;
ViewBag.ServiceID = new SelectList(db.Services, "id", "nom");
ViewBag.EmployeID = new SelectList(db.Employes, "matricule", "nom");
return View(model);
}
Demande -> Create.cshtml (View)
<div class="editor-label">
#Html.LabelFor(model => model.EmployeID, "Employe")
</div>
<div class="editor-field">
#Html.DropDownList("EmployeID", String.Empty)
#Html.ValidationMessageFor(model => model.EmployeID)
</div>
Employe class:
public partial class Employe
{
public Employe()
{
this.ActivityLogs = new HashSet<ActivityLog>();
this.Demandes = new HashSet<Demande>();
}
public int matricule { get; set; }
public int DepartementID { get; set; }
public string nom { get; set; }
public string prenom { get; set; }
public string telephone { get; set; }
public string adresse { get; set; }
public string fonction { get; set; }
public string username { get; set; }
public string password { get; set; }
public string role { get; set; }
public Nullable<bool> isAdmin { get; set; }
public virtual ICollection<ActivityLog> ActivityLogs { get; set; }
public virtual ICollection<Demande> Demandes { get; set; }
public virtual Departement Departement { get; set; }
}
Demande class:
public partial class Demande
{
public int id { get; set; }
public int EmployeID { get; set; }
public int ServiceID { get; set; }
public Nullable<System.DateTime> date { get; set; }
public string status { get; set; }
public string details { get; set; }
public virtual Service Service { get; set; }
public virtual Employe Employe { get; set; }
}
By default, because I have many employees, the view generates a dropdownlist where I have to chose the employe name. That works without problems.
However, I am trying to change the dropdownlist into a textbox that would display the currently logged-in employe which is saved in a session object.
I tried a lot of things such as saving the Employe object in the model from the Controller like you can see in the Controller code above but it did not work as the View does not save the entire object to my understanding so when I submit, it overrides the Employe object and only leaves the name attribute. It worked for the date and status because they are basic objects but not for Employe.
I tried explaining to the best of capacity, I'm fairly new to ASP.NET MVC. If there is any further information you'd like me to provide, just let me know.

Populating a page with data from a database in mvc 5

I would like to populate certain parts of a view with certain fields from a database. I'm not sure exactly how to make this work. This is my current situation...
Here is my controller action:
public ActionResult Course_page(string id)
{
string abbrev = id;
var cpage = from c in db.Course_page
select c;
if (!String.IsNullOrEmpty(abbrev))
{
cpage = cpage.Where(x => x.abbrev.Contains(abbrev));
}
return View(cpage);
}
My Model:
[Table("course_page")]
public class Course_page
{
[Key]
public int CourseID { get; set; }
public string Meta { get; set; }
public string Title { get; set; }
public string Country { get; set; }
public string main_image { get; set; }
public string list_1 { get; set; }
public string list_2 { get; set; }
public string list_3 { get; set; }
public string list_4 { get; set; }
public string list_5 { get; set; }
public string list_6 { get; set; }
public string list_7 { get; set; }
public string list_8 { get; set; }
public string list_9 { get; set; }
public string list_10 { get; set; }
public string testim_1 { get; set; }
public string testim_2 { get; set; }
public string testim_3 { get; set; }
public string course_site { get; set; }
public string popup_script { get; set; }
public string abbrev { get; set; }
}
The view (shortened):
#model IEnumerable<oltinternational_mvc.Models.Course_page>
<div id="main_container">
<article class="content">
<h1>{#Html.DisplayNameFor(modelItem => cpage.Title)}</h1>
</article>
</div>
I get that I have to reference the cpage variable somewhere on the view but I'm not sure exactly in what manner. The idea is that the course page will load with the correct details as per the ID provided by the URL.
Please could someone advise me how I am to include the cpage variable in the view file or if I am doing this the correct way at all?
You are doing it correct way just change this helper :
{#Html.DisplayNameFor(modelItem => cpage.Title)} to
#Html.DisplayNameFor(modelItem => modelItem .Title)
And print the data in foreach loop because you can have more than one result.

IList dataset insert to database table

I'm getting data set to POST action method's model object like following
Once I expand above object , it has following properties
Once I expand above ListProductFields IList , it has following properties
Once I expand above ListProductFields IList's object values , [0]th value it has following properties and its values
this is the relevant model class files
public class AddNewProduct
{
public string Product_ID { get; set; }
public string ProductTypeID { get; set; }
public string ProductCategoryID { get; set; }
public string Subsidary_ID { get; set; }
public string Field_ID { get; set; }
public string ProductFieldNameEn { get; set; }
public string ProductFieldNameAr { get; set; }
public string ApprovalStatus { get; set; }
public string Status { get; set; }
public IList<AB_ProductTypeCategoryField> ListProductFields { get; set; }
}
public partial class AB_ProductTypeCategoryField
{
public string ProductFieldID { get; set; }
public string ProductFieldNameEn { get; set; }
public string ProductFieldNameAr { get; set; }
public string ProdcutFieldDiscriptionEn { get; set; }
public string ProductFieldDiscriptionAr { get; set; }
public string Status { get; set; }
public bool IsChecked { get; set; }
public string CreatedBy { get; set; }
public Nullable<System.DateTime> CreatedDate { get; set; }
public string UpdatedBy { get; set; }
public Nullable<System.DateTime> UpdatedDate { get; set; }
public string Field_Value_EN { get; set; }
public string Field_Value_AR { get; set; }
}
public partial class AB_Product_vs_Field
{
public string Product_ID { get; set; }
public string Field_ID { get; set; }
public string Field_Value_EN { get; set; }
}
I have database table call AB_Product_vs_Field and I want to insert ,
ProductFieldID ,Field_ID , Field_Value_EN from those values from last image
since these are 19 objects have to insert to the AB_Product_vs_Field database table I may have to use a loop .
so I created following linq query to insert data to that table
[HttpPost]
[ValidateInput(false)]
public ActionResult Add_Product(AddNewProduct product)
{
AB_Product_vs_Field insertproductvalue = new AB_Product_vs_Field();
if (ModelState.IsValid)
{
for (int i = 0; i < product.ListProductFields.Count; i++)
{
insertproductvalue.Product_ID = product.Product_ID;
insertproductvalue.Field_ID = product.ListProductFields[i].ProductFieldID;
insertproductvalue.Field_Value_EN = product.ListProductFields[i].Field_Value_EN;
};
db.AB_Product_vs_Field.Add(insertproductvalue);
db.SaveChanges();
}
}
but I'm getting following error
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
I put debug point in front of this line db.AB_Product_vs_Field.Add(insertproductvalue); of my code.once this line calling its directing to following section in App_Browsers.9u0xu-_o.0.cs file
public class ApplicationBrowserCapabilitiesFactory : System.Web.Configuration.BrowserCapabilitiesFactory {
public override void ConfigureCustomCapabilities(System.Collections.Specialized.NameValueCollection headers, System.Web.HttpBrowserCapabilities browserCaps) {
}
this is the error page I'm getting once this line called
these are the images of error
Image 1:
Image 2:
I added the following line in the for loop, then it can keep a record of every tuple
#Html.HiddenFor(m => m.ListProductFields[i].ProductFieldID)
then my view page appeared like this
<div class="col-md-10">
#Html.HiddenFor(m => m.ListProductFields[i].ProductFieldID)
#Html.TextAreaFor(m => m.ListProductFields[i].Field_Value_EN,
new { #class = "form-control summernote", #row = 5 })
</div>

How to define model property for master detail

I have a post model that for every post it's need to define category and tag , and from category or tag I wanna to reach all of posts that have that category of tag.
this is my blog model
public class Post
{
public Guid Id { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public string Summary { get; set; }
public DateTime CreationDate { get; set; }
public string UrlSlug { get; set; }
public Category Category { get; set; }
public Tag Tag { get; set; }
}
and this is Category:
public class Category
{
public Guid Id { get; set; }
public string Name { get; set; }
public string UrlSlug { get; set; }
public string Description { get; set; }
public DateTime CreationDate { get; set; }
public IList<Post> Posts { get; set; }
}
and finally this tag model:
public class Tag
{
public Guid Id { get; set; }
public string Name { get; set; }
public string UrlSlug { get; set; }
public string Description { get; set; }
public DateTime CreationDate { get; set; }
public IList<Post> Posts { get; set; }
}
I just want to know what I've done in designing model is right or not ??
You dont need the lists in the model ( remove public IList Posts { get; set; }
First create two get actions in the controller that takes tag ID, and the other`category ID. Inside the this actions get all the posts and populate your View ( detail view)
public ActionResult PostsByCategoryID(Guid Id)
{
List<post> posts = ///get them by id
return View(posts) ; //the view take list and displays the posts
}

LINQ / EF - Using GroupBy to return values to a View

In my MVC 3 application I'm using the following query:
var items = context.QuoteLines.Include("DaybookVehicles").Where(x => x.EnquiryID == id).GroupBy(x=>x.VehicleID).ToList();
return View(items);
Then in my view I have this at the top:
#model IEnumerable<myApp.Areas.DayBook.Models.DayBookQuoteLines>
But this throws an error:
The model item passed into the dictionary is of type
'System.Collections.Generic.List`1[System.Linq.IGrouping`2[System.Int32,myApp.Areas.DayBook
.Models.DayBookQuoteLines]]', but this dictionary requires a model item of type
'System.Collections.Generic.IEnumerable`1[myapp.Areas.DayBook.Models.DayBookQuoteLines]'.
How do I use a group by in this case? As I'd like to group each of my QuoteLines to their matching VehicleID
Edit
QuoteLines Model:
public class DayBookQuoteLines
{
[Key]
public int QuoteLineID { get; set; }
public int EnquiryID { get; set; }
public virtual int VehicleID { get; set; }
public virtual DaybookVehicles Vehicle { get; set; }
[Required(ErrorMessage = "This field is required.")]
[Display(Name = "Item Number:")]
[MaxLength(50)]
public string ItemNumber { get; set; }
public string ItemDescription { get; set; }
}
Vehicles Model:
public class DaybookVehicles
{
[Key]
public int VehicleID { get; set; }
public int EnquiryID { get; set; }
public virtual ICollection<DayBookQuoteLines> QuoteLines { get; set; }
public string vrm { get; set; }
public string make { get; set; }
public string model { get; set; }
public string engine_size { get; set; }
public string fuel { get; set; }
}
I think I have this setup correctly, but each Vehicle can have a collection of QuoteLines attached to it!
The model type is different from the type returned by the function .I think that the appropriate model for this view is
#model IEnumerable<IGrouping<int, DayBookQuoteLines>>
and there is no need for the ToList at the query

Categories