Non lazy loading - asp.net

i have a model looks like this.
public class TradeModel
{
public int id { get; set; }
public BaseProductModel baseProduct { get; set; }
public string productDescription { get; set; }
public List<byte[]> images { get; set; }
public int price { get; set; }
// Date infos
public DateTime estimatedShippingDate { get; set; }
}
What i want to do is. when i call post request i want to send an id of an existing baseProduct not the entire baseProductForm and that being created.
ive tried
[Required]
public int baseProductId { get; set; }
[ForeignKey("baseProductId")]
public virtual BaseProductModel baseProduct { get; set; }
something like this, but seems to be not working.
any possible solutions?

Your model:
public class TradeModel
{
public int id { get; set; }
public int baseProductId { get; set; }
public virtual BaseProductModel baseProduct { get; set; }
public string productDescription { get; set; }
public List<byte[]> images { get; set; }
public int price { get; set; }
// Date infos
public DateTime estimatedShippingDate { get; set; }
}
Your ViewModel:
public class TradeViewModel
{
public int id { get; set; }
public int baseProductId { get; set; }
public string productDescription { get; set; }
public List<byte[]> images { get; set; }
public int price { get; set; }
// Date infos
public DateTime estimatedShippingDate { get; set; }
}
Now you can pass only the baseProductId:
public IActionResult(TradeViewModel model)
{
// Your form will contain only the id anyway so the method below should work.
// Replace that with your actual context
//dbcontext.Trades.Add(new TradeModel { ... });
}

Related

Cannot deserialize a JSON string using .NET Core

