Trying to update table in asp.net - mysql

Saving the change to a temp variable is successful as when debugging I can see the values changing, however when I actually try to save the changes to the database, the required field is not being changed.
I am trying to change the value of the field from 'Being Investigated' to 'Closed'
nemesysEntities db2 = new nemesysEntities();
report report = db2.reports.Find(investigation.report_id);
report_status rep = db2.report_status.Find(3);
report.report_status = rep;
report.report_status.description = "Closed";
report.report_status.id = 3;
db2.Entry(report).State= EntityState.Modified;
db2.SaveChanges();
The table that stores the reports is called reports, and investigation.report_id represents the id of the report being investigated. Hence by passing the report id as a value, the table should find the report in the reports table and change the value of the action status to Closed, by the below line of code, (the id of the action "closed" in the database is 3)
report_status rep = db2.report_status.Find(3);
However the required changes in the database are not being stored.
Any ideas??
This is the model of the report
namespace WebApplication2.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Diagnostics;
using System.Web;
public partial class report
{
public report()
{
this.investigations = new HashSet<investigation>();
HttpCookie _userId = System.Web.HttpContext.Current.Request.Cookies["User"];
string userId="";
nemesysEntities db = new nemesysEntities();
if(_userId!=null)
{
this.user_id = Convert.ToInt32(_userId["Id"]);
user temp=db.users.Find(user_id);
this.email = temp.email;
this.phone = temp.phone;
temp.ConfirmPassword = temp.password;
int i = temp.points;
i++;
temp.points = i;
db.Entry(temp).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbEntityValidationException dbEx)
{
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
}
}
}
}
else
{
this.user_id = 13;
}
this.status_id = 1;
}
public int id { get; set; }
[Display(Name = "Date of near miss")]
public System.DateTime date { get; set; }
[Display(Name = "Location")]
public string location { get; set; }
[DisplayName("Type")]
public int type_id { get; set; }
[Display(Name = "Description")]
public string description { get; set; }
public int status_id { get; set; }
public int user_id { get; set; }
[Display(Name = "Email Address")]
public string email { get; set; }
[Display(Name = "Phone Number")]
public string phone { get; set; }
public int votes { get; set; }
public virtual ICollection<investigation> investigations { get; set; }
public virtual report_status report_status { get; set; }
public virtual report_type report_type { get; set; }
public virtual user user { get; set; }
}
}
This is the model of the investigator. You can see that in one of the setters I am using the same method I am attempting to use to change the status of the report.
namespace WebApplication2.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Diagnostics;
using System.Web;
public partial class investigation
{
public investigation()
{
HttpCookie _userId = System.Web.HttpContext.Current.Request.Cookies["User"];
if (_userId != null)
{
this.investigator_id = Convert.ToInt32(_userId["Id"]);
//5 is the primary key of "Being investigated" in type of action
this.action_id = 5;
this.cause = "";
this.date_of_action = new DateTime(2012, 1, 3);
}
}
public int id { get; set; }
[Display (Name="Formal Description")]
public string formal_description { get; set; }
[Display(Name = "Cause of Hazard")]
public string cause { get; set; }
[Display(Name = "Action Take")]
public int action_id { get; set; }
[Display(Name = "Date of Action")]
public System.DateTime date_of_action { get; set; }
public int investigator_id { get; set; }
int _report_id;
[Display(Name = "Report Id:")]
public int report_id
{
get
{
return _report_id;
}
set
{
_report_id = value;
nemesysEntities db = new nemesysEntities();
report report = db.reports.Find(this.report_id);
//2 is the primary key of "Being investigated" in report status
report_status rep = db.report_status.Find(2);
report.report_status = rep;
db.Entry(report).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbEntityValidationException dbEx)
{
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
}
}
}
}
}
public virtual investigation_action investigation_action { get; set; }
public virtual report report { get; set; }
public virtual user user { get; set; }
}
}

Related

How make dropdownlist to access data on your SelectItemList using asp.net mvc?

