I have the following model.
public class Customer
{
[Key]
public int CustomerId { get; set; }
public string CustomerName { get; set; }
public DateTime RegisteredDate { get; set; }
}
From the model, I generate scaffold controller. Then I have the following code:
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var obj = await _db.Customers.FindAsync(id);
if (obj == null)
{
return NotFound();
}
return View(obj);
}
It will triggered when user clicked the edit link on the table. But, the RegisteredDate didn't retrieved to the view. I have the following view:
<input asp-for="CustomerId" hidden />
<input asp-for="CustomerName" />
<input asp-for="RegisteredDate" />
Why the RegisteredDate didn't load to the view? But If I add type="datetime", the data is loaded. The problem is, DateTime picker dropdown is not appears.
1st pic is without type="datetime" and 2nd pic is with type="datetime" (notice there's no datetime picker icon on it).
please advice.
thank you.
in your customer class add Datatype to RegisteredDate like this
public class Customer
{
[Key]
public int CustomerId { get; set; }
public string CustomerName { get; set; }
[DataType(DataType.Date)]
public DateTime RegisteredDate { get; set; }
}
Related
I have this classes and a WebApi method to POST the Item.
After inserting Item i want it to insert the inserted PK ItemId and given CategoryId into CategoryItem
public partial class Item
{
public int Id { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
public string? Type { get; set; }
}
public partial class Category
{
public int Id { get; set; }
public string? Description { get; set; }
public string? Name { get; set; }
}
public partial class Categoryitem
{
public int IdCategory { get; set; }
public int IdItem { get; set; }
public virtual Category IdCategoryNavigation { get; set; } = null!;
public virtual Item IdItemNavigation { get; set; } = null!;
}
[HttpPost]
public ActionResult<Item> PostItem(Item item)
{
_context.Item.Add(item);
_context.SaveChanges();
return Ok();
}
How do i pass the IdCategory into POST method ? Do I need a CategoryCollection in Item class and pass IdCategory through Item member ?
What about the relationship table ? How do i insert the two Ids ?
Thank you
you can create a viewmodel if you need to add several categories in the same time when you create an item, or if you only assign one category when you create an item you can just add CategoryId, but with attribute [NotMapped]
public partial class Item
{
public int Id { get; set; }
... another properties
[NotMapped]
public int? CategoryId{ get; set; }
}
or fluent api
modelBuilder.Entity<Item>().Ignore(c => c.CategoryId);
you will have to bind this CategoryId to dropdown list in the view
and action
[HttpPost]
public ActionResult<Item> PostItem(Item item)
{
var categoryitem = new Categoryitem
{
IdItemNavigation=item,
IdCategory = item.CategoryId
};
_context.Categoryitem.Add(categoryitem);
_context.SaveChanges();
return Ok(item);
}
I am working on an asp.net core MVC framework + entity framework. where i got those model classes:-
public partial class Submission
{
public Submission()
{
SubmissionQuestionSubmission = new HashSet<SubmissionQuestionSubmission>();
}
public long Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime? Created { get; set; }
public virtual ICollection<SubmissionQuestionSubmission> SubmissionQuestionSubmission { get; set; }
}
public partial class SubmissionQuestion
{
public SubmissionQuestion()
{
SubmissionQuestionSubmission = new HashSet<SubmissionQuestionSubmission>();
}
public int Id { get; set; }
public string Question { get; set; }
public virtual ICollection<SubmissionQuestionSubmission> SubmissionQuestionSubmission { get; set; }
}
public partial class SubmissionQuestionSubmission
{
public int SubmissionQuestionId { get; set; }
public long SubmissionId { get; set; }
public bool? Answer { get; set; }
public virtual Submission Submission { get; set; }
public virtual SubmissionQuestion SubmissionQuestion { get; set; }
}
public class SubmissionCreate
{
public Submission Submission {set; get;}
public IList<SubmissionQuestion> SubmissionQuestion { set; get; }
public IList<SubmissionQuestionSubmission> SubmissionQuestionSubmission { set; get; }
}
and i have the following create view:-
#for (var i = 0; i < Model.SubmissionQuestion.Count(); i++)
{
<div class="form-group">
<input asp-for="#Model.SubmissionQuestion[i].Question" hidden />
<input asp-for="#Model.SubmissionQuestionSubmission[i].SubmissionQuestionId" hidden />
<label class="control-label" style="font-weight:bold">#Model.SubmissionQuestion[i].Question</label><br />
<input type="radio" asp-for="#Model.SubmissionQuestionSubmission[i].Answer" value="true" /><span style="color: #4d9b84;font-size:14px;font-weight:bold"> Yes</span><br />
<input type="radio" asp-for="#Model.SubmissionQuestionSubmission[i].Answer" value="false" /><span style="color: #4d9b84;font-size:14px;font-weight:bold"> No</span>
</div>
}
and the following create post method:-
public async Task<IActionResult> Create([Bind("Submission,SubmissionQuestionSubmission")] SubmissionCreate sc )
{
if (ModelState.IsValid)
{
var newsubmission = _context.Submission.Add(sc.Submission);
sc.Submission.Created = DateTime.Now;
await _context.SaveChangesAsync();
foreach (var v in sc.SubmissionQuestionSubmission)
{
v.SubmissionId = sc.Submission.Id;
_context.SubmissionQuestionSubmission.Add(v);
}
await _context.SaveChangesAsync();
but inside my action method if i try the following sc.Submission.SubmissionQuestionSubmission.FirstOrDefault(a => a.SubmissionQuestion.Question.StartsWith("Are you")).Answer i will get null reference exception where the sc.Submission.SubmissionQuestionSubmission.SubmissionQuestion will be null, although the relation of these objects are defined inside the database.. any advice?
FirstOrDefault could be null in any case. It doesn't related to this particular case. So, before using any property, it should be checked whether it is null or not.
var object = list.FirstOrDefault(x=>x.p1='aa');
if(object != null)
{
//use object.Answer
}
I want to make a drop down list of "Trailers" and "Customers" available in my "Order" form. I am able to use the Html tag helper to pass Trailer data from database to the view in the "Order" form but i am not able to do the same for Customers using the razor select tag helper. Why isn't the razor select tag helper not passing values from the database to the view? Below are snippets of my code. I am confused as to why it's not working
Trailer Class
public class Trailer
{
public string SerialNumber { get; set; }
public string TrailerNumber { get; set; }
public string TrailerStatus { get; set; }
public int TrailerID { get; set; }
public virtual Order OrderforTrailer { get; set; }
public Trailer()
{
TrailerStatus = "Available";
}
}
Customer class
public class Customer
{
public string CustomerName { get; set; }
public string StreetNumber { get; set; }
public string StreetName { get; set; }
public string ZipCode { get; set; }
public string State { get; set; }
public int CustomerID { get; set; }
public IList<Order> CustomerOrders { get; set; }
}
Order Class
public class Order
{
public string OrderNumber { get; set; }
public string OrderStatus { get; set; }
public int OrderID { get; set; }
public int TrailerForLoadID { get; set; }
public virtual Trailer TrailerForLoad { get; set; }
public int CustomerOrdersID { get; set;}
public virtual Customer CustomerOrders { get; set; }
public Order()
{
OrderStatus = "Available";
}
}
AddOrderViewModel
public string OrderNumber { get; set; }
public int TrailerID { get; set; }
public List<SelectListItem> TrailersForLoad { get; set; }
public int CustomerID { get; set; }
public List<SelectListItem> CustomersOrder { get; set; }
public AddOrderViewModel()
{
}
public AddOrderViewModel(IEnumerable<Trailer> trailersForLoad, IEnumerable<Customer> customersOrder)
{
TrailersForLoad = new List<SelectListItem>();
foreach (var trailer in trailersForLoad)
{
TrailersForLoad.Add(new SelectListItem
{
Value = (trailer.TrailerID).ToString(),
Text = trailer.TrailerNumber
});
};
CustomersOrder = new List<SelectListItem>();
foreach (var customer in customersOrder)
{
CustomersOrder.Add(new SelectListItem
{
Value = (customer.CustomerID).ToString(),
Text = customer.CustomerName
});
};
}
}
Order controller
public IActionResult Add()
{
IList<Trailer> trailerForLoad = context.Trailers.Where
(c => c.TrailerStatus == "Available").ToList();
IList<Customer> customerOrder = context.Customers.ToList();
AddOrderViewModel addOrderViewModel =
new AddOrderViewModel(trailerForLoad, customerOrder);
return View(addOrderViewModel);
}
[HttpPost]
public IActionResult Add(AddOrderViewModel addOrderViewModel)
{
if (ModelState.IsValid)
{
Order newOrder = new Order()
{
OrderNumber = addOrderViewModel.OrderNumber,
TrailerForLoad = context.Trailers.
Where(x => x.TrailerID == addOrderViewModel
.TrailerID).Single(),
CustomerOrders = context.Customers
.Single(x => x.CustomerID==addOrderViewModel.CustomerID)
};
context.Orders.Add(newOrder);
trailerSelected = context.Trailers.Where(x =>
x.TrailerID == addOrderViewModel.TrailerID).Single();
trailerSelected.TrailerStatus = "Unavailable";
context.SaveChanges();
return Redirect("/Order");
}
return View(addOrderViewModel);
}
The form in the view should display a list of customers
<form asp-controller="Order" asp-action="Add" method="post">
<fieldset>
<div class="form-group">
<label asp-for="OrderNumber">Order number </label>
<input class="form-control" asp-for="OrderNumber" />
<span asp-validation-for="OrderNumber"></span>
</div>
<div class="form-group">
<label asp-for="TrailersForLoad">Trailer</label>
#Html.DropDownListFor(x => x.TrailerID, Model.TrailersForLoad)
<span asp-validation-for="TrailersForLoad"></span>
</div>
<div class="form-group">
<label asp-for="CustomerID">Customers Name</label>
<select asp-for="CustomerID"
asp-items="Model.CustomersOrder"></select>
<span asp-validation-for="CustomerID"></span>
</div>
<div>
<input type="submit" value="Submit" name="submitButton" />
</div>
</fieldset>
You are using the SELECT tag helper incorrectly. In your current code, you are using a self closing tag approach! Instead you should use an explicit </SELECT> closing tag
This should work
<select asp-for="CustomerID" asp-items="Model.CustomersOrder"></select>
I have a application where stores can complete a questionnaire. within this application i have two tables db.StoreAud(pk:AuditId) which contains all the stores information, and db.storequests(pk:ReviewId) which holds the all questions information.
AuditId is a foreign key in db.storequests table. Now here is the issue if a store complete the questionnaire the data saves perfectly in the database, however is the same store does the questionnaire again the db.storequests creates a new row in the database with a new primary key value instead of updating the previous row. Question is how can i update the previous row if the same store does the same questionnaire again. hope this made since.
db.StoreAUD
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
[Column(Order = 1)]
public int AuditId { get; set; }
public string Date { get; set; }
public int StoreNumber { get; set; }
public string StoreName { get; set; }
db.storequests
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public int ReviewId { get; set; }
public int AuditId { get; set; }
public int QuestionOne { get; set; }
public string QuestionTwo { get; set; }
public string QuestionThree { get; set; }
public string QuestionFour { get; set; }
controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(StoreQuestions storequestions)
{
if (ModelState.IsValid)
{
StoreAudit findingAudit = db.StoreAudit.Find(storequestions.AuditId); // grabbing the id from th store audit table
findingAudit.ReadOnlyTickBox = true;
db.StoreQuestions.Add(storequestions);
db.SaveChanges();
return RedirectToAction("Details", "Audit", new { id = storequestions.AuditId });
}
return View(storequestions);
}
I would seperate your update logic into a new Update action, following the Single Responsibility Principle:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Update(StoreQuestions storequestions)
{
if (ModelState.IsValid)
{
StoreAudit findingAudit = db.StoreAudit.Find(storequestions.AuditId);
findingAudit.ReadOnlyTickBox = true;
// update objects here
db.SaveChanges();
return RedirectToAction("Details", "Audit", new { id = storequestions.AuditId });
}
return View(storequestions);
}
}
I have taken primary key (Userid) as foreign key in 'Book' table.It is one to many relationship i.e a single user is able to upload multiple books. BookID is auto incremented.Whenever user clicks 'Upload Books' button, I need to store the name of the book and its path in database with userid as foreign key from User table and BookID to be auto increment.
I am having the following exception at db.SaveChanges():
An exception of type 'System.Data.Entity.Infrastructure.DbUpdateException' occurred in EntityFramework.dll but was not handled in user code Additional information: An error occurred while updating the entries. See the inner exception for details.
Inner exception is:
Cannot insert the value NULL into column 'Id', table 'BooksModule.dbo.Book'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated.
Below is my code:
Here is my model class: Book.cs
public partial class Book
{
public string Id { get; set; }
public int BookID { get; set; }
public string BookName { get; set; }
public string BookPath { get; set; }
public virtual User User { get; set; }
}
Here is my model class of Users: User.cs
public partial class User
{
public User()
{
this.Books = new HashSet<Book>();
}
public string Id { get; set; }
public string UserName { get; set; }
public virtual ICollection<Book> Books { get; set; }
}
here is a method:
[HttpGet]
public ActionResult FileUpload(string id)
{
return View();
}
[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase file,Book bk)
{
var filepath = "";
var fname = "";
if (ModelState.IsValid)
{
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/Uploads"), fileName);
filepath = path;
fname = fileName;
file.SaveAs(path);
}
bk.BookName = fname;
bk.BookPath = filepath;
db.Books.Add(bk);
db.SaveChanges();
return RedirectToAction("Index", "Home");
}
else
{
return View();
}
}
Here is a view:
<div class="sidebar">
#using (Html.BeginForm("FileUpload", "UploadBooks", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary();
<fieldset>
<legend>Upload a file</legend>
<div class="editor-field">
#Html.TextBox("file", "", new { type = "file" })
</div>
<input type="submit" id="btnSubmit" class="btn btn-default2" value="Upload" />
</fieldset>
}
</div>
Entity Framework will pick Id as the primary key, and as yours is a string you need to supply it yourself (which you are not doing.)
It's preferable to have an int as your primary key so EF can make it an identity column in the database.
A few other observations too:
The FileUpload post action is taking a Book object that isn't used other than as a variable in your action, instead just declare a new Book object inside the method.
The fileName and path variables are not needed.
Do you need both Id and BookId? I would remove BookId.
I would suggest your Book.cs looks like this:
public partial class Book
{
public int Id { get; set; }
public string BookName { get; set; }
public string BookPath { get; set; }
public virtual User User { get; set; }
}
And your post action:
[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
if (file.ContentLength > 0)
{
fname = Path.GetFileName(file.FileName);
filepath = Path.Combine(Server.MapPath("~/App_Data/Uploads"), fileName);
file.SaveAs(fname);
Book bk = new Book
{
BookName = fname,
BookPath = filepath
};
db.Books.Add(bk);
db.SaveChanges();
}
return RedirectToAction("Index", "Home");
}
else
{
return View();
}
}
Update
From the comments you made above, there is an additional change you need to make to the Book class. First you need to tell Entity Framework that your Id property if the key using the [Key] attribute. Secondly for the Id column you should do one of these:
Remove Id (as Entity Framework will create one for you)
Rename Id to UserId to allow Entity Framework to automatically link it to the User property.
Add an attribute to the User property to tell it the name of the column to use, for example [ForeignKey("Id")]
I would suggest either 1 or 2 so it is more obvious what the column is when looking at the database:
public partial class Book
{
[Key]
public int BookId { get; set; }
public string BookName { get; set; }
public string BookPath { get; set; }
public string UserId { get; set; }
public virtual User User { get; set; }
}