Using Generic Type DTO In ServiceStack Request - rest

I was wondering if it's possible to use a Templated DTO requested of the type public class
RequestDTO<T, U> where T : class where U : class
{
public T ContextRequest { get; set; }
public U Request { get; set; }
}
And pass it to my service's request...
I've tried a simple example of type
public class MyContext
{
//removed some fields
public int IdUser {get;set;}
}
public class MyType1Request
{
public int IdRequest {get;set;}
}
public class MyType2Request
{
public DateTime SomeReallyImportantDate { get; set; }
}
public class UtenteService : Service
{
public UtenteService()
{
}
public string Any(RequestDTO<MyContext,MyType1Request> request)
{
return string.Format("User:{0} - IDRequest: {1}", request.ContextRequest.IdUser, request.Request.IDRequest);
}
public object Any(RequestDTO<MyContext, MyType2Request> request)
{
return string.Format("Utente:{0} - Data : {1}", request.ContextRequest.IDUtente, request.Request.DataLavorativa);
}
But I got this as far I try to access to the service
Sequence contains more than one matching element
Another solution is to implement in each my DTO Request object a IContext (and maybe IContextExt IContextSpecificManner) into the request object...but I would prefer to use the first approach
Thanks

AFAIK - This should work. The only thing that I am missing here is, you need to register route in apphost like:
Routes.Add>("/Utente/{IdUser}/{IdRequest}")

Related

Model method that depends on DbContext

Context
I have a model for representing comments that looks like the following:
public class Comment
{
public int Id { get; set; }
public int CommentId { get; set; } // Id of parent comment
...
}
In my DetailsModel class which is a subclass of PageModel, I have the following method for finding replies to a given comment:
public IList<Comment> Replies(int comment_id) =>
_context.Comment.Where(comment => comment.CommentId == comment_id).ToListAsync().Result;
I use it from a Razor page as follows:
Model.Replies(reply.Id).Count
This works fine.
More object-oriented approach?
In a more traditional object-oriented design, Replies might be a method on Comment. So finding the replies would look like this:
reply.Replies()
Moving the Replies method into Comment, we get:
public class Comment
{
public int Id { get; set; }
public int CommentId { get; set; } // Id of parent comment
...
public async Task<IList<Comment>> Replies()
{
return await _context.Comment.Where(comment => comment.CommentId == Id).ToListAsync();
}
}
And now you can see the issue; Comment now has a dependency on the DbContext, which seems like a very odd arrangement.
So my question is, is there a way to get Replies to be a method on Comment in a way that's idiomatic for ASP.NET Core / EF Core?
UPDATE - CommentAlt
Here's one approach I've explored.
I have a CommentAlt class.
It is a subclass of Comment (so as to inherit all the fields from Comment).
The constructor accepts a BasePageModel.
My page models inherit from BasePageModel.
BasePageModel gives CommentAlt access to things like
DbContext
UserManager<IdentityUser>
AuthorizationService
Here's CommentAlt:
public class CommentAlt : Comment
{
private BasePageModel Model { get; }
public CommentAlt(Comment comment, BasePageModel model)
{
Id = comment.Id;
CommentId = comment.CommentId;
...
Model = model;
}
public IList<CommentAlt> Replies() =>
Model.Context.Comment
.Where(comment => comment.CommentId == Id).ToList()
.Select(elt => new CommentAlt(elt, Model)).ToList();
...
}
As you can see, now Replies is a method on it. In one of my Razor pages, I have the following expression:
#if (reply.Replies().Count > 0)
and it works fine.
Here's my BasePageModel which is passed to the CommentAlt contructor:
public class BasePageModel : PageModel
{
public ApplicationDbContext Context { get; }
public IAuthorizationService AuthorizationService { get; }
public UserManager<IdentityUser> UserManager { get; }
public BasePageModel(
ApplicationDbContext context,
IAuthorizationService authorizationService,
UserManager<IdentityUser> userManager) : base()
{
Context = context;
UserManager = userManager;
AuthorizationService = authorizationService;
}
}
One thing I feel a little weird about is having the Context, AuthorizationService, and UserManager properties here be public. I changed them to public so that ConmmentAlt would have access to them.
Is the approach taken here with CommentAlt recommended? Is there a better way?

issue with new create dbcontext class object in asp.net core 2.1

I m new in .net core 2.1
I m working with .net core 2.1 with code first approach
issue is when I create a new object dbcontext class then give error see below line
dbcontextstudent db=new dbcontextstudent(); //here give an red line
appsettings.json
},
"ConnectionStrings": {
"sqlserverconn": "Server=DEVISSHAHID; Database=studdbs; User id=xxxx;Password=xxxxx;"
},
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
//connection string
services.AddDbContext<DbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("sqlserverconn")));
student.cs
namespace WebApplication1.Models
{
public class student
{
[Key]
public int studid { get; set; }
public string studname { get; set; }
public string studsalary { get; set; }
public int studage { get; set; }
}
}
dbcontextstudent.cs
namespace WebApplication1.Models
{
public class dbcontextstudent : DbContext
{
public dbcontextstudent(DbContextOptions<dbcontextstudent> options) : base(options)
{
}
public DbSet<student> stud { get; set; }
}
}
HomeController.cs
I m not understood the above intellisense
I write the code as per intellisense but still give an error I know error is clear but not solved
which place doing I m wrong?
You will have to pass your DbContext type to the AddDbContext method in ConfigureServices method like this:
services.AddDbContext<dbcontextstudent>(options => options.UseSqlServer(Configuration.GetConnectionString("sqlserverconn")));
After that, you have registered the dbcontextstudent class in dependency injection.
You shouldn't create the instance of dbcontextstudent on your own like you did:
dbcontextstudent db=new dbcontextstudent();
Instead you can inject it though the constructor of your controller like this:
public HomeController : Controller
{
private readonly dbcontextstudent _db;
public HomeController(dbcontextstudent db)
{
_db = db;
}
... and then you can use the _db variable in your post action
}