I am using DropDownlist in order to get country of all the world. I have attached the file(country_list.txt) using srcFilePath. The error i am getting is "There is no ViewData item of type 'IEnumerable' that has the key 'SelectedCountryId'.What could be an issue, because my EditFormTrainingRegViewModel does have this field SelectedCountry as a primary key. Its been declared as public int? SelectedCountryId {get;set;}
// List for countries.
private IEnumerable<SelectListItem> GetCountryList()
{
SelectList listcn = null;
try
{
var list = this.LoadData().Select(p => new SelectListItem
{
Value = p.Country_Id.ToString(),
Text = p.Country_Name
});
listcn = new SelectList(list, "Value", "Text");
}catch(Exception ex)
{
throw ex;
}
return listcn;
}
public ActionResult DropDownSelect()
{
EditTrainingRegFormViewModel model = new EditTrainingRegFormViewModel();
model.SelectedCountryId = 0;
this.ViewBag.CountryList = this.GetCountryList();
return this. View(model);
}
// Loading data for country list.
private List<EditTrainingRegFormViewModel> LoadData()
{
List<EditTrainingRegFormViewModel> lst = new List<EditTrainingRegFormViewModel>();
try
{
string line = string.Empty;
string srcFilePath = "Content/files/country_list.txt";
var rootPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
var fullPath = Path.Combine(rootPath, srcFilePath);
string filePath = new Uri(fullPath).LocalPath;
StreamReader src = new StreamReader(new FileStream(filePath, FileMode.Open, FileAccess.Read));
// while to read the file
while((line = src.ReadLine()) !=null) {
EditTrainingRegFormViewModel infoLst = new EditTrainingRegFormViewModel();
string[] info = line.Split(',');
//Setting
infoLst.Country_Id = Convert.ToInt32(info[0].ToString());
infoLst.Country_Name = info[1].ToString();
lst.Add(infoLst);
}
src.Dispose();
src.Close();
}catch(Exception ex)
{
Console.Write(ex);
}
return lst;
}
//View
#Html.DropDownListFor(m=>m.SelectedCountryId, this.ViewBag.CountryList as SelectList, new {#class = "form-control"})
// Model class
public class EditTrainingRegFormViewModel
{
public string Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Position { get; set; }
public string Company { get; set; }
public string Address { get; set; }
[Display(Name = "Choose country")]
public int ? SelectedCountryId { get; set; }
public string Code { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Cell_Number { get; set; }
public List<string> Dietary_requirement { get; set; }
public string Email { get; set; }
public int Country_Id { get; set; }
public string Country_Name { get; set; }
}

How to create multiple Radiobutton group in ASP.Net Core 2 and Razor?

I want to create multiple grouped Radio buttons. So, basically I have multiple questions and 3 radio buttons with answers. The problem I'm facing is how to return the selected value for the multiple radio buttons.
Controller
public IActionResult Test()
{
SafetyObservationCardForm form = new SafetyObservationCardForm();
using (IDbConnection dbConnection = Connection)
{
dbConnection.Open();
var questions = dbConnection.Query<QuestionsViewModel>("SELECT * FROM SOCQuestions ORDER BY soc_order_id");
var observationType = new List<ObservationType>
{
new ObservationType { Id = 1, Name = "Safe" },
new ObservationType { Id = 2, Name = "At Risk" },
new ObservationType { Id = 3, Name = "N/A" }
};
var rb = new List<Answer>();
foreach (var item in questions)
{
rb.Add(new Answer { Id = item.soc_question_id, ObservationTypes = observationType });
};
form.Answers = rb;
form.Questions = questions.ToList();
return View(form);
}
}
Model
public class SafetyObservationCardForm
{
public List<QuestionsViewModel> Questions { get; set; }
public string Comments { get; set; }
public string Location { get; set; }
public string Observer { get; set; }
public DateTime TimeStamp { get; set; }
public string Task { get; set; }
public ObserverType ObserverType { get; set; }
public IEnumerable<Answer> Answers { get; set; }
}
public class ObserverType
{
public bool Supervisor { get; set; }
public bool Peer { get; set; }
public bool Self { get; set; }
public bool Other { get; set; }
}
public class ObservationType
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Answer
{
public int Id { get; set; }
public IEnumerable<ObservationType> ObservationTypes { get; set; }
public int SelectedObservation { get; set; }
}
}
View
Here I'm trying the loop. Answers model is null when I submit the form for some reason.
#model DBI.Safety.Models.SafetyObservationCardForm
<form asp-action="CreateTest">
#foreach (var answer in Model.Answers)
{
<input name="#answer.Id" asp-for="#answer.SelectedObservation" type="radio"
value="#answer.Id" /> #answer.ObservationTypes
}
</form>

