Here is my code for adding a new registered user to the Firebase database :
TransactionResult AddUserToDatabaseTransaction(MutableData mutableData) {
if (mutableData != null)
{
List<object> users = mutableData.Value as List<object>;
if (users == null)
{ users = new List<object>();
}
users = new List<object>();
// Now we add the new score as a new entry that contains the email address and score.
Dictionary<string, object> newUserRegistration = new Dictionary<string, object>();
newUserRegistration["Dateofbirth"] = "22/03/1980";
newUserRegistration["Email"] = auth.CurrentUser.Email;
newUserRegistration["Full Name"] = "cool";
newUserRegistration["LastLoggedIn"] = "27/06/2017";
newUserRegistration["RegistrationDate"] = "26/04/2017";
users.Add(newUserRegistration);
// You must set the Value to indicate data at that location has changed.
mutableData.Value = users;
return TransactionResult.Success(mutableData);
}
else return TransactionResult.Abort();
}
public void AddUserToDatabase() {
DatabaseReference reference = FirebaseDatabase.DefaultInstance.GetReference("users");
DatabaseReference usersaddnow = reference.Child(auth.CurrentUser.UserId);
usersaddnow.RunTransaction(AddUserToDatabaseTransaction)
.ContinueWith(task => {
if (task.Exception != null) {
information.text +=task.Exception.ToString();
} else if (task.IsCompleted) {
information.text += " Transaction complete.";
}
}
);
}
Here is a snapshot of the database:
So, I am trying to add a user to database.
I succeeded in adding them as you can see from the picture, but it is adding a zero child before the user details. Can you please tell me why is this happening ?
I have been trying to get rid of this for hours an I can not find the solution.
The problem is because of arraylist
it's setting the data by it's own index i.e 0,1 etc
so it seems like in unity it uses these indexes by default
I can access testing and inner elements
It's easier to manage data this way and access it
Related
I'm not very experienced when it comes to development and I'm trying to secure an application so please bear with me. At the moment, the user is being authenticated and a new session is created using the following code:
public static void NewSession(Account account)
{
var redirectUrl = "Login.aspx";
if (account == null)
{
var sessionCookie = HttpContext.Current.Request.Cookies["test-app-session"];
if (sessionCookie != null)
ExpireCookie(sessionCookie);
}
else
{
var sessionCookie = new HttpCookie("test-app-session");
sessionCookie.Values["account-id"] = account.Id.ToString();
sessionCookie.Expires = DateTime.Now.AddHours(12);
HttpContext.Current.Response.Cookies.Add(sessionCookie);
var redirectCookie = HttpContext.Current.Request.Cookies["test-app-redirect"];
if (redirectCookie != null)
{
redirectUrl = redirectCookie.Values["url"];
ExpireCookie(redirectCookie);
}
if (string.IsNullOrWhiteSpace(redirectUrl))
redirectUrl = "Default.aspx";
}
HttpContext.Current.Response.Redirect(redirectUrl);
}
When the App validates the session, it then uses the below code:
public static Account FromSession()
{
var sessionCookie = HttpContext.Current.Request.Cookies["test-app-session"];
if (sessionCookie != null && long.TryParse(sessionCookie.Values["account-id"], out long accountId))
{
using (var db = Database.Connect())
{
using (var cmd = db.Command("SELECT * FROM Account WHERE id=#id").Parameter("#id", accountId, DbType.Int64))
using (var reader = cmd.ExecuteReader())
if (reader.Read())
return new Account(reader);
}
}
if (!Path.GetFileName(HttpContext.Current.Request.Path).Equals("Login.aspx", StringComparison.OrdinalIgnoreCase))
{
var redirectCookie = new HttpCookie("test-app-redirect");
redirectCookie.Values["url"] = HttpContext.Current.Request.Url.ToString();
redirectCookie.Expires = DateTime.Now.AddHours(1);
HttpContext.Current.Response.Cookies.Add(redirectCookie);
HttpContext.Current.Response.Redirect("Login.aspx");
}
return null;
}
The problem is that the account-id value can be easily guessed, so I want to use a unique value for this. I don't really know how I'd implement this, as I'm not sure how the value would then be tied to the users session if there isn't an identifier I can check against. Obviously I'm missing something fundamental in how session management is supposed to work, but I can't figure out what it is. If I create a GUID to store in the cookie, the browser saves it and knows what it is, but how does the server know what this ID is and link it to the user?
I am running through a set of records using a for each loop, and also doing simple checks to ensure that good data is inserted into a database table.
Sometimes the dataset can be missing the LegistarID value, the change I need to do in my code, is to add a check for LegistarItem,
if the value of LegistarID is missing, but the AgendaItem value is not, then assign the value of AgendaItem to LegistarID
if LegistarId is missing, and there is also no AgendaItem value, then return a message to the user, to let them know that these values need to be present in the dataset they are trying to import.
I know it does not sound complex, but I am having a hard time making this change successfully. I need a bit of help if possible, please.
Here is my code as I currently have it:
if (ModelState.IsValid)
{
using (Etities db = new Entities())
{
foreach (var i in meeting)
{
if (i.MeetingID == 0)
{
message = string.Format("This file is missing the Meeting ID value of at least 1 record. \n Verify that the data you are trying to upload meets the criteria, and then try to upload your file again.", i.MeetingID);
return new JsonResult { Data = new { status = status, message = message } };
}
else
{
// development
var compositeKey = db.MeetingAgenda.Find(i.MeetingID, i.AgendaItem);
if (compositeKey == null)
{
// Add new
// development
db.MeetingAgenda.Add(i);
//
}
else
{
// Serves as an update, or addition of a previously imported dataset
db.Entry(compositeKey).CurrentValues.SetValues(i.MeetingID);
db.Entry(compositeKey).State = EntityState.Modified;
}
}
}
db.SaveChanges();
status = true;
}
}
else
{
message = string.Format("Please, verify that the file you are trying to upload is correctly formatted, and that the data it contains, meets the expected criteria, then click the upload button again. \n Thank you!");
return new JsonResult { Data = new { status = status, message = message } };
}
I think that part of the code I need is something like this:
else if (i.LegistarID == 0 and i.AgendaItem != 0)
{
i.LegistarID = i.AgendaItem
}
I just am unsure how in the current code place it.
I would check all rows before returning a result.
if (ModelState.IsValid) {
var errors = new List<string> ();
var rowCounter = 1;
using (Etities db = new Entities ()) {
foreach (var i in meeting) {
if (i.MeetingID == 0) {
// Let the user know this row is bad
errors.Add ($"Row {rowCounter}: This file is missing the Meeting ID. Verify that the data you are trying to upload meets the criteria, and then try to upload your file again.");
}
// Check if LegistarID is missing
if (i.LegistarID == 0) {
// Check if Agenda Item is present
if (i.AgendaItem == 0) {
errors.Add ($"Row {rowCounter}: Meeting has no LegistarID and no Agenda Item. Please check data");
} else {
i.LegistarID = i.AgendaItem
}
}
// development
var compositeKey = db.MeetingAgenda.Find (i.MeetingID, i.AgendaItem);
if (compositeKey == null) {
// Add new
// development
db.MeetingAgenda.Add (i);
//
} else {
// Serves as an update, or addition of a previously imported dataset
db.Entry (compositeKey).CurrentValues.SetValues (i.MeetingID);
db.Entry (compositeKey).State = EntityState.Modified;
}
rowCounter++;
}
// If there are errors do not save and return error message
if (errors.Count > 0) {
return new JsonResult { Data = new { status = false, message = string.Join ("\n", errors) } };
}
db.SaveChanges ();
status = true;
}
} else {
message = string.Format ("Please, verify that the file you are trying to upload is correctly formatted, and that the data it contains, meets the expected criteria, then click the upload button again. \n Thank you!");
return new JsonResult { Data = new { status = status, message = message } };
}
The "if(i.MeetingID == 0)" else is redundant, because you are returning if the condition is met. So to avoid unneeded/confusing nesting I would rewrite the actual code (of the loop only) as:
foreach (var i in meeting)
{
if (i.MeetingID == 0)
{
message = string.Format("This file is missing the Meeting ID value of at least 1 record. \n Verify that the data you are trying to upload meets the criteria, and then try to upload your file again.", i.MeetingID);
return new JsonResult { Data = new { status = status, message = message } };
}
// development
var compositeKey = db.MeetingAgenda.Find(i.MeetingID, i.AgendaItem);
if (compositeKey == null)
{
// Add new
// development
db.MeetingAgenda.Add(i);
//
}
else
{
// Serves as an update, or addition of a previously imported dataset
db.Entry(compositeKey).CurrentValues.SetValues(i.MeetingID);
db.Entry(compositeKey).State = EntityState.Modified;
}
}
Then, I would add the new condition in between the MeetingID = 0 check and the rest of the code, like this:
foreach (var i in meeting)
{
if (i.MeetingID == 0)
{
message = string.Format("This file is missing the Meeting ID value of at least 1 record. \n Verify that the data you are trying to upload meets the criteria, and then try to upload your file again.", i.MeetingID);
return new JsonResult { Data = new { status = status, message = message } };
}
// *** New check on LegistarID and AgendaItem ***
if(i.LegistarID == 0)
{
// Is there a chance to fill LegistarID with AgendaItem?
if(i.AgendaItem != 0)
{
// Yes, fill it and then let the rest of the code flow peacefully.
i.LegistarID = i.AgendaItem
}
else
{
// No way: I must stop the procedure here and warn the user about this.
// return "these values need to be present in the dataset they are trying to import."
}
}
// development
var compositeKey = db.MeetingAgenda.Find(i.MeetingID, i.AgendaItem);
if (compositeKey == null)
{
// Add new
// development
db.MeetingAgenda.Add(i);
//
}
else
{
// Serves as an update, or addition of a previously imported dataset
db.Entry(compositeKey).CurrentValues.SetValues(i.MeetingID);
db.Entry(compositeKey).State = EntityState.Modified;
}
}
I will load data via API into my ListView async.
I have a list of items (1 to 6300) and in my search box I can search for the items and then it will be displayed in the ListView.
Now I want to show the items Avg prices, which come from a JSON Api.
If you want to take a look at the tool, here is the git link: https://github.com/Triky313/AlbionOnline-StatisticsAnalysis
My current method looks like this. Once new data is loaded from the API and then again only if they are older than one hour.
public static ObservableCollection<MarketStatChartItem> MarketStatChartItemList = new ObservableCollection<MarketStatChartItem>();
public static async Task<string> GetMarketStatAvgPriceAsync(string uniqueName, Location location)
{
try
{
using (var wc = new WebClient())
{
var apiString = "https://www.albion-online-data.com/api/v1/stats/charts/" +
$"{FormattingUniqueNameForApi(uniqueName)}?date={DateTime.Now:MM-dd-yyyy}";
var itemCheck = MarketStatChartItemList?.FirstOrDefault(i => i.UniqueName == uniqueName);
if (itemCheck == null)
{
var itemString = await wc.DownloadStringTaskAsync(apiString);
var values = JsonConvert.DeserializeObject<List<MarketStatChartResponse>>(itemString);
var newItem = new MarketStatChartItem()
{
UniqueName = uniqueName,
MarketStatChartResponse = values,
LastUpdate = DateTime.Now
};
MarketStatChartItemList?.Add(newItem);
var data = newItem.MarketStatChartResponse
.FirstOrDefault(itm => itm.Location == Locations.GetName(location))?.Data;
var findIndex = data?.TimeStamps?.FindIndex(t => t == data.TimeStamps.Max());
if (findIndex != null)
return data.PricesAvg[(int) findIndex].ToString("N", LanguageController.DefaultCultureInfo);
return "-";
}
if (itemCheck.LastUpdate <= DateTime.Now.AddHours(-1))
{
var itemString = await wc.DownloadStringTaskAsync(apiString);
var values = JsonConvert.DeserializeObject<List<MarketStatChartResponse>>(itemString);
itemCheck.LastUpdate = DateTime.Now;
itemCheck.MarketStatChartResponse = values;
}
var itemCheckData = itemCheck.MarketStatChartResponse
.FirstOrDefault(itm => itm.Location == Locations.GetName(location))?.Data;
var itemCheckFindIndex =
itemCheckData?.TimeStamps?.FindIndex(t => t == itemCheckData.TimeStamps.Max());
if (itemCheckFindIndex != null)
return itemCheckData.PricesAvg[(int) itemCheckFindIndex]
.ToString("N", LanguageController.DefaultCultureInfo);
return "-";
}
}
catch (Exception ex)
{
Debug.Print(ex.StackTrace);
Debug.Print(ex.Message);
return "-";
}
}
Through the API requests everything loads very long and I can not normally use the search.
Does anyone know of a better solution for loading asnyc data without the search problems?
EDIT:
Here again visually represented...
The item list is already loaded and the search is very fast.
Now you can see some minuses on the right side, there should be numbers. These numbers are loaded later when the item is shown in the list.
The problem: The search is extremely stale if he has 50+ items in the search and then fill them with the data of the API.
For each item, an API request is made.
Can this API query be canceled if the search changes or is there another possibility?
My objects will not save no matter what I do they will fetch and get info and make a new record but not update.
This is the code that details with getting existing patient and then modifying the record setting the state then calling save change this is cracking my head the last three hours what is going wrong. I was told you had to change the entity state of an object before it would no if to save but when i try to attach it it says its already attached
Appointment _appointment = new Appointment();
int errorCount = 0;
Patient _patient = SourceDal.getPatientByPatientNewId(Convert.ToInt32(txtPatientId.Text));
_patient.SSN = txtSSN.Text;
_patient.FirstName = txtPatientFirstName.Text;
_patient.LastName = txtPatientLastName.Text;
_patient.Middle = txtPatientMiddle.Text;
_patient.AddressOne = txtPatientAddressOne.Text;
_patient.City = txtPatientCity.Text;
_patient.State = txtPatientState.Text;
_patient.ZipCode = txtPatientZip.Text;
_patient.HomePhone = txtPatientHomePhone.Text;
_patient.WorkPhone = txtPatientWorkPhone.Text;
_patient.CellPhone = txtPatientCellPhone.Text;
if (rBtnHomePhone.Checked == true)
// _patient.ApptPhone = txtPatientHomePhone.Text;
if (rBtnHomePhone.Checked == true)
// _patient.ApptPhone = txtPatientHomePhone.Text;
if (rBtnWorkPhone.Checked == true)
// _patient.ApptPhone = txtPatientWorkPhone.Text;
_patient.BirthDate = dtBirthDate.DateTime;
_patient.emailAddress = txtPatientEmail.Text;
_patient.Race = Convert.ToInt32(dpRace.SelectedValue);
_patient.Ethnicity =Convert.ToInt32(dpEthnicity.SelectedValue);
_patient.Language = Convert.ToInt32(dpLanguages.SelectedValue);
if (dpGender.Text == "")
{
dpGender.Focus();
errorCount = 1;
lblGenderRequired.Text = "* Gender is required.";
}
else
{
errorCount = 0;
lblGenderRequired.Visible = false;
}
_patient.Gender = "M";
_patient.PatientID = txtPatientId.Text;
SourceDal.SourceEntities.Patients.Attach(_patient);
SourceDal.SourceEntities.Patients.Context.ObjectStateManager.ChangeObjectState(_patient, EntityState.Modified);
SourceDal.SourceEntities.SaveChanges();
The error I get is
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Data.Entity.dll
Additional information: An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
Edit 2:
Code to show my function getPaitnetByPatineyNewId
public Patient getPatientByPatientNewId(int newId)
{
Patient patient = new Patient();
if (newId == -1)
{
patient = new Patient();
}
else
{
patient = SourceEntities.Patients
.Where(w => w.ID == newId)
.FirstOrDefault();
}
return patient;
}
I think you have some issues with proper separation of concerns within your DAL, but for the short solution, you should only add (and not attach) if it's a new entity
if (_patent.PatentId == 0)
{
_patient.PatientID = txtPatientId.Text; // If you're using an identity column, remove this line. I would also strongly suggest not letting the user change this...
SourceDal.SourceEntities.Patients.Add(_patient);
}
For Anyone else the above scenarios did not work for me so this is what I had to do. I put a flag on my forms isUpdate and check that on the save button then if save call similar to below then if add just call savechanges and its now working thank you for everyone help hope this help someone.
public void SaveProviders(Provider _providers)
{
try
{
using (var ctx = new SMBASchedulerEntities(this.Connectionstring))
{
ctx.Providers.Add(_providers);
ctx.Entry(_providers).State = System.Data.Entity.EntityState.Modified;
ctx.SaveChanges();
}
}
catch (DbEntityValidationException e)
{
foreach (var eve in e.EntityValidationErrors)
{
Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
foreach (var ve in eve.ValidationErrors)
{
Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
ve.PropertyName, ve.ErrorMessage);
}
}
throw;
}
}
i'm trying to add multiple textbox values to database it is working on just single textbox row but now working when i'm adding multiple rows of textboxes. i'm sharing what i have done so far.
Action Method:
public async Task<ActionResult> Create(FormCollection values)
{
var customer = new Customer();
var model = new TicketViewModel();
TryUpdateModel(model.TicketDetail);
try
{
foreach (var ticket in model.Tickets)
{
ticket.Date = DateTime.Now;
ticket.ProcessId = DateTime.Now.Ticks.ToString().Substring(12, 6);
ticket.CreationMethod = "Manual";
ticket.isCustomer = User.IsInRole("Customer") ? true : false;
ticket.Total = 0;
ticket.Email = model.TicketDetail.Ticket.Email;
customer.City = "Not Specified";
customer.Country = "Not SPecified";
customer.Image = "~/Images/nopic.jpg";
customer.Password = System.Web.Security.Membership.GeneratePassword(11, 3);
customer.IsActive = true;
customer.CreationMethod = "Manual";
customer.DateAdded = DateTime.Now;
customer.Email = ticket.Email;
customer.FirstMidName = string.IsNullOrEmpty(ticket.FullName) ? "Not Specified" : ticket.FullName;
customer.LastName = "Not Specified";
customer.Salutation = "Not Specified";
customer.UserName = DateTime.Now.Ticks.ToString().Substring(3, 9);
//ticket detail
var abcd = values["abcd"].ToString();
var getID = await db.Parts.Where(c => c.PartNumber == abcd)
.FirstOrDefaultAsync();
model.TicketDetail.GenericOrderId = ticket.GenericOrderId;
model.TicketDetail.PersonID = customer.PersonID;
model.TicketDetail.Status = "New";
model.TicketDetail.PartId = getID.PartId;
model.TicketDetail.Ticket.Date = DateTime.Now;
}
try
{
// db.Tickets.Add(ticket);
db.Customers.Add(customer);
db.TicketDetails.Add(model.TicketDetail);
}
catch (Exception ex)
{
ViewBag.PartId = new SelectList(db.Parts.Take(5), "PartId", "Name");
ModelState.AddModelError("", string.Format(ex.Message + "\n" + ex.InnerException));
return View(model.TicketDetail);
}
// Save all changes
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
catch(Exception ex)
{
ModelState.AddModelError("", String.Format(ex.Message + "\n" + ex.InnerException));
//Invalid - redisplay with errors
return View(model.TicketDetail);
}
}
ViewModel:
public class TicketViewModel
{
public TicketViewModel()
{
TicketDetails = new List<TicketDetail>();
TicketDetail = new TicketDetail();
Ticket = new Ticket();
Tickets = new List<Ticket>();
}
public virtual Ticket Ticket { get; set; }
public virtual IEnumerable<Ticket> Tickets { get; set; }
public virtual TicketDetail TicketDetail { get; set; }
public virtual IEnumerable<TicketDetail> TicketDetails { get; set; }
}
it is also giving error on this "TryUpdateModel(model.TicketDetail);" the error is value cannot be null, please guide me i'm stuck here i have searched internet but couldn't found any appropriate solution. i want to add multiple records
First all properties of your TicketViewModel class have to be instantiated.
To add multiple records (multiple Insert) you could use a StringBuilder and append the insert statements to it. You then have one big query string to be executed on your database.
If using values this is also a valid way:
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
And loading the data to be inserted directly from a file is even faster.
Edit
(after down voting for no reason)
Because some people act like they know it all:
SQL injections are indeed a serious problem when dealing with Database access. That's no secret at all. A common technique to prevent the SQL query from being 'highjacked' you simply use the SQLCommand.Parameters property which is used to map each value individually to the statement to separate the query statement from the data (values) this way. It's now impossible to inject or manipulate statements whithout breaking them. And server side validation is standard to obtain maximum security as well as escaping special input characters and avoiding the use of privilegs with no or low restrictions.
This is NOT a wrong answer.