In my solution there are total three projects. Two of them is web application in ASP.Net MVC and one is C# class library. Both web applications use same DB so I created C# class library and put ADO.Net Entity Data Model(EDMX) in it. I added reference of C# class libray project in web applications and using ADO.Net Entity Data Model to access database. This working properly, I am able to access table, add/edit/delete records but issue comes when I am trying to write data annotations for validation. Class generated by EDMX in C# class library project for table is like this:
namespace EDMXProjectNamespace
{
using System;
using System.Collections.Generic;
public partial class DrugClass
{
public DrugClass()
{
this.Drugs = new HashSet<Drug>();
}
public int ID { get; set; }
public string Name { get; set; }
public string NName { get; set; }
public virtual ICollection<Drug> Drugs { get; set; }
}
}
For connection I added connection string generated in my C# class library project's App.config to Web.config so it's working fine. Now only issue is where to write data annotations for validating user input.
Thanks in advance....
Thanks all for your valuable replies.
Finally I found solution for this problem. Instead of creating partial classes and add data annotations there, I created ViewModels for my views and added my data annotations there. With ViewModel I am able to validate my user's input.
Related
I have a project where I have to make an ASP.NET Core MVC Web Application in which I should include user sign up, login, and an SQL database with basic CRUD operations and corresponding views. For login and signup I decided to use Asp.Net Core Identity following this tutorial: https://youtu.be/CzRM-hOe35o. Everything works and looks fine for signup and login but I can't figure out how to use my database with the database generated by Identity.
My idea for a project database was to have a table for a User and Article (there are more tables but I'm going to keep it simple to explain my problem) with one to many relation. Now that I have a generated database for all things about Users(from Identity tutorial) how can I include this Article table in the databse and make a one to many relation between AspNetUsers and Article?
Or can I use two databases in my project, one with Users and the other one with other project tables? But then how to make relations between tables from different databases, and is it even possible?
First of all, you should know that you can use two databases but never on this case.
To do what you want, follow those steps:
Step 1 - Create a class called "User" in project folder called "Data". Class will be like this:
public class User : IdentityUser
{
}
Step 2- Create another class called "Article" in the same folder called "Data".
public class Article
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public virtual User User { get; set; }
}
Step 3 - Go to "User" class that you created in the step one and edit it to look like this
public class User : IdentityUser
{
public virtual ICollection<Article> Articles { get; set; }
}
Step 4 - In the same folder where you added those two classes you have another class called "ApplicationDbContext". Open it and register User and Article classes.
public class ApplicationDbContext : IdentityDbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Article> Articles { get; set; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
Step 5 - delete in your local database the existing db generated from your project before.
After that "Add-migration" and "Update-database"
For more information about how Entity Framework Core works see the link : https://www.learnentityframeworkcore.com/conventions/one-to-many-relationship#:~:text=The%20easiest%20way%20to%20configure,public%20class%20Author
I am currently trying to develop a SCIM endpoint to be called from AAD. I pretty much understand the setup of SCIM and the idea behind it (I think). The problem is that I can't wrap my head around how to practically work with the Schemas. Should I make a model in C# that reflects the Schema that we end up using or should I try to do some clever logic that "looks up" the schema in the endpoint when a AAD for instance tries to create a user and then parse the JSON based on that or is there another approach that I am totally missing?
I am using a .NET Core Web API and have a Users controller so far as I do not really need anything else for now from AAD.
Any help with how to "use" these schemas in practice will be greatly appreciated!
This sample may be helpful - https://github.com/AzureAD/SCIMReferenceCode/blob/master/Microsoft.SystemForCrossDomainIdentityManagement/Schemas/Core2UserBase.cs
namespace Microsoft.SCIM
{
using System.Collections.Generic;
using System.Runtime.Serialization;
[DataContract]
public abstract class GroupBase : Resource
{
[DataMember(Name = AttributeNames.DisplayName)]
public virtual string DisplayName
{
get;
set;
}
[DataMember(Name = AttributeNames.Members, IsRequired = false, EmitDefaultValue = false)]
public virtual IEnumerable<Member> Members
{
get;
set;
}
}
When configuring your app in AAD you will also be able to go into the app > provisioning > attribute mappings > show advanced options > and then specify which attributes are required
In my VS2017 EF-Core 2.2 solution, I have 3 projects:
Backend: WebServer - storing data in SQLServer, delivering data with NewtonSoft.Json
DataModels - classes used to create tables in SQLServer (Backend) and SQLite (Frontend)
Frontend: Xamarin.Forms app - using SQLite, getting data with NewtonSoft.Json
The Backend contains a project reference to the DataModels project.
Since my local SQLite database stores just a subset of the content defined in the DataModels classes, I did not add a project reference to the DataModels project, but created a Windows 10 symbolic link in my Frontend project to the DataModels directory, which allows me to modify the DataModel classes like
namespace DataModels
{
[Table("Info")] // Used for front- and backend
public abstract class BaseInfo
{
public Guid Id { get; set; }
[Required]
[StringLength(200)]
public string Title { get; set; }
#if FRONTEND // Only available on frontend side
[NotMapped]
public bool IsSelected {get; set;}
#endif
#if !FRONTEND // Only available on backend side
[Required]
[StringLength(25)]
public MediaProcessingStateEnum MediaProcessingState { get; set; }
#endif
}
}
This is quit nice, but now I have the problem,
that the Backend serializes the data with NewtonSoft.Json adding the $type item to it (since there are abstract classes)
but when I want to deserialize the json content on the Frontend side using
var info = JsonConvert.DeserializeObject<Info>(content, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
});
the deserializer can not create an instance of the class, because the (typeinfo) link to the DataModels assembly is missing!
"Error resolving type specified in JSON 'DataModels.Info, DataModels'. Path '$type', line 1, position 41."
Could someone please give me an idea, how to solve the 'missing reference' problem in NewtonSoft.Json deserializer, without giving up the concept described above?
I have a client/server solution using C#, WPF, ASP.NET WebAPI and Entity Framework. Client and server clases share the model among his projects. Now I am trying to create a new client, using Xamarin Forms and sharing the model to, but Entity Framework attributes(MaxLength, Index, NotMapped, etc), are not compatible in a PCL. So this are the things that I've tried:
Import Microsoft.EntityFrameworkCore to the PCL Model
As described here, you should be able to use entity framework with Xamarin forms, so I convert the PCL to NetStandard 1.3, and it works, every EntityFramework attribute is allowed. But now the server project is not compatible with that standard and I cannot add packages like prism and Newtonsoft.Json in the model project.
Mock the attributes for Xamarin forms using the bait and switch trick
I've tried the approach described here, based on creating custom attributes in the model PCL, and redefining them in the class libraries. MyClient.Droid and MyClient.UWP redefine the attributes leaving them empty, and MyServer will redefine them with the Entity Framework functionality.
Custom IndexAttribute - Model PCL:
namespace Model.Compatibility
{
public class IndexAttribute : Attribute
{
public IndexAttribute()
{
}
}
}
Custom IndexAttribute - Server side:
[assembly: TypeForwardedToAttribute(typeof(Model.Compatibility.IndexAttribute))]
namespace Model.Compatibility
{
public class MockedIndexAttribute : System.ComponentModel.DataAnnotations.Schema.IndexAttribute
{
public MockedIndexAttribute()
{
}
}
}
I test this aproach calling var attribute = new Model.Compatibility.IndexAttribute();. MockedIndexAttribute constructor is never called.
Create a Shared Project Instead of PCL
This way is a little more messy, but looks like it works. Just creating a new shared project for the model, and using conditional flags like this:
#if !__MOBILE__
[NotMapped, Index]
#endif
public Guid Id { get; set; }
I've not fully deployed this approach at the moment, but if I cannot make none of the first two ways working, I will go with this.
EDIT - Trying to make the "Bait and Switch Attributes" approach work
As #AdamPedley sugested and this thread to, I've redefined IndexAttribute in a new PCL(Xamarin.Compatibility), using the same namespace as the original one:
namespace System.ComponentModel.DataAnnotations.Schema
{
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
public class IndexAttribute : Attribute
{
public IndexAttribute() { }
}
}
Now, my PCL Model includes a reference to Xamarin.Compatibility, so I can use Index attribute in my model properties:
[Index]
public Guid Id { get; set; }
Then, from my Server project, I call the next line of code to check what constructor is called, the custom attribute, or the one defined by EntityFramework:
PropertyInfo prop = typeof(MyClass).GetProperty("Id");
object[] attributes = prop.GetCustomAttributes(true);
The constructor called is the custom one, so it does not work because it have to call to the attribute defined by EntityFramework. Thats is the thing that I don't know, what is the mechanism that make my model's PCL select custom attribute or EF attribute depending on the calling assembly.
I've also added a file in my server project, called TypeForwarding.Net.cs(as sugested here), that contains:
[assembly: TypeForwardedTo(typeof(IndexAttribute))]
But still not working.
I believe the EF fluent API is PCL and NetStandard friendly. Thus you can create POCO objects and let the fluent api do the cross platform mappings instead of using attributes. msdn.microsoft.com/en-us/library/jj591617(v=vs.113).aspx
Note: I did this with a project using EF6 and PCL projects to share across MVC / WPF / Mobile
I am not sure how to formulate precisely my question. I have a requirement when any of my business models have changed ( for example: new property is added ) and the application is deployed, on start up of the application some custom logic to be triggered. For example:
this is my business model:
public class MyEntity
{
public string FirstName { get; set; }
public string LastName { get; set; }
public bool hasMiddleName { get; set; }
}
I am adding a new property MiddleName and deploy the application. When the application is started again it should check if the model is changed and only then to perform some custom logic ( set hasMiddleName to true for example). I am not very experienced with asp mvc and I am not sure if this can be done automatically.
I am using ASP MVC 4 with .Net 4.0 and EntityFramework 4.0(I am not using ef migrations). Also, I am using sql project to manipulate the database. As I mentioned, I am not very experienced, so any ideas and explanations will be greatly appreciated. Thanks.