How to build a Create View for a Many to Many relationship

Ok, looks like someone should run into this, but I have not found anything that helps. This is my scenario.
I have a clients and skills model. The objective is to allow clients to rate each of a set of skills, all of them.
So, here I'll paste model, viewModel, Controller and View. at the end the crucial question
MODEL
namespace ClientSkills.Models
{
public class Client
{
public int ClientId { get; set; }
public string Name { get; set; }
public ICollection<ClientSkills> Skills { get; set; }
}
public class Skill
{
public int SkillId { get; set; }
public string Name { get; set; }
public ICollection<ClientSkills> Clients { get; set; }
}
public class Rating
{
public int RatingId { get; set; }
public string Name { get; set; }
public ICollection<ClientSkills> ClientSkills { get; set; }
}
public class ClientSkills
{
[Key, Column(Order=0)]
public int ClientId { get; set; }
[Key, Column(Order = 1)]
public int SkillId { get; set; }
public int RatingId { get; set; }
public Rating Rating { get; set; }
public Skill Skill { get; set; }
public Client Client { get; set; }
}
public partial class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public DbSet<Client> Client { get; set; }
public DbSet<Skill> Skill { get; set; }
public DbSet<Rating> Rating { get; set; }
public DbSet<ClientSkills> ClientSkills { get; set; }
}
}
VIEW MODEL
namespace ClientSkills.Models
{
public class RateViewModel
{
public RateViewModel()
{
this.Skills = new List<SkillViewModel>();
}
public RateViewModel(Client client)
{
this.ClientId = client.ClientId;
this.Skills = new List<SkillViewModel>();
if (client.Skills.Count == 0)
{
var context = new ApplicationDbContext();
foreach (var skill in context.Skill)
{
var skillVM = new SkillViewModel(skill);
skillVM.SelectedRatingid = context.Rating.First(r => r.Name == "No aplica").RatingId;
Skills.Add(skillVM);
}
}
else
{
foreach (var item in client.Skills)
{
var skillVM = new SkillViewModel(item);
skillVM.SelectedRatingid = item.SkillId;
this.Skills.Add(skillVM);
}
}
}
public int ClientId { get; set; }
public List<SkillViewModel> Skills { get; set; }
}
public class SkillViewModel
{
public SkillViewModel()
{
Ratings = new List<Rating>();
}
public SkillViewModel(Skill skill)
{
var context = new ApplicationDbContext();
this.Ratings = context.Rating.ToList();
this.SkillId = skill.SkillId;
this.SkillName = skill.Name;
}
public SkillViewModel(ClientSkills item)
{
var context = new ApplicationDbContext();
this.Ratings = context.Rating.ToList();
this.SkillId = item.SkillId;
this.SkillName = item.Skill.Name;
this.SelectedRatingid = item.RatingId;
}
public List<Rating> Ratings { get; set; }
public int SelectedRatingid { get; set; }
public int SkillId { get; set; }
public string SkillName { get; set; }
}
}
CONTROLLER
namespace ClientSkills.Controllers
{
public class RateController : Controller
{
//
// GET: /Rate/Create
public ActionResult Create()
{
//first, we assume there is an already selected user
var context = new ApplicationDbContext();
var client = context
.Client
.Include(c => c.Skills)
.First(c => c.Name.ToLower() == "ricker");
var model = new RateViewModel(client);
return View(model);
}
}
}
VIEW
This View is made creating a Create view with the wizard, deleting the useless field it creates and putting the code below
<table>
<tr>
<td>Skill</td>
<td>Rate</td>
</tr>
#foreach (var item in Model.Skills)
{
<tr>
<td>
#Html.DisplayFor(model => model.Skills.First(i => i.SkillName == item.SkillName).SkillName, new { #class = "control-label col-md-2" })
</td>
<td>
#Html.DropDownListFor(x => item.SelectedRatingid, new SelectList(item.Ratings, "RatingId", "Name"), "Seleccione el valor")
</td>
</tr>
}
</table>
The problem is that in the RateViewModel(Client client) constructor in the line skillVM.SelectedRatingid = context.Rating.First(r => r.Name == "No aplica").RatingId; I set a default value for the selectedRatingId property. I need to make sure all clients has all skills rated even if they forgot or bypass one of them.
When the view is loaded, and I was sure the ratesid was well set, the skill names look ok but the drop dpwn lists does not show the selected default value.
How can I make the view to bind the selectedRatingId property to the drop down list control?
Passing selected value to SelectList:
#Html.DropDownListFor(x => item.SelectedRatingid, new SelectList(item.Ratings, "RatingId", "Name", item.SelectedRatingid), "Seleccione el valor")
As I understand it (rightly or wrongly) that last parameter is an object if it matches with one of the options values - it is selected else the first one in the options is selected.
More info about the Selectlist overload.

