class won't let me create a new object - asp.net

Hi I'm unable to create a new object that is a subclass I think that's what you call it it saying virtual isn't allowed what must I do to correct this here is my code.
public class PagerBuilder {
private virtual class PagerLink
{
public string Title { get; set;}
public int PageNo { get; set; }
public string Class { get;set;}
}
private readonly List<PagerLink> _pagerLinks = new List<PagerLink>();
private readonly string _urlTemplate;
public PagerBuilder(string urlTemplate)
{
_urlTemplate = urlTemplate;
}
public string PagerClass { get;set;}
public void AddPage(string title, int pageNo)
{
AddPage(title, pageNo, string.Empty);
}
public void AddPage(string title, int pageNo, string itemClass)
{
PagerLink link = new PagerLink();
}
}

First, I would move PagerLink outside of the PagerBuilder class and define it separately (in a new file as well).
Second, you don't need virtual to subclass PagerLink (It's not even valid, in fact). If you want it to be abstract, use the abstract keyword instead, but this code won't compile (at PagerLink link = new PagerLink() until you define a concrete implementation of PagerLink. You don't need to use abstract to inherit from PagerLink, though. Just do this:
public class CustomPagerLink: PagerLink
{
//Subclass implementation
}

You want to remove virtual from your class definition.
private class PagerLink
{
public string Title { get; set;}
public int PageNo { get; set; }
public string Class { get;set;}
}

Related

How to create two foreign keys to the same table with SQLite in Xamari Form

I working in a project with Xamarin Form using C#. I'm trying to create two foreign keys to the same table, using this code:
[Table("Posts")]
public class Post
{
[PrimaryKey]
public long PostID { get; set; }
public string Name { get; set; }
public TypeEntity mode = null;
[ManyToOne(CascadeOperations = CascadeOperation.CascadeInsert)]
public TypeEntity Mode
{
get
{
return mode;
}
set
{
mode = value;
}
}
[ForeignKey(typeof(TypeEntity))]
public long ModeID { get; set; }
public TypeEntity level = null;
[ManyToOne(CascadeOperations = CascadeOperation.CascadeInsert)]
public TypeEntity Level
{
get
{
return level;
}
set
{
level = value;
}
}
[ForeignKey(typeof(TypeEntity))]
public long LevelID { get; set; }
}
[Table("Types")]
public class TypeEntity
{
[PrimaryKey]
public long TypeID { get; set; }
public string Code { get; set; }
public string Name { get; set; }
}
As you can see, the properties Mode and Level are type "TypeEntty", so I need to create the relations.
When I try to insert data, only "Mode" property is inserted ok, "Level" property stay null.
public abstract class BaseStore<T> where T : new()
{
public static SQLiteConnection sql;
public BaseStore()
{
sql = DependencyService.Get<ISQLite>().GetConnection();
Init();
}
public void Init()
{
sql.CreateTable<T>();
}
public void Insert(T entity)
{
sql.InsertWithChildren(entity);
}
}
I switched properties order, I added Level first than Mode, and Level got the value. It means, that SQLIte take only the first property to create the relation.
Does anyone know why this isn't working?
I'm working with SQLite.Net.Core-PCL 3.1.1 and SQLiteNetExtensions 2.1.0.
You have to manually specify which foreign key corresponds to each relation. To do so, pass the ForeignKey parameter in each ManyToOne attribute.
Can't test it right now, but it would probably look something like this:
[ManyToOne(ForeignKey = "ModeID", CascadeOperations = CascadeOperation.CascadeInsert)]
public TypeEntity Mode
(...)
[ManyToOne(ForeignKey = "LevelID", CascadeOperations = CascadeOperation.CascadeInsert)]
public TypeEntity Level

I can not create instace of DBContext

