Entity Validation Error in Asp.Net MVC - asp.net

I am working on ASP.net MVC ...i have made database and now i am using the code below to insert data in the database using View Model class.
But it gives Entity Validation Error on db.savechanges() in user table(as tbl
_user). Please let me know where i am doing mistake.
Code to insert in DB
public string RegisterStudent(RegisterationLoginViewModel svm)
{
tbl_User_Role usr_role = new tbl_User_Role
{
// UserRole_Id=svm.User_Role_id,
RoleName = svm.User_Role,
Dsecription=svm.Description,
OtherDetails=svm.OtherDetails,
};
db.tbl_User_Role.Add(usr_role);
db.SaveChanges();
tbl_User S_Up = new tbl_User
{
FullName = svm.Full_Name,
DOB = svm.Date_of_Birth,
Address = svm.Home_Address,
MobileNumber = svm.Mobile_Number1,
CNIC = svm.CNIC,
Country = svm.Country,
Provience = svm.Provience,
City = svm.City,
UserRole_Id = usr_role.UserRole_Id,
Gender = svm.Gender,
CreatedOn = DateTime.Now,
};
db.tbl_User.Add(S_Up);
db.SaveChanges(); -->**Exception is thrown at this line**

If your UserRole_Id in model tbl_User_Role is not auto generated, then writing this line of code UserRole_Id = usr_role.UserRole_Id giving null because may be it is the Foreign Key of tbl_User table.
Beside, If you have set DatabaseGeneratedOption.Identity then you need to get it's UserRole_Id after saving the usr_role and then assign it to UserRole_Id.
And finally recheck your Required fields are not null and foreign key is getting value.

Related

sqlite in Xamarin.Froms how to Update individual record in Local DB

I am trying to update individual records in sqlite database. I know how to Insert and delete records. I'd like to Update an individual record in a similar way to how I am deleting an individual record below. This uses a linq statement to get the record by Asset ID. I'd then like to pass my data to this to update.
I've also included how I insert a new record for reference. Does anybody have an example that they could share?
Delete an existing record
using (SQLiteConnection localconn = new SQLiteConnection(App.FilePath))
{
localconn.CreateTable<Road_Inspections>();
localconn.Table<Road_Inspections>().Where(x => x.Unique_ID == unique_ID).Delete();
}
Insert new record
Road_Inspections lri = new Road_Inspections()
{
ID = id,
Road_ID = Road_ID.Text.ToString(),
Asset_ID = Asset_ID.Text.ToString(),
Defect_Type = txtDefectType.Text.ToString(),
Response = txtResponse.Text.ToString(),
Inspection_Date = DateTime.Now,
};
using (SQLiteConnection conn = new SQLiteConnection(App.FilePath))
{
conn.CreateTable<Road_Inspections>();
int rowsAdded = conn.Insert(lri);
await DisplayAlert("Success", "Inspeciton Saved to Device", "OK");
}
You need a primary Key or Id in your object Announcement to identify your unique object in your database, for example:
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
Since you want to update you have to get the original entry from the database first.
And then you can edit and update it. So, you don't need to delete it before you insert a new one.
In xamarin form you can use nuget sqlite-net-pcl to achieve this.
Please refer to the following code:
public Task<int> SaveItemAsync(TodoItem item)
{
if (item.ID != 0)
{
return Database.UpdateAsync(item);
}
else
{
return Database.InsertAsync(item);
}
}
For more details,you can check: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/data-cloud/data/databases .
And there is a sample included in above document, you can check it here:https://learn.microsoft.com/en-us/samples/xamarin/xamarin-forms-samples/todo/

Linq not being recognized parse in query

I am trying to make a login page. When I try to receive the userdata with linq I get an exception because I try to use Parse in my query. I searched a bit online and found out it is because Linq doesn't recognize Parse. From what I understand I have to translate the not recognisable code to code that linq/slq recognises. Since I have just started using linq queries I have no idea how to accomplish this.
My query:
public static UserDetails GetUser(UserDetails userde)
{
var usr = from u in db.Users
join r in db.Roles on u.RoleId equals r.IdRole
where u.Email == userde.Email && u.Active == true
select new UserDetails
{ Firstname = u.Firstname,
Surname = u.Surname,
Email = u.Email,
Function = u.Function,
Password = u.Password,
Salt = u.Salt,
Userroles = (UserRoles)Enum.Parse(typeof(UserRoles), r.Role1)
};
return usr.FirstOrDefault();
}
I checked these articles:
linq to entities does not recognize method
linq to entities does not recognize the methods system object parsesystem type
you should first use FirstOrDefault() and parse it later. Otherwise linq is still trying to build the select-statement. After FirstOrDefault (or ToList,...) you have your result and can then parse it without problems.
Should be something like this:
public static UserDetails GetUser(UserDetails userde)
{
var usr = from u in db.Users
join r in db.Roles on u.RoleId equals r.IdRole
where u.Email == userde.Email && u.Active == true
select new UserDetails { Firstname = u.Firstname,
Surname = u.Surname,
Email = u.Email,
Function = u.Function,
Password = u.Password,
Salt = u.Salt,
// store the database-value in another property
UserrolesUnparsed = r.Role1
};
// get the database-results
UserDetails details = usr.FirstOrDefault();
// parse the database-value and set it to the property you want to
details.Userroles = (UserRoles)Enum.Parse(typeof(UserRoles), details.UserrolesUnparsed);
return details;
}
sure, there are better/cleaner methods, but this is just to explain you.

Allowing the attacker to access unathorized records finding

I have a scan finding and hope someone can provide any ideas as to best ways to resolve the issue. First I will show the scan Finding then my code and finally what the scanner's recommended solution is.
Finding
Without proper access control, the method GetAttributeKey() in Provider.cs can execute a SQL statement on line 163 that contains an attacker-controlled primary key, thereby allowing the attacker to access unauthorized records.
Rather than relying on the presentation layer to restrict values submitted by the user, access control should be handled by the application and database layers. Under no circumstances should a user be allowed to retrieve or modify a row in the database without the appropriate permissions. Every query that accesses the database should enforce this policy, which can often be accomplished by simply including the current authenticated username as part of the query.
My Code:
Offending line:
myParam.SqlParam.Value = attribute;
Method:
public string GetAttributeKey(string attribute)
{
string qry = "SELECT ws_attribute_key FROM webservice_attributes WHERE ws_attribute = #attribute";
QueryContainer Instance = new QueryContainer(qry);
MyParam myParam = new MyParam();
myParam.SqlParam = new SqlParameter("#attribute", Instance.AddParameterType(_DbTypes._string));
myParam.SqlParam.Value = attribute;
Instance.parameterList.Add(myParam);
object key = ExecuteScaler(Instance);
return Convert.ToString(key);
}
Scanner's Recommend fix:
string user = ctx.getAuthenticatedUserName();
int16 id = System.Convert.ToInt16(invoiceID.Text);
SqlCommand query = new SqlCommand(
"SELECT * FROM invoices WHERE id = #id AND user = #user", conn);
query.Parameters.AddWithValue("#id", id);
query.Parameters.AddWithValue("#user", user);
SqlDataReader objReader = query.ExecuteReader();
I think the problem is dealing with the code calling the GetAttributeKey. The method is called only if the user has no access to to the Attribute. I think I need some type of checking. Here is the calling code:
if (result.Rows.Count > 0)
{
// get the attribute
DataRow[] rows = result.Select("ws_attribute = '" + attribute + "'");
if (rows.Length > 0)
{
// check time range
string hr = DateTime.Now.Hour.ToString();
DataRow[] valid = result.Select("ws_attribute = '" + attribute + "' AND start_time <= " + hr + " AND end_time >= " + hr);
if (valid.Length > 0)
{
ws_user_attribute_key = Convert.ToInt32(valid[0]["ws_user_attribute_key"].ToString());
ret = true;
// generate salt
TextEncryptor te = new TextEncryptor();
salt = te.CreateSalt(8);
// save to the log, return false if failed to log
if (!LogTransfer(ipAddress, accessDate, fileName, ws_user_attribute_key, salt, out logKey))
return false;
}
else
{
ret = false;
LogInvalidAccess(username, rows[0]["ws_attribute_key"].ToString(), ipAddress, accessDate, WSInvalidAccessReason.OutsideValidTimeRange);
}
}
else
{
// if user has no access to attribute
ret = false;
LogInvalidAccess(username, GetAttributeKey(attribute), ipAddress, accessDate, WSInvalidAccessReason.AttributeNotAccessible);
}
}
else
{
ret = false;
LogInvalidAccess(username, GetAttributeKey(attribute), ipAddress, accessDate, WSInvalidAccessReason.InvalidAccount);
}

push data from web form into CRM 2015 with duplicate detection before creating new records inside CRM

Guys.
I have a web form to push metadata into CRM 2015 online by creating new records. But before creating new records in CRM, I would like to check if this records(First Name, Last Name, DOB) duplicate or not. If duplicates, updates the existing record, If not, create a new record.
My current idea is, that on the web form(ASP.NET APP) retrieve all records(Names, DOB) and compare with input metadata, if match, updates or creates new record. But I am not sure if there is simple way to do this.
Do you have any suggestion?
Appreciate it.
I think I just got it.
bool hasDulicate = false;
//duplicate detection
FilterExpression codeFilter = new FilterExpression(LogicalOperator.And);
codeFilter.AddCondition("firstname", ConditionOperator.Equal, firstname.Text);
codeFilter.AddCondition("lastname", ConditionOperator.Equal, lastname.Text);
QueryExpression query = new QueryExpression
{
EntityName = "contact",
ColumnSet = new ColumnSet(true), // we assume you want to retrieve all the fields
Criteria = codeFilter
};
EntityCollection records = service.RetrieveMultiple(query);
int totalrecords = records.Entities.Count;
foreach (Entity record in records.Entities)
{
if (record["emailaddress1"] != null)
{
record["emailaddress1"] = email.Text;
record["mobilephone"] = phone.Text;
proxy.Update(record);
hasDulicate = true;
}
}
if (hasDulicate == false)
{
Entity contact = new Entity("contact");
contact["firstname"] = Convert.ToString(firstname.Text);
contact["lastname"] = Convert.ToString(lastname.Text);
contact["emailaddress1"] = Convert.ToString(email.Text);
contact["mobilephone"] = Convert.ToString(phone.Text);
Guid conid = proxy.Create(contact);
}

Custom RoleProvider: Can't insert record in UsersInRole Table

I have implemented a LINQ to SQL based RoleProvider, when I assign role to a user following exception is thrown while AddUsersToRoles method is called. I have defined a composite primary key userid & roleId on this table, it still throwing this exception:
Can't perform Create, Update or Delete
operations on 'Table(UsersInRole)'
because it has no primary key.
My LinQ to SQL implementation of AddUsersToRoles method is as follows. It breaks at db.UsersInRoles.InsertOnSubmit(userInRole);
using (RussarmsDataContext db = new RussarmsDataContext())
{
List<UsersInRole> usersInRole = new List<UsersInRole>();
foreach (string username in usernames)
{
foreach (string rolename in rolenames)
{
UsersInRole userInRole = new UsersInRole();
object userId = ProvidersUtility.GetUserIdByUserName(username,applicationName);
object roleId = ProvidersUtility.GetRoleIdByRoleName(rolename,applicationName);
if (userId != null && roleId != null)
{
userInRole.UserId = (Guid)userId;
userInRole.RoleId = (Guid)roleId;
db.UsersInRoles.InsertOnSubmit(userInRole);
}
}
}
try
{
// db.UsersInRoles.InsertAllOnSubmit(usersInRole);
db.SubmitChanges();
}
catch (ChangeConflictException)
{
db.ChangeConflicts.ResolveAll(RefreshMode.OverwriteCurrentValues);
db.SubmitChanges();
}
}
Any help will be appreciated.
Thanks.
LINQ to SQL does not natively support many to many... the joining table has to have two foreign key columns PLUS 1 primary key column with the IDENTITY attribute.

Resources