Exporting class containing an ObservableCollection to csv in C#

I've found many solutions for exporting a class to CSV but my problem is this:
The class I'm trying to export has a property that is an observablecollection. eg:
public class ShipmentForExport
{
public string WaybillNumber { get; set; }
public DateTime WaybillDate { get; set; }
public string CustomerName { get; set; }
public string CustomerCode { get; set; }
public string CollectingBranchName { get; set; }
public string CollectingBranchCode { get; set; }
public string RecipientName { get; set; }
public string RecipientPhoneNumber { get; set; }
public string RecipientCellphoneNumber { get; set; }
public string RecipientCompany { get; set; }
public string DestinationAddress1 { get; set; }
public string DestinationAddress2 { get; set; }
public string DestinationCity { get; set; }
public string DestinationSuburb { get; set; }
public string DestinationProvince { get; set; }
public string DestinationCountry { get; set; }
public string DestinationPostalCode { get; set; }
***public ObservableCollection<InHouseParcel> Parcels { get; set; }***
}
When I try export a list of shipments to csv it works but obviously the parcels do not export the way I want them to.
I have tried using Filehelpers Library and csvHelper as well.
Any help is greatly appreciated!!
Josh's answer is outdated nowadays. You can use a typeconverter like:
CsvHelper.TypeConversion.TypeConverterFactory.AddConverter<ObservableCollection<string>>(new CsvHelper.TypeConversion.StringListConverter());
using (var txt = new StreamReader(filename))
using (var reader = new CsvHelper.CsvReader(txt))
{ .... }
namespace CsvHelper.TypeConversion
{
public sealed class StringListConverter : DefaultTypeConverter
{
public override object ConvertFromString(TypeConverterOptions options, string text)
{
var oc = new ObservableCollection<string>();
if (text.IndexOf('|') >= 0)
{
var list = text.Split('|').ToList<string>();// base.ConvertFromString(options, text);
oc = new ObservableCollection<string>(list);
}
return oc;
}
public override string ConvertToString(TypeConverterOptions options, object value)
{
var l = value as IEnumerable<string>;
if ( l == null || l.Count() == 0)
{
return "";
}
return string.Join("|", l);
}
public override bool CanConvertFrom(Type type)
{
return type == typeof(string);
}
}
}
Using CsvHelper (a library I maintain)...
When writing, you'll have to write manually because writing of collection properties isn't supported.
foreach( var record in records )
{
csv.WriteField( record.WaybillNumber );
...
foreach( var parcel in record.Parcels )
{
csv.WriteField( parcel );
}
}
Reading is a little easier because you can add it in the mapping.
Map( m => m.Parcels ).ConvertUsing( row =>
{
var oc = new ObservableCollection<InHouseParcel>();
var parcel = row.GetField<InHouseParcel>( 17 );
oc.Add( parcel );
} );
You'll need to convert the field values into InHouseParcel and loop through the remainder of the fields in the row. I'll leave that task to you.

KeyNotFoundException on SaveChanges()

