I'm currently developing a side-project, which will consist of a Database, Web API, and then different Apps on top which consume the restful API.
I've started thinking about User accounts and how to make these secure. Currently, as a standard, I have the following model in the Data Layer:
public int Id { get; set; }
public string Username { get; set; }
public string Full_Name { get; set; }
public string Password { get; internal set; }
public string Salt { get; internal set; }
Now, obviously, when someone makes a request for /Users/{id}, the User associated with that Id is returned. However, I don't want to return the Password or Salt, so really don't want those to be part of the User model.
I have toyed with the idea of creating a different, internal-only model for UserDetails, and shipping the Password/Salt, etc off into that. However, I hit the snag of, when signing up to the service, how do I get a desired password from the user to the API?
There's probably a really simple implementation of what I want to do, but I can't think of one right now. Any help would be greatly appreciated!
You should use a special view model without the password property for this purpose. Then inside your API you will map between your data model and the view model and return the view model out from your Web API method. Same stands true for the Salt property as well.
Related
I have two Model classes to be created using Entity Framework: Skill and Activity. The following are the definitions of each:
Skill.cs
public class Skill
{
public int Id { get; set; }
public String Name { get; set; }
}
Activity.cs
public class Activity
{
public int Id { get; set; }
public String Name { get; set; }
public virtual List<Skill> RequiredSkills { get; set; }
}
Ideally, in the database, I'd want the Activity to be linked via foreign key to a association entity (e.g. SkillActivityAssoc) and the Skill not to have to do anything with it. I don't need to track which activities need a certain skill. I just need to track what skills are needed for each activity thus explaining why I don't have a List in the Skill class. I hope that made sense.
My question is: Is this the right way to go about doing this? When I update the RequiredSkills property of Activity via:
activity.RequiredSkills = someInstanceOfRequiredSkillsList;
dbcontext.Entry(activity).State = EntityState.modified;
dbcontext.SaveChanges();
.., it doesn't work. I'm already speculating that it's because I'm not able to update the association entity. Moreover, my current implementation has a virtual List<Activity> property in the Skill class which I want to get rid of. How do I go about changing my model design and how do I update RequiredSkills accordingly?
Thank you in advance!
virtual is for lazy loading and track changes in EF. You can read more about it here: Understanding code first virtual properties. You should also read MSDN documentation about loading entities in EF: https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx
Since you want to have more than one Skills in each Activity and each Skills can be in more than one Activity as well, you have a many-to-many relantionship. Please read this example: How to create a many-to-many mapping in Entity Framework? and this http://www.entityframeworktutorial.net/code-first/configure-many-to-many-relationship-in-code-first.aspx
In my EF 6 Model First application, I have an entity with a many-to-many navigation property to another entity. In the first entity, I need to add several references to the same record in navigation property.
The first entity is a “saleslistItem” and the second entity is “warehouseItem”. Normally there will be a one-to-one relationship here, but exceptionally there will be some bundles where one “saleslistItem” contains several “warehouseItems”. “WarehouseItem” can also be included in several “salesListItems”. At the end of the project, my customer says, testing it, that “saleslistItem” must be able to consist of several “WarehouseItems” of the same kind (like two boxes of smoked ham).
These data is used several places in my code. (ie. doing a sale removes items from the warehouse) If I could just add several the same reference, my code would work without any modifications. But in the implementation of the navigation property the “hashtable”-collection is used, and this collection requires unique entries. Is there a workaround here? Performance is irrelevant as the data amount is small.
If there are no such workaround, is it possible to store values together with the instance of navigation property? Maybe it is implemented as a field in the join-table???
Any other suggestions?
Need a solution so the customer pays the last part of the bill!
So you currently have a 1:1 from SalesListItem toWarehouseItemvia a ForeignKey inSalesListItem`? Sounds like you need:
public class SalesListItem
{
public virutal ICollection<SalesListWarehouseItem> WareHouseItems { get; set; }
}
public class SalesListWarehouseItem
{
public virtual SalesListItem Parent{ get; set; }
public virtual WarehouseItem WarehouseItem { get; set; }
public int Quantity { get; set; } // maybe double?
}
I am using MVC with Entity framework.
I have a Client requirement that client want to set default period for all the context table. When he set some date range into the user setting page it saves the detail to the sql table. When the app runs application all the data from table will come for that particular period.
I want to apply this filter in my context file.
Here is my context file and suppose i got the date here.
public class MyContext : DbContext
{
public DbSet<Contact> Contacts { get; set; }
public DbSet<Contact_phone> Contact_phones{ get; set; }
}
How i achieve this.
Thanks
I'm hoping this is a simple question. I've created an Azure Mobile Apps project based upon the sample ToDo project, adding my own tables/data objects. The problem I'm having is adding/POSTing records to a table that has a foreign key relationship to another. The following is my Employee table data object:
public class Employee : EntityData
{
public string Name { get; set; }
public string EmailAddress { get; set; }
public bool IsActive { get; set; }
public string EmployeeTypeId { get; set; }
public virtual EmployeeType EmployeeType { get; set; }
}
...and this is my EmployeeType data object:
public class EmployeeType : EntityData
{
public string EmpType { get; set; }
public bool IsActive { get; set; }
}
The virtual EmployeeType property in the Employee class was necessary, I believe, to create the relationship with the EmployeeType table when using EF Code First to create the tables in the database. (At least, that's what I understand, and it worked) I am able to insert records from my Xamarin client app into the EmployeeType table using the InsertAsync method, but I receive a "Bad Request" 400 error when trying to insert into the Employee table.
I've looked around quite a bit for solutions, but everything refers to Azure Mobile Services and not Apps. If need be, I can update this question with my client side model classes (I'm on my PC now and don't have access to the Xamarin Studio project on my Mac). For reference, these classes are pretty much the same as the data objects - just each property is decorated with the JsonProperty attribute, except the virtual property outlined in the service. And for completeness, I did try adding that property to the client object and it still threw the "Bad Request" 400 error.
Thanks for any direction you can offer me.
Most likely, the problem is happening when trying to map the foreign key. Are you specifying all of the fields for employee type? I recommend that you do the following:
Use Fiddler or attach a delegating handler to your client to see what the outgoing request looks like. Update your comment with the JSON body. See https://github.com/Azure/azure-mobile-apps/wiki/Help,-my-app-isn't-working!#log-outgoing-requests-in-managed-client-xamarin-windows.
Attach a debugger to your server project. You can do this while running locally or after your solution is deployed to Azure, but you'll have better performance if you run locally. See https://github.com/Azure/azure-mobile-apps/wiki/Help,-my-app-isn't-working!#remote-debugging-net-server-sdk.
I suspect that the problem is that EmployeeType ends up being null in your deserialized object, and then Entity Framework rejects the DB insert.
Could you get more information from the bad request? Try adding this to the table controller
protected override void Initialize(HttpControllerContext controllerContext)
{
controllerContext.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
}
I'm new to Entity Framework and am trying to learn how to use Code First to load entities from the database.
My model contains a user:
public class User
{
public int UserID { get; set; }
[Required]
public string Name { get; set; }
// Navigation Properties
public virtual ICollection<AuditEntry> AuditEntries { get; set; }
}
Each user can have a set of audit entries each of which contains a simple message:
public class AuditEntry
{
public int AuditEntryID { get; set; }
[Required]
public string Message { get; set; }
// Navigation Properties
public int UserID { get; set; }
public virtual User User { get; set; }
}
I have a DBContext which just exposes the two tables:
public DbSet<User> Users { get; set; }
public DbSet<AuditEntry> AuditEntries { get; set; }
What I want to do is load a list of AuditEntry objects containing the message and the related User object containing the UserID and Name properties.
List<AuditEntry> auditEntries = db.AuditEntries.ToList();
Because I have my navigation properties marked as virtual and I haven't disabled lazy loading, I get an infinitely deep object graph (each AuditEntry has a User object, which contains a list of the AuditEntries, each of which contains a User object, which contains a list of AuditEntries etc)
This is no good if I then want to serialize the object (for example to send as the result in a Web API).
I've tried turning off lazy loading (either by removing the virtual keywords from my navigation properties in the model, or by adding this.Configuration.LazyLoadingEnabled = false; to my DBContext). As expected this results in a flat list of AuditEntry objects with User set to null.
With lazy loading off, I've tried to eager load the User like so:
var auditentries = db.AuditEntries.Include(a => a.User);
but this results in the same deep / cyclic result as before.
How can I load one level deep (e.g. include the user's ID and name) without also loading back-references / following navigation properties back to the original object and creating a cycle?
After much hacking, I've come up with the following potential solution using a dynamic return type and projection in my Linq query:
public dynamic GetAuditEntries()
{
var result = from a in db.AuditEntries
select new
{
a.AuditEntryID,
a.Message,
User = new
{
a.User.UserID,
a.User.Username
}
};
return result;
}
This produces (internally) the following SQL which seems sensible:
SELECT
[Extent1].[AuditEntryID] AS [AuditEntryID],
[Extent1].[Message] AS [Message],
[Extent1].[UserID] AS [UserID],
[Extent2].[Username] AS [Username]
FROM [dbo].[AuditEntries] AS [Extent1]
INNER JOIN [dbo].[Users] AS [Extent2] ON [Extent1].[UserID] = [Extent2].[UserID]
This produces the results that I'm after, but it seems a bit long winded (especially for real life models that would be significantly more complex than my example), and I question the impact this will have on performance.
Advantages
This gives me a lot of flexibility over the exact contents of my returned object. Since I generally do most of my UI interaction / templating on the client side, I frequently find myself having to create multiple versions of my model objects. I generally need a certain granularity over which users can see which properties (e.g. I might not want to send every user's email address to low-privilege user's browser in an AJAX request)
It allows entity framework to intelligently build the query and only select the fields that I have chosen to project. For example, inside each top level AuditEntry object, I want to see User.UserID and User.Username but not User.AuditEntries.
Disadvantages
The returned type from my Web API is no longer strongly typed so I couldn't create a strongly typed MVC view based on this API. As it happens this is not a problem for my particular case.
Projecting manually in this way from a large / complex model could result in a lot of code, seems like a lot of work and has the potential to introduce errors in the API. This would have to be carefully tested.
The API method becomes tightly coupled with the structure of the model and since this is no longer fully automated based on my POCO classes, any changes made to the model would have to be reflected in the code that loads them.
Include method?
I'm still a little confused about the use of the .Include() method. I understand that this method will specify that related entities should be "eager loaded" along with the specified entity. However, since the guidance seems to be that navigation properties should be placed on both sides of a relationship and marked as virtual, the Include method seems to result in a cycle being created which has a significant negative impact on it's usefulness (especially when serializing).
In my case the "tree" would look a little like:
AuditEntry
User
AuditEntries * n
User * n
etc
I'd be very interested to hear any comments about this approach, the impact of using dynamic in this way or any other insights.