Code first Type per hierarchy

I use EF 5 with the code first approach. Now I try to define a "code" table in which I want to have several different codes (like address code, medium code, etc.). In this table I just have the following properties: ID (Guid), Name (String), Description (String) and a discriminator (in this case something like the type of the code: address code, medium code, etc.).
So I defined the following base class:
public abstract class Code : EntityBase
{
public string Name { get; set; }
public string Beschreibung { get; set; }
}
Then I derived two classes from code
public class AddressCode : Code {}
public class MediumCode : Code {}
The class EntityBase is abstract and just defines the Id property, we use it for every POCO class...
The goal is that I can use AddressCode as a property on my address POCO class:
public class Adresse : EntityBase
{
#region Properties
public string Name1 { get; set; }
public virtual AddressCode AddressCode { get; set; }
#endregion
}
The question now is, how can I explain EF how to do that? Anyone can help?
Thanks
Marco
Thanks for your answer!
I tried to do it like you said. Unfortunately I get an error because of my EntityBase class:
public abstract class EntityBase
{
#region Properties
public virtual Guid Id { get; set; }
public virtual bool IsValid
{
get
{
{
return Validate();
}
}
}
[NotMappedAttribute]
public virtual IList<ValidationFailure> ValidationFailures { get; set; }
#endregion
#region Methods
private bool Validate()
{
var validatorFactory = new AttributedValidatorFactory();
IValidator validator = validatorFactory.GetValidator(GetType());
if (validator == null)
{
return true;
}
ValidationResult validationResult = validator.Validate(this);
ValidationFailures = validationResult.Errors;
return validationResult.IsValid;
}
#endregion
}
The error message is:
You cannot use Ignore method on the property 'ValidationFailures' on type 'Entities.AdresseCode' because this type inherits from the type 'Entities.EntityBase' where this property is mapped. To exclude this property from your model, use NotMappedAttribute or Ignore method on the base type.
As you can see I already defined the property ValidationFailures as NotMapped but still I get this error.. Do you have an idea?
Thanks
Marco
Just create a context (derived from DbContext)
public class AddressesDb : DbContext
{
public DbSet<Code> Codes { get; set; }
public DbSet<Adresse> Adressen { get; set; }
}
And (when used in code) EF will create a database with default table and column names. It will create a discriminator column of type text (nvarchar) which will contain the names of the classes that derive from Code.
If you want different names and/or types you should either use data annotations or fluent API to configure these.
Finally I got it work!
In the DBContext be aware to define DbSets for the code derived classes before all the other POCO's and then it works!