I have model:
public class Department
{
public int DepartmentID { get; set; }
[Required]
[UniqueDepartmentName]
public string Name { get; set; }
public List<Person> Persons { get; set; }
}
And DBcontext:
public class InstituteContext : DbContext
{
public InstituteContext (DbContextOptions<InstituteContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Department>().HasIndex(p => p.Name).IsUnique();
}
public DbSet<Institute.Models.Department> Department { get; set; }
}
As you see property "NAME" i make unique.
For validation i create My validation Attribute:
public class UniqueDepartmentName : ValidationAttribute
{
public override bool IsValid(object value)
{
var db = new InstituteContext();
}
}
But i can not create instance of InstituteContext, because constructor need parameters.
How i can create instance of InstituteContext? Or what should i pass to constructor in parameters?
Try this:
public class UniqueDepartmentName : ValidationAttribute
{
public override bool IsValid(object value)
{
var connectionString = "Your ConnectionString"
var options = new DbContextOptionsBuilder<InstituteContext>()
.UseSqlServer(new SqlConnection(connectionString)).Options;
using (var dbContext = new BloggingContext(options))
{
// Do necessary staffs here with dbContext
}
}
}
Your DbContextOptions method is in the wrong place, your constructor can be empty, and you need to add the method OnConfiguring, which receives the DbContextOptions.
Something like:
public DbSet<Department> Department { get; private set; }
protected override void OnConfiguring(DbContextOptionsBuilder options) {
// In my case I'm passing the connection string in this method below
options.UseSqlServer("Data Source=DATABASEIP;Initial Catalog=DATABASETABLE;" +
"User ID=USER;Password=PASSWORD");
}

AspNetRoles table not showing custom fields

