Updated 08/14/2012 12:05pm
I will try to explain my situation and hopefully someone can point me in the right direction.
I have a form in my project that will have several tables involved all of the tables are already set up with relationships. Here are the models that are related.
namespace QQAForm.Models
{
public class AuditSchedule
{
public virtual int AuditScheduleID { get; set; }
public virtual Nullable<DateTime> audit_completed_date { get; set; }
public virtual string gl_cmp_key { get; set; }
public virtual string audit_year { get; set; }
public virtual string ar_ship_key { get; set; }
public virtual string ar_ship_name { get; set; }
public virtual string im_adres_city { get; set; }
public virtual string im_adres_state { get; set; }
public virtual string audit_type { get; set; }
public virtual string audit_no { get; set; }
public virtual string audit_group { get; set; }
public virtual string Footage { get; set; }
public virtual string Rolling3MosFootage { get; set; }
public virtual string snp_SalesRep8 { get; set; }
public virtual string epg_sales_rep_accountable { get; set; }
public virtual string tech_service_rep { get; set; }
public virtual string audit_done_by { get; set; }
public virtual Nullable<DateTime> audit_recieved_date { get; set; }
public virtual string audit_notes { get; set; }
public virtual string audit_pdf { get; set; }
public virtual string updated { get; set; }
public virtual string hidden { get; set; }
public virtual string en_stats_key { get; set; }
public virtual string Control_ID { get; set; }
public virtual Nullable<DateTime> audit_date { get; set; }
public virtual string contacts_present { get; set; }
public virtual string audit_furnished_to { get; set; }
public virtual string spacer_type { get; set; }
}
}
MainQuestion:
namespace QQAForm.Models
{
public class MainQuestion
{
public virtual int MainQuestionID { get; set; }
public virtual int SubCategoryID { get; set; }
public virtual int ReferenceNo { get; set; }
public virtual int DisplayIndex { get; set; }
public virtual int SuggestionID { get; set; }
public virtual string Question { get; set; }
public virtual SubCategory SubCategory { get; set; }
public virtual ICollection<Suggestion> suggestions { get; set; }
public virtual ICollection<DocumentLink> documentLink { get; set; }
}
}
Child Questions:
namespace QQAForm.Models
{
public class ChildQuestion
{
public virtual int ChildQuestionID { get; set; }
public virtual int MainQuestionID { get; set; }
public virtual int ReferenceNo { get; set; }
public virtual int DisplayIndex { get; set; }
public virtual string QuestionText { get; set; }
public virtual string UserEntityType { get; set; }
public virtual string UserEntityTexts { get; set; }
public virtual MainQuestion MainQuestion { get; set; }
}
}
Suggestions:
namespace QQAForm.Models
{
public class Suggestion
{
public virtual int SuggestionID { get; set; }
public virtual int MainQuestionID { get; set; }
public virtual int DisplayIndex { get; set; }
public virtual string ReferenceNo { get; set; }
public virtual string Suggestions { get; set; }
public virtual MainQuestion MainQuestion { get; set; }
}
}
Main Answer:
namespace QQAForm.Models
{
public class MainAnswer
{
public virtual int MainAnswerID { get; set; }
public virtual int AuditScheduleID { get; set; }
public virtual int MainQuestionID { get; set; }
public virtual string Score { get; set; }
public virtual string AdditionalNotes { get; set; }
public virtual AuditSchedule AuditSchedule { get; set; }
public virtual MainQuestion MainQuestion { get; set; }
}
}
I am having a difficult time figuring out how to display a question from one table that has a relationship with another table with sub questions and check boxes for the answer. The answers are simple Yes, No, and N/A. They are also held in a different table. The reason i have all of this in data tables is they have to be editable or if i want to add to the areas.
This is what the page should look like. i have incerted text to give the look for the page.
Layout:
<html>
<head>
<title>#ViewBag.Title</title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"> </script>
</head>
<body>
<div id="head" class="container">
#Html.Partial("Header")
</div>
<div class="container">
<div id="main">
<ul id="breadcrumbs">
</ul>
<div id="formTopCol">
#RenderBody()
#*#Html.Partial("_Audit")*#
</div>
<div id="formBottomCol">
#Html.Action("_SubCategory")
<div id="formBottomRightCol">
#Html.Action("_Forms")
#*#RenderBody()*#
</div>
<div style="clear:left;"></div>
</div>
</div>
</div>
<div class="container">
#Html.Partial("Footer")
</div>
</body>
</html>
This is what it looks like:
I have set up in the global.asax a string to accept a audit record and then pull the main question. there is a side menu that will select the question area's. This is done in a view where the Audit schedule is the Body and the side menu and form question/answers are Html.Action() for partials.
Global Code:
routes.MapRoute(
"AuditSchedule", // Route name
"AuditSchedule/Audit/{id}/{section}", // URL with parameters
new { controller = "AuditSchedule", action = "Audit", id = UrlParameter.Optional, section = UrlParameter.Optional } // Parameter defaults
);
I have tried to play around with a view model for this but i cannot get this to work. When it comes to databases in C# coding i am really weak.
Here is the Model i am working on with the controller:
namespace QQAForm.ViewModels
{
public class AuditFormEdit
{
public Models.MainAnswer ScoreInstance { get; set; }
public List<ScoreCardCheckBoxHelper> ScoreCardCheckBoxHelperList { get; set; }
public void InitializeScoreCheckBoxHelperList(List<Models.Score> ScoreList)
{
if (this.ScoreCardCheckBoxHelperList == null)
this.ScoreCardCheckBoxHelperList = new List<ScoreCardCheckBoxHelper>();
if (ScoreList != null
&& this.ScoreInstance != null)
{
this.ScoreCardCheckBoxHelperList.Clear();
ScoreCardCheckBoxHelper scoreCardCheckBoxHelper;
string scoreTypes =
string.IsNullOrEmpty(this.ScoreInstance.Score) ?
string.Empty : this.ScoreInstance.Score;
foreach (Models.Score scoreType in ScoreList)
{
scoreCardCheckBoxHelper = new ScoreCardCheckBoxHelper(scoreType);
if (scoreTypes.Contains(scoreType.ScoreName))
scoreCardCheckBoxHelper.Checked = true;
this.ScoreCardCheckBoxHelperList.Add(scoreCardCheckBoxHelper);
}
}
}
public void PopulateCheckBoxsToScores()
{
this.ScoreInstance.Score = string.Empty;
var scoreType = this.ScoreCardCheckBoxHelperList.Where(x => x.Checked)
.Select<ScoreCardCheckBoxHelper, string>(x => x.ScoreName)
.AsEnumerable();
this.ScoreInstance.Score = string.Join(", ", scoreType);
}
public class ScoreCardCheckBoxHelper : Models.Score
{
public bool Checked { get; set; }
public ScoreCardCheckBoxHelper() : base() { }
public ScoreCardCheckBoxHelper(Models.Score scoreCard)
{
this.ScoreID = scoreCard.ScoreID;
this.ScoreName = scoreCard.ScoreName;
}
}
}
}
Controller section:
//get
public ActionResult _Forms(int id)
{
AuditFormEdit viewModel = new AuditFormEdit();
//viewModel.ScoreInstance = _db.MainAnswers.Single(r => r.AuditScheduleID == id);
viewModel.InitializeScoreCheckBoxHelperList(_db.Scores.ToList());
return View(viewModel);
}
//post
[HttpPost]
public ActionResult _Forms(int id, AuditFormEdit viewModel)
{
if (ModelState.IsValid)
{
viewModel.PopulateCheckBoxsToScores();
_db.Entry(viewModel.ScoreInstance).State = System.Data.EntityState.Modified;
_db.SaveChanges();
return RedirectToAction("/");
}
else
{
return View(viewModel);
}
}
As i stated before the ViewModel does not work because i am asking for an id that does not exist. Right now the view model only has code to populate check boxes for the answers.
Added view codes 08/14/2012 1:00pm
Form partial view mostly test but script that compliments the check box code
#{ Layout = null; }
#model QQAForm.ViewModels.AuditFormEdit
<table width="698" border="2" cellpadding="2">
<tr>
<td align="center"><b>Section</b><br />1.0</td>
<td><b>Glass edge damage noted. (shells, flakes, sharks teeth)</b>
<br /><br />
#Html.CheckBox("suggestion1")
It was noted that there was a significant amount of glass edge damage observed on the IG units being produced.
This glass edge damage may lead to a significantly high glass breakage rate in IG unit handling, in the glazing operation and in service.
[MAJOR CONCERN]
The cause of this glass edge damage should be determined and efforts made to eliminate the damage.
<br /><br />
#Html.CheckBox("suggestion2")
The glass edge should be smooth and free of chips, flakes, wings, or other damage. Damaged edges may result in stress cracks or premature IG unit failure.
[MAJOR CONCERN]
<br /><br />
<label>Additional Notes:</label><br />
#Html.TextArea("Additional Notes")
<br />
</td>
<td>
#for (int index = 0; index < Model.ScoreCardCheckBoxHelperList.Count; index++)
{
#Html.CheckBoxFor(m => m.ScoreCardCheckBoxHelperList[index].Checked)
#Html.LabelFor(m => m.ScoreCardCheckBoxHelperList[index], Model.ScoreCardCheckBoxHelperList[index].ScoreName)
#Html.HiddenFor(m => m.ScoreCardCheckBoxHelperList[index].ScoreID)
#Html.HiddenFor(m => m.ScoreCardCheckBoxHelperList[index].ScoreName)
}
</td>
</tr>
</table>
Here is the side menu partial:
#{ Layout = null; }
#model IEnumerable<QQAForm.Models.SubCategory>
<div id="menuCol">
<h3>Audit Sections</h3>
<ul>
<li>
#foreach (var item in Model)
{
<div class="sidemenu">
#Html.ActionLink(item.SubcategoryName, "Audit", new { section = item.SubCategoryID }, null)
</div>
}
</li>
</ul>
</div>
This is the Body:
#model QQAForm.Models.AuditSchedule
#{
ViewBag.Title = "Edit";
Layout = "~/Views/AuditSchedule/_FormLayout.cshtml";
}
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<table class="audit-display">
<tr>
<th>ID</th>
<th>Customer</th>
<th>City</th>
<th>State</th>
<th>EPG TSM Rep/NAM</th>
<th>EPG RSM (or NAM's VP)</th>
<th>Tech Rep</th>
<th>Audit Type</th>
</tr>
<tr>
<td>#Html.DisplayFor(m => m.AuditScheduleID)</td>
<td>#Html.DisplayFor(m => m.ar_ship_name)</td>
<td>#Html.DisplayFor(m => m.im_adres_city)</td>
<td>#Html.DisplayFor(m => m.im_adres_state)</td>
<td>#Html.DisplayFor(m => m.epg_sales_rep_accountable)</td>
<td>#Html.DisplayFor(m => m.snp_SalesRep8)</td>
<td>#Html.DisplayFor(m => m.tech_service_rep)</td>
<td>#Html.DisplayFor(m => m.audit_type)</td>
</tr>
</table>
<table class="audit-display">
<tr>
<th>Date</th>
<th>Contacts Present</th>
<th>Audit Furnished To</th>
<th>Audit Done By (If not sheduled)</th>
<th>Spacer's Used</th>
</tr>
<tr>
<td>#Html.DisplayFor(m => m.audit_date)</td>
<td>#Html.DisplayFor(m => m.contacts_present)</td>
<td>#Html.DisplayFor(m => m.audit_furnished_to)</td>
<td>#Html.DisplayFor(m => m.audit_done_by)</td>
<td>#Html.DisplayFor(m => m.spacer_type)</td>
</tr>
</table>
</fieldset>
<hr />
}
why are you adding an int id parameter to _Forms HttpPost action? You don't use it so you don't need it then, right? You also don't demonstrate your view code.
Related
I am making a system for the client, and he did not use fullcalendar, which would be practical. With that, I created in a table with the fields AgendaId (int), and DateAgendar (DateTime) years forward (some 20000 lines).
With that I set up the following ViewModel:
public class AgendaAgendamentoVM
{
public int Id { get; set; }
public int? AgendamentoId { get; set; }
public DateTime Date { get; set; }
public int? ClienteId { get; set; }
public string ClienteNome { get; set; }
}
And I have a second table called Reserva with the fields:
public class Reserva
{
public int ReservaId { get; set; }
public int AgendaId { get; set; }
[Required]
public int ClienteId { get; set; }
public string Servico { get; set; }
public virtual Cliente Cliente { get; set; }
}
and Clients:
public class Cliente
{
public int ClienteId { get; set; }
[Column(TypeName = "varchar(50)")]
public string Nome { get; set; }
[Column(TypeName = "varchar(50)")]
public string Telefone { get; set; }
[Column(TypeName = "varchar(50)")]
public string Endereco { get; set; }
[Column(TypeName = "varchar(50)")]
public string Email { get; set; }
public DateTime DataCadastro { get; set; }
}
The ViewModel code below returns every day from 6 am until 10 pm:
IList<AgendaAgendamentoVM> _listaAgendaVM = new List<AgendaAgendamentoVM>();
if (!String.IsNullOrEmpty(mes))
{
var data = DateTime.Parse(mes);
ViewBag.Data = data;
ViewBag.Ontem = data.AddDays(-1);
ViewBag.Amanha = data.AddDays(1);
var dias = await _context.Agenda
.Where(x => x.DataAgenda >= data.AddHours(6))
.Where(x => x.DataAgenda <= data.AddHours(22))
.ToListAsync();
foreach (var item in dias)
{
AgendaAgendamentoVM li = new AgendaAgendamentoVM();
li.Id = item.AgendaId;
li.Date = DateTime.Parse(item.DataAgenda.ToString());
_listaAgendaVM.Add(li);
}
ViewData["ListaAgenda"] = _listaAgendaVM;
return View();
The View:
#{
ViewBag.Title = "Agenda";
}
<form>
<input type="date" name="mes" required /> <input type="submit" value="Enviar" />
</form>
<div class="row m-1 p-2 bg-success rounded">
<div class="col-4">
<a class="text-white" href="/Agenda/Index?mes=#String.Format("{0:d}", ViewBag.Ontem)"><</a>
</div>
<div class="col-4 text-center text-white font-weight-bolder">
#String.Format("{0:d}", ViewBag.Data)
</div>
<div class="col-4 text-right">
<a class="text-white" href="/Agenda/Index?mes=#String.Format("{0:d}", ViewBag.Amanha)">></a>
</div></div>
<ul class="list-group m-1">
#foreach (var item in ViewData["ListaAgenda"] as
List<Camarim.Core.ViewModels.AgendaAgendamentoVM>)
{
<li class="list-group-item"><a href="#?agendaid=#item.Id">#String.Format("{0:HH:mm}",
item.Date) - #item.ClienteNome</a></li>
}
Only with the Agenda table, I can display in a view a "navigable" calendar as shown in the image:
Still in the Reservation table, I have a ClienteId field, where I return a specific customer. In the List I make of the ViewModel, I use a foreach calling the Reservation and Customers table, as shown in the photo:
The problem with this is, when doing this, the view stops showing the entire list from 6 am to 10 pm, it only shows the fields where clients are scheduled. My goal was to leave it at least this way:
How can I do to achieve this goal: and / OR another: Is there any other way to do this without using the database for popular dates?
It seems that you want to display the ClientNome.
Firstly,from your expected result image,it should be one-to-many relationship between Agenda and Reserva.Then you could get the multiple ClientNome to display it in your razor view.Change your model like below:
public class Agenda
{
public int AgendaId { get; set; }
public DateTime DataAgenda { get; set; }
public List<Reserva> Reserva { get; set; }
}
public class Reserva
{
public int ReservaId { get; set; }
public int AgendaId { get; set; }
[Required]
public int ClienteId { get; set; }
public string Servico { get; set; }
public virtual Cliente Cliente { get; set; }
}
public class Cliente
{
public int ClienteId { get; set; }
[Column(TypeName = "varchar(50)")]
public string Nome { get; set; }
[Column(TypeName = "varchar(50)")]
public string Telefone { get; set; }
[Column(TypeName = "varchar(50)")]
public string Endereco { get; set; }
[Column(TypeName = "varchar(50)")]
public string Email { get; set; }
public DateTime DataCadastro { get; set; }
}
public class AgendaAgendamentoVM
{
public int Id { get; set; }
public int? AgendamentoId { get; set; }
public DateTime Date { get; set; }
public int? ClienteId { get; set; }
public List<string> ClienteNome { get; set; }
}
View:
<form>
<input type="date" name="mes" required /> <input type="submit" value="Enviar" />
</form>
<div class="row m-1 p-2 bg-success rounded">
<div class="col-4">
<a class="text-white" href="/Agenda/Index?mes=#String.Format("{0:d}", ViewBag.Ontem)"><</a>
</div>
<div class="col-4 text-center text-white font-weight-bolder">
#String.Format("{0:d}", ViewBag.Data)
</div>
<div class="col-4 text-right">
<a class="text-white" href="/Agenda/Index?mes=#String.Format("{0:d}", ViewBag.Amanha)">></a>
</div>
</div>
<ul class="list-group m-1">
#foreach (var item in ViewData["ListaAgenda"] as List<AgendaAgendamentoVM>)
{
<li class="list-group-item">
<a href="#?agendaid=#item.Id">
#String.Format("{0:HH:mm}",
item.Date) - #foreach (var i in item.ClienteNome)
{
#i #string.Format(" ") #*change this*#
}
</a>
</li>
}
</ul>
Controller:
public async Task<IActionResult> Index(string mes)
{
IList<AgendaAgendamentoVM> _listaAgendaVM = new List<AgendaAgendamentoVM>();
if (!String.IsNullOrEmpty(mes))
{
var data = DateTime.Parse(mes);
ViewBag.Data = data;
ViewBag.Ontem = data.AddDays(-1);
ViewBag.Amanha = data.AddDays(1);
var dias = await _context.Agenda
.Where(x => x.DataAgenda >= data.AddHours(6))
.Where(x => x.DataAgenda <= data.AddHours(22))
.ToListAsync();
foreach (var item in dias)
{
var reservas = (from p in _context.Reservas
join c in _context.Clientes on p.ClienteId equals c.ClienteId
where p.AgendaId == item.AgendaId
select c).ToList();
AgendaAgendamentoVM li = new AgendaAgendamentoVM();
li.Id = item.AgendaId;
li.Date = DateTime.Parse(item.DataAgenda.ToString());
li.ClienteNome = reservas.Select(a => a.Nome).ToList();
_listaAgendaVM.Add(li);
}
ViewData["ListaAgenda"] = _listaAgendaVM;
return View();
}
return View();
}
Result:
So I want to get the titlefor that image in the database. How do I do it? It's showing Describe your post... for all images instead of the actual title of the image in the database
https://i.gyazo.com/17828889116a77983f70fd8c8a4c2ebf.png
View:
#foreach (var image in Model.Images)
{
<h2>#Html.LabelFor(m => m.title)</h2>
<div class="row">
<div class="col-md-8 portfolio-item">
<img class="portrait" src="#Url.Content(image)" alt="Hejsan" />
</div>
</div>
}
Model
[Table("MemeImages")]
public class UploadFileModel
{
[Key]
[DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
public int id { get; set; }
public string location { get; set; }
public IEnumerable<string> Images { get; set; }
public int contentLength { get; set; }
public string contentType { get; set; }
public string userID { get; set; }
[Required]
[Display(Name = "Describe your post...")]
public string title { get; set; }
public void SavetoDatabase(UploadFileModel file)
{
ApplicationDbContext db = new ApplicationDbContext();
db.uploadedFiles.Add(file);
db.SaveChanges();
}
}
Instead of label use directly <h2>m => m.title</h2>
Remove the display attribute.
[Required]
public string title { get; set; }
Also, LabelFor() is not the right thing. You may want to use Display/DisplayFor() to render the value.
HTML.BeginCollectionItem does not return values to the controller. It always return NULL in the controller. I am not sure if has got anything to do if there is a partial view within another partial view. Below is the snippet of the code/view.
ProductEditModel
public class ProductEditModel
{
// Product details displayed on edit form
public Product ProductModel { get; set; }
public IList<ProductAssetAudioEditModel> ProductAssetAudios { get; set;}
}
ProductAssetAudioEditModel
public class ProductAssetAudioEditModel
{
public int ProductId { get; set; }
public int? ProductAssetId { get; set; }
public virtual IList<ProductAssetResourceEditModel> ProductAssetResources { get; set; }
}
ProductAssetResourceEditModel
public class ProductAssetResourceEditModel
{
public int? ProductAssetResourceId { get; set; }
public int ProductAssetId { get; set; }
public int ResourceNumber { get; set; }
public int? ElectronicFileId { get; set; }
public ElectronicFile ElectronicFile { get; set; }
}
ProductEditView.cshtml
<div id="audio">
#foreach (ProductAssetAudioEditModel audio in Model.ProductAssetAudios)
{
Html.RenderPartial("_ProductAssetAudioRow", audio);
}
</div>
_ProductAssetAudioRow.cshtml
#using (Html.BeginCollectionItem("ProductAssetAudios"))
{
....
<tbody>
#foreach (var resource in Model.ProductAssetResources)
{
Html.RenderPartial("_ProductAssetAudioResource", resource);
}
</tbody>
.....
}
_ProductAssetAudioResource
#using (Html.BeginCollectionItem("ProductAssetResources"))
{
#Html.HiddenFor(m => Model.ProductAssetResourceId)
#Html.HiddenFor(m => Model.ProductAssetId)
<td>
#if (Model.ElectronicFileId.HasValue)
{
#Html.HiddenFor(model => model.ElectronicFileId)
#Html.ActionLink(Model.ElectronicFile.FileName, "Details", "File", new { id = Model.ElectronicFileId, area = "Edi" }, null);
}
</td>
<td>
#Html.EditorFor(c => Model.TrackTitle)
</td>
}
In the controller , ProductAssetResources is NULL even though edit page binds the properties correctly for editing.
I am not sure what I am missing here.
-Alan-
Testing a Website. While logged in as an admin, the user should be able to delete a Service. A Service could have sub categories known as "Service Options" and below that "Service Option Items". When an admin tries to permanently delete a service he/she receives the following server error.
Server Error
I have done some research and found out that the sub categories may need to be deleted first, and I believe the code reflects that.
Controller
//
// GET: /Service/Delete
[Authorize(Roles = "admin")]
public ActionResult Delete(int id)
{
Service serviceToDelete = db.Services.Where(s => s.ServiceId == id).Single();
return View(serviceToDelete);
}
//
// POST: /Service/Delete
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirm(int id)
{
var serviceToDelete = db.Services.Where(s => s.ServiceId == id).Single();
// remove the service option items
var serviceOptionItems = db.ServiceOptionItems.Where(soi => soi.ServiceOption.ServiceId == serviceToDelete.ServiceId);
foreach (var serviceOptionItem in serviceOptionItems)
{
db.ServiceOptionItems.Remove(serviceOptionItem);
}
// remove the service options
var serviceOptions = db.ServiceOptions.Where(so => so.ServiceId == serviceToDelete.ServiceId);
foreach (var serviceOption in serviceOptions)
{
db.ServiceOptions.Remove(serviceOption);
}
// remove the service
db.Services.Remove(serviceToDelete);
// save all changes
db.SaveChanges();
return RedirectToAction("Index", new { manage = "yes", mode = "all" });
}
View
#model YardLad.Models.Domain.Service
#{
ViewBag.Title = "Delete Service";
}
<script>
$(document).ready(function () {
var isConfirmed = false;
$("form").submit(function (e) {
if (!isConfirmed)
{
$("#dialog-confirm").dialog({
resizable: false,
height: 140,
modal: true,
buttons: {
"Yes": function () {
$(this).dialog("close");
isConfirmed = true;
$("#deleteService").submit();
},
Cancel: function () {
$(this).dialog("close");
}
}
});
e.preventDefault();
return false;
}
else
{
return true;
}
});
});
</script>
<h2>Delete</h2>
<h3>Are you sure you want to delete this service?</h3>
<div class="display-label">Service Category</div>
<div class="display-field">
#Html.DisplayFor(m => m.ServiceCategory.Name)
</div>
<div class="display-label">Name</div>
<div class="display-field">
#Html.DisplayFor(m => m.Name)
</div>
<div class="display-label">Description</div>
<div class="display-field">
#if (Model.Description == null)
{
#:No Description
}
else
{
#Html.DisplayFor(m => m.Description)
}
</div>
<div class="display-label">Base Price</div>
<div class="display-field">
#Html.DisplayFor(m => m.BasePrice)
</div>
<div class="display-label">Is Active</div>
<div class="display-field">
#Html.DisplayFor(m => m.IsActive)
</div>
#using (Html.BeginForm("Delete", "Service", null, FormMethod.Post, new { id = "deleteService" }))
{
<p>
<input type="submit" id="btnSubmit" value="Delete" />
</p>
}
<div>
#Html.ActionLink("Back", "Index", new { manage = "yes" })
</div>
<div id="dialog-confirm" title="Delete this service?" class="hidden">
<p>This service will be permanently deleted and cannot be recovered. Are you sure?</p>
</div>
Model
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using YardLad.Models.Domain;
namespace YardLad.Models.View
{
public class ServiceViewModel
{
[Display(Name = "Service Id")]
public int ServiceId { get; set; }
[Required(ErrorMessage = "please enter a name")]
public string Name { get; set; }
[UIHint("multilinetext")]
public string Description { get; set; }
[Display(Name = "Base Price")]
public decimal BasePrice { get; set; }
[Display(Name = "Service Category")]
[Required(ErrorMessage = "please select a category")]
public int ServiceCategoryId { get; set; }
[Display(Name = "Is Active?")]
public bool IsActive { get; set; }
[Display(Name = "Service options")]
public List<ServiceOption> ServiceOptions { get; set; }
}
public class RequestServiceViewModel
{
[Required(ErrorMessage = "please select a state")]
public int StateId { get; set; }
[Required(ErrorMessage = "please select a service area")]
public int ServiceAreaId { get; set; }
[Required(ErrorMessage = "please select a service")]
public int ServiceId { get; set; }
[Required(ErrorMessage = "please indicate the items selected")]
public string[] SelectedServiceOptionItemIds { get; set; }
[Required(ErrorMessage = "please indicate the contractors available for the request")]
public string[] AvailableContractorIds { get; set; }
public State SelectedState { get; set; }
public ServiceArea SelectedServiceArea { get; set; }
public Service SelectedService { get; set; }
public List<ServiceOption> SelectedServiceOptions { get; set; }
public List<ServiceOptionItem> SelectedServiceOptionItems { get; set; }
public List<Contractor> AvailableContractors { get; set; }
public int SelectedContractorId { get; set; }
public Contractor SelectedContractor { get; set; }
public int SelectedContractorServiceId { get; set; }
public ContractorService SelectedContractorService { get; set; }
public decimal SubTotal { get; set; }
public decimal Tax { get; set; }
public decimal SelectedContractorTaxRate { get; set; }
public decimal Total { get; set; }
public bool UserIsLoggedIn { get; set; }
public int UserAddressId { get; set; }
public Address UserAddress { get; set; }
public bool CreateCustomAddress { get; set; }
public Address CustomAddress { get; set; }
}
public class SelectContractorViewModel
{
public int ServiceAreaId { get; set; }
public ServiceArea SelectedServiceArea { get; set; }
public int ServiceId { get; set; }
public Service SelectedService { get; set; }
public List<ServiceOption> ServiceOptions { get; set; }
public List<ServiceOptionItem> ServiceOptionItems { get; set; }
public List<Contractor> AvailableContractors { get; set; }
public Contractor SelectedContractor { get; set; }
public int ContractorTypeId { get; set; }
public int ContractorServiceId { get; set; }
public ContractorService SelectedContractorService { get; set; }
public List<ContractorServiceOption> ContractorServiceOptions { get; set; }
public List<ContractorServiceOptionItem> ContractorServiceOptionItems { get; set; }
public decimal SubTotal { get; set; }
public decimal Tax { get; set; }
public decimal SelectedContractorTaxRate { get; set; }
public decimal Total { get; set; }
}
}
Image of DB relations:
edmx
Thank You for Reading
Your Service is related to ContractorService as well and there must be some child records in there to cause the error you posted. You'll need to remove all of those children like you did the other tables, but you also need to set the child entity to Deleted:
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirm(int id)
{
var serviceToDelete = db.Services.Where(s => s.ServiceId == id).Single();
// remove the service option items
var serviceOptionItems = db.ServiceOptionItems.Where(soi => soi.ServiceOption.ServiceId == serviceToDelete.ServiceId);
foreach (var serviceOptionItem in serviceOptionItems)
{
db.ServiceOptionItems.Remove(serviceOptionItem);
db.Entry(serviceOptionItem).State = EntityState.Deleted;
}
// remove the service options
var serviceOptions = db.ServiceOptions.Where(so => so.ServiceId == serviceToDelete.ServiceId);
foreach (var serviceOption in serviceOptions)
{
db.ServiceOptions.Remove(serviceOption);
db.Entry(serviceOption).State = EntityState.Deleted;
}
// remove the contractor services
var contractorServices = db.ContractorServices.Where(so => so.ServiceId == serviceToDelete.ServiceId);
foreach (var contractorService in contractorServices)
{
db.ContractorServices.Remove(contractorService);
db.Entry(contractorService).State = EntityState.Deleted;
}
// remove the service
db.Services.Remove(serviceToDelete);
// save all changes
db.SaveChanges();
return RedirectToAction("Index", new { manage = "yes", mode = "all" });
}
You have a foreign key constraint on the tables Service, ServiceOptions and ServiceOptions. Thus you will have to delete all the ServiceOptionsItems and ServiceOptions of that service before you can delete the service.
But if you have such requirement, I suggest you use ON DELETE CASCADE while adding the constraint. So that it will allow you to directly delete the service and will delete all the child ServiceOptions and ServiceOptionsItems automatically.
More Info: http://www.mysqltutorial.org/mysql-on-delete-cascade/
From the error message, it looks like you have the association between Service and something called ContractorService. Delete the related ContactorService entities first or remove or change its ServiceId value.
I have view to display Restaurant. In this view at the bottom of the page, I want to display Comments form to add comments about that Restaurant.
Can someone please help me to do this using MVC 4 & C#.
My Models has the followign two tables:
/Classifieds TABLE
public class Classifieds
{
[Key]
public string C_Unique_Id { get; set; }
public string AdType { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
//ClassifiedsComments TABLE
public class ClassifiedsComments
{
[Key]
public string CCommentsUniqueId { get; set; }
public string CommentAuthor { get; set; }
public string Comment { get; set; }
[ForeignKey("Classifieds")]
public string C_Unique_Id { get; set; } //this is the foreign key of Classified record
public virtual Classifieds Classifieds { get; set; }
}
Classifieds Details view:
#model SomeIndianShit.Models.Classifieds
#{
ViewBag.Title = "Details";
}
<table class="recordDetailsDisplayTableStype">
<tr>
<td colspan="2" align="left">
#Html.DisplayFor(model => model.Description)
<br /><br />
</td>
</tr>
<tr>
<td>
Ad Type
</td>
<td align="left"> :
#Html.DisplayFor(model => model.AdType)
</td>
</tr>
SOME OTHER FIELDS DISPLAY HERE
</table>
//Here I want to display "ClassifiedsComments" form to add comments to above Classified.
//HOW can I display the ClassifiedsComments create.cshtml code here??
Try this:
With View:
#using (Html.BeginForm("Classifieds", "ClassifiedsDetails", FormMethod.Post))
and
#using (Html.BeginForm("ClassifiedsComments", "ClassifiedsDetails", FormMethod.Post))
And use 1 Model for this:
public class ClassifiedsDetails
{
public Classifieds Model1{ get; set; }
public ClassifiedsComments Model2{ get; set; }
}
Update:
public class ClassifiedsDetails
{
public ClassifiedsDetails()
{
Model1 = new Classifieds();
Model2 = new ClassifiedsComments();
}
public Classifieds Model1{ get; set; }
public ClassifiedsComments Model2{ get; set; }
}
public class Classifieds
{
public Classifieds()
{
C_Unique_Id = String.Emty;
AdType = String.Emty;
//---- Add default setting here------
}
[Key]
public string C_Unique_Id { get; set; }
public string AdType { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
Or display list of comments in View with Model:
public class ClassifiedsDetails
{
public ClassifiedsDetails()
{
Model1 = new Classifieds();
Model2 = new List<ClassifiedsComments>();
}
public Classifieds Model1{ get; set; }
public List<ClassifiedsComments> Model2{ get; set; }
}
View:
#model ClassifiedsDetails
#Html.LabelFor(model => model.Model1.Title)
#foreach (var items in Model.Model2)
{
#item. //fields
}
To display data in view create view model, but to post comment, dont use model:
public class ClassifiedsViewModel
{
public ClassifiedsViewModel()
{
Comments = new List<ClassifiedsComments>();
}
public Classifieds Classifieds { get; set; }
public List<ClassifiedsComments> Comments { get; set; }
}
Fill this view model, use in view to display details and comments like above you write.
if(Model != null && Model.Classifieds != null)
{
<table> ...display details.. </table>
}
if(Model != null && Model.Comments != null)
{
<table> ...display comments with foreach loop.. </table>
}
And at bottom, create comment post form
#using (Html.BeginForm("SaveComment", "Controller", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
//set to which Classifieds will this comment posted
#Html.Hidden("C_Unique_Id", Model.Classifieds.C_Unique_Id)
<fieldset>
#Html.TextBox("Comment")
//other fields ....
<input type="submit" value="Save" />
</fieldset>
}
Edit2: View model creating:
public ActionResult Details(int id)
{
//add breakpoint here and follow any step.
ClassifiedsViewModel viewModel = new ClassifiedsViewModel();
viewModel.Classifieds = db.Classifieds.Find(id);
viewModel.Comments = db.LoadCommentsByClassifiedsId(id); //create db method
// or instead of this line use:
viewModel.Comments = db.ClassifiedsComments.Where(e => e.C_Unique_Id == id).ToList();
return(viewModel);
}
You can then add a ViewModel like this
public class ClassifiedsDetailViewModel
{
public ClassifiedsDetailViewModel()
{
ClassifiedsComments = new ClassifiedsComments();
}
public Classifieds Classifieds { get; set; }
public ClassifiedsComments ClassifiedsComments { get; set; }
}
Pass this view model to your view and then add #Html.Partial("_CreateClassifiedsCommentsFormPartial", Model.ClassifiedComments) below the table. And in your partial view, you can use Html.BeginForm or the Ajax.BeginForm.
See sample here