Okey so i'm trying to update information in my database from a form.
But when i call db.SaveShanges() i get KeyNotFoundException.
I'm using MVC3 and EF 4.1.
I use Controller->Service->Repositry->EF design pattern.
The callstack:
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at System.Data.Objects.EntityEntry.UpdateComplexObjectSnapshot(StateManagerMemberMetadata member, Object userObject, Int32 ordinal, Object currentValue)
at System.Data.Objects.EntityEntry.DetectChangesInProperties(Boolean detectOnlyComplexProperties)
at System.Data.Objects.ObjectStateManager.DetectChangesInScalarAndComplexProperties(IList`1 entries)
at System.Data.Objects.ObjectStateManager.DetectChanges()
at System.Data.Objects.ObjectContext.DetectChanges()
at System.Data.Entity.Internal.InternalContext.DetectChanges(Boolean force)
at System.Data.Entity.Internal.InternalContext.GetStateEntries(Func`2 predicate)
at System.Data.Entity.Internal.InternalContext.GetStateEntries()
at System.Data.Entity.Infrastructure.DbChangeTracker.Entries()
at System.Data.Entity.DbContext.GetValidationErrors()
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
My repositrory db is a dbContext with a DbSet for the model i'm using.
public bool Save()
{
try
{
db.SaveChanges();
}
catch(Exception e)
{
return false;
}
return true;
}
My Service that calls the repository
public bool UpdateUserInformationFromSettingsModel(UserSettingsModel model)
{
int userInfoID = _profile.GetUserInformationID(model.userName);
UserInformation userInfo = _repository.Get(userInfoID);
if (userInfo == null)
{
return false;
}
userInfo.firstName = model.firstName;
userInfo.lastName = model.lastName;
userInfo.phone = model.phone;
userInfo.invoiceReciever = model.invoiceReciever;
userInfo.invoiceAddress = model.invoiceAddress;
userInfo.address = model.address;
userInfo.preferedLanguage = model.preferedLanguage;
bool saveSuccess = _repository.Save();
if(!saveSuccess)
{
return false;
}
return true;
}
My controller
[HttpPost]
public ActionResult Edit(UserSettingsModel model)
{
if(ModelState.IsValid)
{
if (_userService.UpdateUserInformationFromSettingsModel(model))
{
return RedirectToAction("Settings");
}
ModelState.AddModelError("", GuiText.editSettingsError);
}
return View(model);
}
The UserInformation Model
public class UserInformation
{
public int ID { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public string phone { get; set; }
public string invoiceSendOption { get; set; }
public string invoiceReciever { get; set; }
public Address invoiceAddress { get; set; }
public Address address { get; set; }
public string preferedLanguage { get; set; }
public string confirmCode { get; set; }
public UserSiteSettings siteSettings { get; set; }
public UserInformation()
{
firstName = "";
lastName = "";
phone = "";
invoiceSendOption = "";
invoiceReciever = "";
invoiceAddress = new Address();
address = new Address();
preferedLanguage = "";
confirmCode = "";
siteSettings = new UserSiteSettings();
}
The UserSettingsModel
public class UserSettingsModel
{
public string userName { get; set; }
[Display(Name = "name", ResourceType=typeof(GuiText))]
public string firstName { get; set; }
public string lastName { get; set; }
[Display(Name = "phone", ResourceType = typeof(GuiText))]
public string phone { get; set; }
[Display(Name = "invoiceInfo", ResourceType = typeof(GuiText))]
public string invoiceReciever { get; set; }
public Address invoiceAddress { get; set; }
[Display(Name = "address", ResourceType = typeof(GuiText))]
public Address address { get; set; }
[Display(Name = "prefLang", ResourceType = typeof(GuiText))]
public string preferedLanguage { get; set; }
public List<SelectListItem> preferedLanguageList { get; set; }
I have checked the variables in debugger and it all seems to be ok.
I'm using MySql connector v6.5.4.
So anyone got any ideas what the problem might be?
After some days of frustration and searching i found the problem.
I used a custom made equals method in my UserInformation and Address class. That caused the problems. Now i have removed it and changed my Unit Tests to work in another way.