I have recently extended my AspNetRoles table like this:
public class AspNetRoles:IdentityRole
{
public AspNetRoles() : base() { }
public String Label { get; set; }
public String ApplicationId { get; set; }
public AspNetApplications Application { get; set; }
public static readonly String SystemAdministrator = "SystemAdministrator";
}
It works fine when I create a new role. However, when I try to extract it to a list like this:
var data = dbContext.Roles.ToList();
And try to do a search like this:
data = data.Where(u => u.Id.ToString().ToLower().Contains(Input.Search.ToLower())).ToList();
I can't access the ApplicationId column. Am I missing something?
EDIT:
My dbContext
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, AspNetRoles<string>, string>
{
public virtual DbSet<AspNetUsersExtendedDetails> AspNetUsersExtendedDetails { get; set; }
public virtual DbSet<AspNetApplications> AspNetApplications { get; set; }
public virtual DbSet<AspNetEventLogs> AspNetEventLogs { get; set; }
public virtual DbSet<AspNetRoles> AspNetRoles { get; set; }
public ApplicationDbContext() : base("AppStudio")
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
I have updated my dbContext but now it shows this error: 'IdentityDbContext<ApplicationUser, AspNetRoles<string>, string>' does not contain a constructor that takes 2 arguments
You need to tell ASP.Net Identity about the custom role table that you want to use.
Edit: since the default IdentityRole implementation uses a string as the PK, the type can be omitted. Just checking futher on ASP.Net Identity version 2, as soon as you specify a custom IdentityRole class, the class declaration needs to include all types.
That means you need to declare your ApplictionDbContext like this:
public class ApplicationDbContext: IdentityDbContext<ApplicationUser, AspNetRoles, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
{
public ApplicationDbContext() : base("AppStudio")
{
//note: before this change, if you included the
//throwIfV1Schema parameter in the constructor,
//it needs to be removed.
}
//implementation
}
Note that this assumes that the Primary Key of the users table is a string. If this is not the case, substitute with the applicable type (e.g. a Guid).
You have to add AspNetRoles to your IdentityDbContext.
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, AspNetRoles, string>
{
public virtual DbSet<AspNetUsersExtendedDetails> AspNetUsersExtendedDetails { get; set; }
public virtual DbSet<AspNetApplications> AspNetApplications { get; set; }
public virtual DbSet<AspNetEventLogs> AspNetEventLogs { get; set; }
public ApplicationDbContext() : base("AppStudio", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}

Clean way for updating object in a collection of abstract objects

As I'm developping an asp net core + ef core 2.0 with localized objects in my model, I adapted the solution provided in the following link to localize my objects link.
I'm now trying to find a clean way to update my collection of translation when updated object are received in the controller.
For the moment I have a step model class defined this way :
public class Step
{
//Native properties
public Guid ID { get; set; }
public string Name { get; set; }
public int Order { get; set; }
public string ScriptBlock { get; set; }
//Parent Step Navigation property
public Nullable<Guid> ParentStepID { get; set; }
public virtual Step ParentStep { get; set; }
//Collection of sub steps
public virtual ICollection<Step> SubSteps { get; set; }
//MUI Properties
public TranslationCollection<StepTranslation> Translations { get; set; }
public string Description { get; set; }
//{
// get { return Translations[CultureInfo.CurrentCulture].Description; }
// set { Translations[CultureInfo.CurrentCulture].Description = value; }
//}
public Step()
{
//ID = Guid.NewGuid();
Translations = new TranslationCollection<StepTranslation>();
}
}
public class StepTranslation : Translation<StepTranslation>
{
public Guid StepTranslationId { get; set; }
public string Description { get; set; }
public StepTranslation()
{
StepTranslationId = Guid.NewGuid();
}
}
Translation and translationCollection are the same as in the link
public class TranslationCollection<T> : Collection<T> where T : Translation<T>, new()
{
public T this[CultureInfo culture]
{
// indexer
}
public T this[string culture]
{
//indexer
}
public bool HasCulture(string culture)
{
return this.Any(x => x.CultureName == culture);
}
public bool HasCulture(CultureInfo culture)
{
return this.Any(x => x.CultureName == culture.Name);
}
}
public abstract class Translation<T> where T : Translation<T>, new()
{
public Guid Id { get; set; }
public string CultureName { get; set; }
protected Translation()
{
Id = Guid.NewGuid();
}
public bool HasProperty(string name)
{
return this.GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Any(p => p.Name == name);
}
}
My issue in this sample is how to deal correctly with the PUT method and the Description property of my step controller. When it receive a Step object to update (which is done through a native c# client) only the string Description property of Step might have been created/updated/unchanged. So I have to update/create/do Nothing on the Description of the translation in the correct culture.
My first guess is to add in the TranslationCollection class a method in which I could pass the culture, the name of the property to update or not (Description in this case) and the value of the Description.
But as the TranslationCollection is a collection of abstract objects I don't even if this is a good idea and if it's possible.
If someone would have any advice on it (hoping I was clear enough) it would be great !
Finally answered my own question, and it was quite simple.
Just had to use the indexer like :
myobject.Translations[userLang].Name = value;

Problem with MEF

I have the folllowing:
private void ConfigureMEFContainer()
{
_catalog = new DirectoryCatalog(_pluginsPath);
_container = new CompositionContainer(_catalog);
}
private readonly string _pluginsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
private DirectoryCatalog _catalog;
private CompositionContainer _container;
Container is passed to another class:
var batch = new CompositionBatch();
batch.AddPart(this);
container.Compose(batch);
[ImportMany(typeof(IOnAnnotationCreatedPlugin))]
public Lazy<IOnAnnotationCreatedPlugin, IAnnotationPluginMetadata>[] OnCreatedPlugins { get; set; }
[ImportMany(typeof(IOnAnnotationCreatingPlugin))]
public Lazy<IOnAnnotationCreatingPlugin, IAnnotationPluginMetadata>[] OnCreatingPlugins { get; set; }
[ImportMany(typeof(IOnAnnotationUpdatedPlugin))]
public Lazy<IOnAnnotationUpdatedPlugin, IAnnotationPluginMetadata>[] OnUpdatedPlugins { get; set; }
[ImportMany(typeof(IOnAnnotationUpdatingPlugin))]
public Lazy<IOnAnnotationUpdatingPlugin, IAnnotationPluginMetadata>[] OnUpdatingPlugins { get; set; }
All the collections above are empty!
Any help?
I'm can't see what's wrong, but here's a blog post on how to debug this type of thing: http://blogs.msdn.com/b/dsplaisted/archive/2010/07/13/how-to-debug-and-diagnose-mef-failures.aspx
Thanks for your responses. I changed the code to the following and now it works fine. I believe, I had a problem with the custom Export Attribute and the Metadata interface. Here is the complete code in case someone else had the same problem:
public interface IAnnotationServicePluginMetadata
{
string Name { get; }
[DefaultValue(0)]
int Priority { get; }
}
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
public class AnnotationServicePluginMetadataAttribute : ExportAttribute
{
public AnnotationServicePluginMetadataAttribute()
: base(typeof(IAnnotationServicePluginMetadata))
{
}
public string Name { get; set; }
public int Priority { get; set; }
}
Using the above:
[Export(typeof(IOnAnnotationUpdatedPlugin))]
[AnnotationServicePluginMetadata(Name = "OnUpdatedPlugin", Priority = 1)]
public class OnUpdatedPlugin : IOnAnnotationUpdatedPlugin
{ }
Properties as follows:
[ImportMany(typeof(IOnAnnotationUpdatedPlugin))]
public IEnumerable<Lazy<IOnAnnotationUpdatedPlugin, IAnnotationServicePluginMetadata>> OnUpdatedPlugins { get; set; }
Hope that helps.
Regards
Have you tried the alternative:
container.ComposeParts(this);
Also, have you ensured that you've specified the type on export, e.g.
[Export(typeof(IOnAnnotationCreatedPlugin))]
Instead of simply:
[Export]
The latter will export the concrete type with a contract for the concrete type, not the interface.

Resources