Use a base class as the return type in ApiController

Using the ASP.NET WebApi 4 RC, is it possible to have an ApiController's return type be a base class and actually return instances of derived classes? Trying to do this now results in an internal server error (500) when returning xml. Returning json using this method works correctly.
public class Base
{
public int ID { get; set; }
}
public class Derived : Base
{
public string Message { get; set; }
}
public class ValuesController : ApiController
{
public IEnumerable<Base> Get()
{
return new Derived[] {
new Derived(){ Message="test"},
new Derived(){ Message="another"}
};
}
}
It would seem that the XML serialization is what's throwing the error but all I can see is the generic 500 error.
Yes, you need to use the knowntype serialization hint:
[System.Runtime.Serialization.KnownType(typeof(Derived))]
public class Base
{
public int ID { get; set; }
}
You might want to do it programmatically
private static Type[] GetKnownType()
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
var knownTypes = new List<Type>();
foreach (var assembly in assemblies)
{
knownTypes.AddRange(assembly.GetTypes().Where(x => x.BaseType == typeof (BaseResponse)).ToArray());
}
return knownTypes.ToArray();
}
Do remember your child class MUST have a default constructor else you will get runtime serialization error.

Composition and RIA

i have problems with related properties Composition attribut and RIA.I 'm using POCO and silverlight. here is my modele :
[MetadataTypeAttribute(typeof(ModeleEnvoiEaMetaData))]
[Serializable]
public abstract partial class ModeleEnvoiEa
{
[DataMember]
public virtual int IdModeleEnvoiEa {get;set;}
[DataMember]
public virtual string Libelle {get;set;}
[DataMember]
public virtual Nullable<int> IdModeleEnvoiEaFooter {...//FK }
public virtual ModeleEnvoiEaHeaderFooter ModeleEnvoiEaFooter
{
get { return _modeleEnvoiEaFooter; }
set
{
if (!ReferenceEquals(_modeleEnvoiEaFooter, value))
{
var previousValue = _modeleEnvoiEaFooter;
_modeleEnvoiEaFooter = value;
FixupModeleEnvoiEaFooter(previousValue);
}
}
}
private ModeleEnvoiEaHeaderFooter _modeleEnvoiEaFooter;
}
public partial class ModeleEnvoiEaMetaData
{
//...
[Association("ModeleEnvoiEa_ModeleEnvoiEaFooter","IdModeleEnvoiEaFooter","IdModeleEnvoiEaHeaderFooter")]
[Include]
[Composition]
public ModeleEnvoiEaHeaderFooter ModeleEnvoiEaFooter;
}
}
In client side i call Test domaine service method , in the client side the property ModeleEnvoiEaFooter is not null, but in my DomainServices class this property is null. Even with de Composition attribut. How can i send the value of ModeleEnvoiEaFooter property to Domainservices class ?
[Invoke]
public ModeleEnvoiEa Test(ModeleEnvoiEa modele)
{
// modele.IdModeleEnvoiEaFooter == 1 // FK to ModeleEnvoiEaFooter
// modele.ModeleEnvoiEaFooter is null here ! Why ? an how can i send this object
}
Try marking ModeleEnvoiEaFooter as a DataMember.