I have recently switched to .NET Core and I am having trouble deserializing the following JSON string into this object. Usually works like a charm using Newtonsoft.
public class smDesktopSearchResultsVM
{
public smDesktopSearchResultsVM()
{
this.indexEventVMs = new List<indexEventVMLite>();
}
public int page { get; set; }
public int totalRecs { get; set; }
public int totalPages { get; set; }
public int? LinkGroupId { get; set; }
public List<indexEventVMLite> indexEventVMs { get; set; }
}
public class indexEventVMLite
{
public indexEventVMLite()
{
this.Event = new EventVMLite();
}
public EventVMLite Event { get; set; }
public int orderCount { get; set; }
public int sortOrder { get; set; }
public string pageImage { get; set; }
public string retinaPageImage { get; set; }
public int linkId { get; set; }
public int linkgroupId { get; set; }
public string pageURL { get; set; }
}
public class EventVMLite
{
public int WebsiteId { get; set; }
public int EventId { get; set; }
public string EventName { get; set; }
public string EventPassword { get; set; }
public DateTime EventDate { get; set; }
public DateTime? EventEndDate { get; set; }
public DateTime? EventExpires { get; set; }
public DateTime? DiscontinuedDate { get; set; }
public DateTime? forceDateDeleted { get; set; }
public bool EventReady { get; set; }
}
Here is the JSON sting:
{
"page": 1,
"totalRecs": 11,
"totalPages": 2,
"indexEventVMs": {
"Event": {
"WebsiteId": 5140,
"EventId": 14614,
"EventName": "Proofpix Elementary School",
"EventPassword": "proofpixelementarydemo",
"EventDate": "2021-08-30T16:00:00",
"EventEndDate": "2021-08-30T20:00:00",
"EventExpires": "2022-09-01T05:00:00",
"DiscontinuedDate": null,
"forceDateDeleted": null,
"EventReady": true
},
"orderCount": 5,
"sortOrder": 1,
"pageImage": "https://s3.us-east-1.wasabisys.com/usstandard.cdn.proofpix.com/websites/5140/PageMedia/266450/Descendants/1939278/680_9099_class-composite-7a.jpg",
"retinaPageImage": null,
"linkId": 354967,
"linkgroupId": 9527,
"pageURL": "https://jackblack.proofpix.com/proofpix-elementary-school/"
},
"LinkGroupId": 9527
}
Here is the error message:
The JSON value could not be converted to System.Collections.Generic.List`1[SortMagic_Desktop.indexEventVMLite]. Path: $.indexEventVMs | LineNumber: 0 | BytePositionInLine: 57.
What is funny is that Visual Studio has no problem parsing the JSON string to JSON when viewing the error data so it must be possible!
The problem can be in the List indexEventVMs a JSON list is [] but in the example it's a object {}.
So according to your JSON the classes would be something like this:
public class Object
{
public long Page { get; set; }
public long TotalRecs { get; set; }
public long TotalPages { get; set; }
public IndexEventVMs IndexEventVMs { get; set; }
public long LinkGroupId { get; set; }
}
public class IndexEventVMs
{
public Event Event { get; set; }
public long OrderCount { get; set; }
public long SortOrder { get; set; }
public Uri PageImage { get; set; }
public object RetinaPageImage { get; set; }
public long LinkId { get; set; }
public long LinkgroupId { get; set; }
public Uri PageUrl { get; set; }
}
public class Event
{
public long WebsiteId { get; set; }
public long EventId { get; set; }
public string EventName { get; set; }
public string EventPassword { get; set; }
public DateTimeOffset EventDate { get; set; }
public DateTimeOffset EventEndDate { get; set; }
public DateTimeOffset EventExpires { get; set; }
public object DiscontinuedDate { get; set; }
public object ForceDateDeleted { get; set; }
public bool EventReady { get; set; }
}
If you need that indexEventVMs receive a list you need to change from the json object {} to an array with object[{}].
You have to replace
public List<indexEventVMLite> indexEventVMs { get; set; }
with this
public indexEventVMLite indexEventVMs { get; set; }
but it is better to try this code
var json = ...your json
var result = JsonConvert.DeserializeObject<smDesktopSearchResultsVM>(json);
var resultSerialized =JsonConvert.SerializeObject(result);
result
{"page":1,"totalRecs":11,"totalPages":2,"indexEventVMs":{"Event":{"WebsiteId":5140,"EventId":14614,"EventName":"Proofpix Elementary School","EventPassword":"proofpixelementarydemo","EventDate":"2021-08-30T16:00:00-02:30","EventEndDate":"2021-08-30T20:00:00-02:30","EventExpires":"2022-09-01T05:00:00-02:30","DiscontinuedDate":null,"forceDateDeleted":null,"EventReady":true},"orderCount":5,"sortOrder":1,"pageImage":"https://s3.us-east-1.wasabisys.com/usstandard.cdn.proofpix.com/websites/5140/PageMedia/266450/Descendant/1939278/680_9099_class-composite-7a.jpg","retinaPageImage":null,"linkId":354967,"linkgroupId":9527,"pageURL":"https://jackblack.proofpix.com/proofpix-elementary-school"},"LinkGroupId":9527}
classes
public partial class smDesktopSearchResultsVM
{
[JsonProperty("page")]
public long Page { get; set; }
[JsonProperty("totalRecs")]
public long TotalRecs { get; set; }
[JsonProperty("totalPages")]
public long TotalPages { get; set; }
[JsonProperty("indexEventVMs")]
public IndexEventVMs IndexEventVMs { get; set; }
[JsonProperty("LinkGroupId")]
public long LinkGroupId { get; set; }
}
public partial class IndexEventVMs
{
[JsonProperty("Event")]
public Event Event { get; set; }
[JsonProperty("orderCount")]
public long OrderCount { get; set; }
[JsonProperty("sortOrder")]
public long SortOrder { get; set; }
[JsonProperty("pageImage")]
public Uri PageImage { get; set; }
[JsonProperty("retinaPageImage")]
public object RetinaPageImage { get; set; }
[JsonProperty("linkId")]
public long LinkId { get; set; }
[JsonProperty("linkgroupId")]
public long LinkgroupId { get; set; }
[JsonProperty("pageURL")]
public Uri PageUrl { get; set; }
}
public partial class Event
{
[JsonProperty("WebsiteId")]
public long WebsiteId { get; set; }
[JsonProperty("EventId")]
public long EventId { get; set; }
[JsonProperty("EventName")]
public string EventName { get; set; }
[JsonProperty("EventPassword")]
public string EventPassword { get; set; }
[JsonProperty("EventDate")]
public DateTimeOffset EventDate { get; set; }
[JsonProperty("EventEndDate")]
public DateTimeOffset EventEndDate { get; set; }
[JsonProperty("EventExpires")]
public DateTimeOffset EventExpires { get; set; }
[JsonProperty("DiscontinuedDate")]
public object DiscontinuedDate { get; set; }
[JsonProperty("forceDateDeleted")]
public object ForceDateDeleted { get; set; }
[JsonProperty("EventReady")]
public bool EventReady { get; set; }
}

Trying to recreate a solution given for a question, need a little assistance

Trying to recreate a solution given for ASP.NET MVC - Taking search criteria as input, and displaying the results, in the same View?, but not sure where to find the querymanager that derloopkat uses in his example.
[HttpPost]
public ActionResult Query(FormQueryModel model)
{
var queryManager = new QueryManager(model);
model.QueryResults = queryManager.GetResults();
return View(model);
}
My ViewModels
public class PartRequestInfoSearch
{
public int? Building { get; set; }
public int? PartType { get; set; }
public int? PartStatus { get; set; }
public Nullable<System.DateTime> tmpStartDate { get; set; }
public Nullable<System.DateTime> tmpEndDate { get; set; }
public int PageSize { get; set; }
public List<RequestedPartInfo> RequestedPartInfos { get; set; }
public PartRequestInfoSearch()
{
this.RequestedPartInfos = new List<RequestedPartInfo>();
}
}
}
public class RequestedPartInfo
{
public int idPartRequest { get; set; }
public string Building { get; set; }
public string RequestNumber { get; set; }
public string PartNumber { get; set; }
public string VendorPartNumber { get; set; }
public string PartDescription { get; set; }
public int StockQTY { get; set; }
public int RequestQTY { get; set; }
public int ShippedQTY { get; set; }
public string PartStatus { get; set; }
}

EF core and creating a many to many table. Creates extra field. Why ?

Why is there a UserProgramRefProgramCharacteristics.RefProgramCharacteristicsId field??? There should only be 2 fields not 3. Right? Below are the 3 classes and the OnModelCreating that is needed to create a many to many table
public class RefProgramCharacteristic
{
public int Id { get; set; }
public string ProgramCharacteristic { get; set; }
public List<UserProgramRefProgramCharacteristic> UserProgramRefProgramCharacteristics { get; set; }
// public ICollection<UserProgram> userPrograms { get; } = new List<UserProgram>();
// public virtual ICollection<UserProgram> UserPrograms { get; set; }
}
public class UserProgram
{
public int Id { get; set; }
//UserProgramSaved
public bool MyList { get; set; }
public float MyPriorityRating { get; set; }
public int Similarity { get; set; }
public bool Compare { get; set; }
//UserProgramSimilarity
public int OverallSimilarityScore { get; set; }
public int DeltaProfileElement1_WorkExp { get; set; }
public int DeltaProfileElement2_VolExp { get; set; }
public int DeltaProfileElement3_ResExp { get; set; }
public int DeltaProfileElement4_Pubs { get; set; }
public int DeltaProfileElement5_Step1 { get; set; }
public int DeltaProfileElement6_Step2ck { get; set; }
public int DeltaProfileElement7_Aoa { get; set; }
public int DeltaProfileElement8_Nspecialties { get; set; }
public int DeltaProfileElement9_PercentApps { get; set; }
//UserComparisonSaved
// public RefProgramCharacteristic RefProgramCharacteristic { get; set; }
public string RefProgramCharacteristicList { get; set; }
public string ApplicationUserId { get; set; }
public ApplicationUser ApplicationUser { get; set; }
public int MedicalProgramId { get; set; }
public RefProgramDetailData MedicalProgram { get; set; }
public List<UserProgramRefProgramCharacteristic> UserProgramRefProgramCharacteristics { get; set; }
// public ICollection<RefProgramCharacteristic> RefProgramCharacteristics { get; } = new List<RefProgramCharacteristic>();
// public virtual ICollection<RefProgramCharacteristic> RefProgramCharacteristics { get; set; }
}
public class UserProgramRefProgramCharacteristic
{
// public int Id { get; set; }
public int UserProgramId { get; set; }
public UserProgram UserProgram { get; set; }
public int RefProgramCharacteristicsId { get; set; }
public RefProgramCharacteristic RefProgramCharacteristic { get; set; }
}
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<UserProgramRefProgramCharacteristic>()
.HasKey(t => new { t.UserProgramId, t.RefProgramCharacteristicsId });
base.OnModelCreating(builder);
}
Why is there a UserProgramRefProgramCharacteristics.RefProgramCharacteristicsId field?
Because you are telling EF Core to create such field here:
public int RefProgramCharacteristicsId { get; set; }
// ^
While the navigation property is called RefProgramCharacteristic (no s). And by EF Core conventions:
If the dependent entity contains a property named <primary key property name>, <navigation property name><primary key property name>, or <principal entity name><primary key property name> then it will be configured as the foreign key.
RefProgramCharacteristicsId does not match any of these rules, so EF Core creates a shadow FK property with default name RefProgramCharacteristicId.
Either rename the property to RefProgramCharacteristicId (best), or map it explicitly using ForeignKey data annotation:
[ForeignKey(nameof(RefProgramCharacteristicsId))]
public RefProgramCharacteristic RefProgramCharacteristic { get; set; }
or
[ForeignKey(nameof(RefProgramCharacteristic))]
public int RefProgramCharacteristicsId { get; set; }
or using HasForeignKey fluent API:
builder.Entity<UserProgramRefProgramCharacteristic>()
.HasOne(e => e.RefProgramCharacteristic)
.WithMany(e => e.UserProgramRefProgramCharacteristics)
.HasForeignKey(e => e.RefProgramCharacteristicsId);

Entity Framework many to many relation error

I'm trying to create a many-to-many relationship between my two tables, but when I run Update-Database command I get this error:
Introducing FOREIGN KEY constraint 'FK_dbo.ExamQuestions_dbo.Questions_Question_Id' on table 'ExamQuestions' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint or index. See previous errors.
My first entity is :
public class Question
{
public Question()
{
this.Exams = new HashSet<Exam>();
}
[Key]
public int Id { get; set; }
[Required(ErrorMessage="Question is Required")]
[Display(Name="Question")]
[AllowHtml]
public string QuestionText { get; set; }
// public bool IsMultiSelect { get; set; }
public string Hint { get; set; }
public string HelpLink { get; set; }
public int Marks { get; set; }
public byte[] ImageData { get; set; }
[StringLength(50)]
public string MimeType { get; set; }
public byte[] Audio { get; set; }
public int QuestionTypeId { get; set; }
public int TopicId { get; set; }
public int DifficulityLevelId { get; set; }
public int SubjectId { get; set; }
public DifficultyLevel QuestionDifficulity { get; set; }
public Topic Topic { get; set; }
public virtual ICollection<Option> Options { get; set; }
public ICollection<Exam> Exams { get; set; }
}
And the second entity is:
public class Exam
{
public Exam()
{
this.Questions = new HashSet<Question>();
}
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int Duration { get; set; }
[Required]
public int TotalQuestion { get; set; }
[Required]
public int TotalMarks { get; set; }
public bool SectionWiseTime { get; set; }
public bool QuestionWiseTime { get; set; }
public bool AllQustionRequired { get; set; }
public bool AllowBackForward { get; set; }
public bool SuffleSubjectWise { get; set; }
public bool SuffleOptionWise { get; set; }
public bool GroupSubjectWise { get; set; }
[Required]
public int ExamTypeId { get; set; }
[Required]
public int ExamInstructionId { get; set; }
[Required]
public int DifficultyLevelId { get; set; }
public virtual ExamType ExamType { get; set; }
public virtual ExamInstruction ExamInstruction { get; set; }
public virtual DifficultyLevel DifficultyLevel { get; set; }
public virtual ICollection<Question> Questions { get; set; }
//public virtual ICollection<ExamSchedule> ExamSchedules { get; set; }
}
Can someone tell me where I'm going wrong?
By default, EF has cascading deletes set. This error is warning you that this can cause cascading deletes with many to many relationships. And is probably not what you intend to have happen on a delete/update.
You can remove the OneToManyCascadeDeleteConvention in the OnModelCreating method, or on the fluent mapping for each entity.
Details are provided in this SO Answer

Edit multiple related tables on ASP.net MVC w/Entity Framework 6

I'll open with the statement that I am very new to .net and MVC so please bear with me. I'm using Visual Studio 2013 and learning as I go.
Essentially - I have a .net MVC database-first project connected to a SQL db. I used scaffolding to create 4 models -
(Survey_Header_Response) - base survey information, identifies which survey a respondent gets
(Survey_Question) holds a unique list of the questions for all surveys and provides the actual question text,
(Survey_Response) lists of all the questions in the survey identified in (Survey_Response_Header) and will hold the value of each answer on post,
(Response_Values) - holds a list of possible responses for each of the different questions in each survey . Information on these is as follows:
Note - models are scaffolded, so even if I change them, they change back on db update.
Survey_Response_Header model:
public partial class Survey_Response
{
public Survey_Response()
{
this.Response_Values = new HashSet<Response_Values>();
}
public int Survey_Response_RecID { get; set; }
public int Survey_RecID { get; set; }
public int Survey_Question_RecID { get; set; }
public string Response { get; set; }
public Nullable<System.DateTime> Date_Responded { get; set; }
public int Contact_RecID { get; set; }
public int Company_RecID { get; set; }
public System.DateTime Date_Sent { get; set; }
public bool Responded { get; set; }
public string Survey_Qtr { get; set; }
public System.Guid Respondent_ID { get; set; }
public virtual Survey_Detail Survey_Detail { get; set; }
public virtual Survey_Question Survey_Question { get; set; }
public virtual ICollection<Response_Values> Response_Values { get; set; }
public virtual Survey_Response_Header Survey_Response_Header { get; set; }
}
Survey_Question:
public partial class Survey_Question
{
public Survey_Question()
{
this.Survey_Cat_SubCat = new HashSet<Survey_Cat_SubCat>();
this.Survey_Detail = new HashSet<Survey_Detail>();
this.Response_Values = new HashSet<Response_Values>();
this.Survey_Response = new HashSet<Survey_Response>();
}
public int Survey_Question_RecID { get; set; }
public string Question { get; set; }
public bool Inactive_Flag { get; set; }
public System.DateTime Date_Created { get; set; }
public string Created_By { get; set; }
public System.DateTime Date_Updated { get; set; }
public string Updated_By { get; set; }
public virtual ICollection<Survey_Cat_SubCat> Survey_Cat_SubCat { get; set; }
public virtual ICollection<Survey_Detail> Survey_Detail { get; set; }
public virtual ICollection<Response_Values> Response_Values { get; set; }
public virtual ICollection<Survey_Response> Survey_Response { get; set; }
}
Survey Response:
public Survey_Response()
{
this.Response_Values = new HashSet<Response_Values>();
}
public int Survey_Response_RecID { get; set; }
public int Survey_RecID { get; set; }
public int Survey_Question_RecID { get; set; }
public string Response { get; set; }
public Nullable<System.DateTime> Date_Responded { get; set; }
public int Contact_RecID { get; set; }
public int Company_RecID { get; set; }
public System.DateTime Date_Sent { get; set; }
public bool Responded { get; set; }
public string Survey_Qtr { get; set; }
public System.Guid Respondent_ID { get; set; }
public virtual Survey_Detail Survey_Detail { get; set; }
public virtual Survey_Question Survey_Question { get; set; }
public virtual ICollection<Response_Values> Response_Values { get; set; }
public virtual Survey_Response_Header Survey_Response_Header { get; set; }
}
Response_Values:
public partial class Response_Values
{
public Response_Values()
{
this.Survey_Response = new HashSet<Survey_Response>();
}
public int Survey_RecID { get; set; }
public int Survey_Question_RecID { get; set; }
public int Value { get; set; }
public int Question_Type_RecID { get; set; }
public string Value_Label { get; set; }
public Nullable<System.DateTime> Date_Created { get; set; }
public string Created_By { get; set; }
public Nullable<System.DateTime> Date_Updated { get; set; }
public string Updated_By { get; set; }
public int Response_Value_RecID { get; set; }
public virtual Question_Type Question_Type { get; set; }
public virtual Survey_Question Survey_Question { get; set; }
public virtual Survey Survey { get; set; }
public virtual Survey_Detail Survey_Detail { get; set; }
public virtual ICollection<Survey_Response> Survey_Response { get; set; }
}
}
There is a many-to-many relationship between the Response_Values & Survey_Response tables through the use of a pure-join table not shown here.
ViewModels: (See edit below)
ResponseData (intended to hold Survey_Response data and reference related tables)
I apologize for the length of this question - I'm new at this so my coding is probably messy and my explanation long. Any help provided is much appreciated and will help me learn!
Edit:
Thanks for your reply. I understand where you're coming from, and I've attempted to build the controller but when I try to populate the ResponseData viewModel that contains the ICollection Survey_Response with data, I get an error "Cannot implicitly convert type 'System.Collections.Generic.List CustomerExperienceSurveyWeb.Models.Survey_Response' to 'System.Collections.Generic.ICollection CustomerExperienceSurveyWeb.ViewModels.SurveyResponseVM'. An explicit conversion exists (are you missing a cast?)"
Here's the relevant part of my controller code:
public ActionResult Edit(Guid id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
//Survey_Response_Header survey = db.Survey_Response_Header.Find(id);
var survey = db.Survey_Response_Header
.Include(i => i.Survey_Response)
.Where(i => i.Responded_ID == id)
.Select(i => new
{
ViewModel = new ResponseData
{
Responded_ID = i.Responded_ID,
Company_RecID = i.Company_RecID,
Contact = i.Contact,
Contact_RecID = i.Contact_RecID,
Date_Responsed = i.Date_Responsed,
Date_Sent = i.Date_Sent,
Responded = i.Responded,
Survey_Qtr = i.Survey_Qtr,
Survey_RecID = i.Survey_RecID,
SurveyResponse = i.Survey_Response.ToList() <<--- This is where the error shows
}
})
.Single();
Updated ResponseData viewModel:
public partial class ResponseData
{
public ResponseData()
{
this.SurveyResponse = new List<SurveyResponseVM>();
}
public System.Guid Responded_ID { get; set; }
public int Survey_RecID { get; set; }
public System.DateTime Date_Sent { get; set; }
public Nullable<System.DateTime> Date_Responsed { get; set; }
public bool Responded { get; set; }
public int Contact_RecID { get; set; }
public int Company_RecID { get; set; }
public string Survey_Qtr { get; set; }
public virtual Contact Contact { get; set; }
public virtual ICollection<SurveyResponseVM> SurveyResponse { get; set; }
}
Referenced SurveyResponseVM viewModel which is throwing the error:
public partial class SurveyResponseVM
{
public SurveyResponseVM()
{
this.Response_Values = new List<ValueData>();
}
public int Survey_Response_RecID { get; set; }
public int Survey_RecID { get; set; }
public int Survey_Question_RecID { get; set; }
public string Response { get; set; }
public Nullable<System.DateTime> Date_Responded { get; set; }
public int Contact_RecID { get; set; }
public int Company_RecID { get; set; }
public System.DateTime Date_Sent { get; set; }
public bool Responded { get; set; }
public string Survey_Qtr { get; set; }
public System.Guid Respondent_ID { get; set; }
public virtual Survey_Detail Survey_Detail { get; set; }
public virtual Survey_Question Survey_Question { get; set; }
public virtual ICollection<ValueData> Response_Values { get; set; }
public virtual Survey_Response_Header Survey_Response_Header { get; set; }
}
I know this means I'm not populating the ICollection part of the viewmodel correctly but I can't seem to figure out how it's supposed to be done. I've done days of research on the internet and I either don't know the right question to ask or I'm completely missing it. Any help you can give me is VERY appreciated!
So the controller is essentially responsible for populating a model and pass this model to a view for rendering, there doesn't need to correspond to a database table.
The way I normally tackle this is to look at what the function is being performed, in this case survey and create a SurveyController. In here you will have a bunch of actions that correspond to views that are responsible for retrieving the correct data from the database, populating a model and then passing the model to the view for rendering.
So if you wanted to display a list of questions, you may do something like this (apologies if this contains errors, no VS atm):
public class SurveyController : Controller
{
public ActionResult Index()
{
var model = new SurveyModel(); // This would contain any properties, like questions and their valid responses
return View(model);
}
}
public class SurveyModel
{
public IList<SurveyQuestionModel> Questions { get; set; }
}

Resources