(using the Microsoft.AspNet.Identity)
The IdentityMessage message within the EmailService has 3 properties
public virtual string Body { get; set; }
public virtual string Destination { get; set; }
public virtual string Subject { get; set; }
When you only have 1 "from" adress it is enough, but if you want more then one "from" address, it is a problem and I need the extra property.
public string From { get; set; }
So I extended the class IdentityMessage (like I dit with Users and roles)
public class ExtendedMessage : IdentityMessage
{
public string From { get; set; }
}
So I changed the default implementation
public class EmailService : IIdentityMessageService
{
public async Task SendAsync(IdentityMessage message)
{
await configSMTPasync(message);
}
// send email via smtp service
private async Task configSMTPasync(IdentityMessage message)
{
// SEND MAIL
}
}
With
public class EmailService : IIdentityMessageService
{
public async Task SendAsync(ExtendedMessage message)
{
await configSMTPasync(message);
}
// send email via smtp service
private async Task configSMTPasync(ExtendedMessage message)
{
// SEND MAIL
}
}
But IIdentityMessageService is still refering to the original IdentityMessage (it is not working as espected)
What is the best way to get this working (using Microsoft.AspNet.Identity; framework)?
Thanks in advance.
You cannot use inheritance because once entity is loaded from the data source EF will not know about inheritance and because of that it will instantiate base type without your properties instead of derived type with your properties. Any inheritance must be mapped in EDMX if EF have to work with it.
Using partial class will solve your problem but:
All parts of partial class must be defined in the same assembly
Properties from your partial part are not persisted to the database
Properties from your partial part cannot be used in linq-to-entities queries
Related
I want to make universal JSON generator for any ViewModel received from frontend. I found here that I can get type from string, but I do not know how to implement this in my case.
My idea was to send from Angular array with 2 values, first would be string that say what type is my ViewModel, and second value would be ViewModel, which I need to convert to JSON. (I need this JSONon backend for converting to other file formats, and I have some special requirements, like change of name property, etc.)
I am using MediatR, and here are my classes:
GenerateJSONQuery is input object, the one I will get from frontend.
public class GenerateJSONQuery<T> : IRequest<string>
{
public string TypeOfList { get; set; }
public List<T> Data { get; set; }
}
GenerateJSONQueryHandler is MediatR handler that will do reflection to ViewModel and generate JSON.
public class GenerateJSONQueryHandler<T> : IRequestHandler<GenerateJSONQuery<T>, string>
{
private readonly IddeeaODPDbContext _context;
private readonly IMapper _mapper;
public GenerateJSONQueryHandler(IddeeaODPDbContext context, IMapper mapper)
{
_context = context;
_mapper = mapper;
}
public async Task<string> Handle(GenerateJSONQuery<T> request, CancellationToken cancellationToken)
{
// logic for generating files, in this part I need to somehow convert
// `request.Data` to specific List<T> where
// T can be e.g. `NewbornByBirthDateViewModel`,
//`IssuedDocumentsViewModel`, `RegisteredVehiclesViewModel`, etc. etc.
}
Controller that connect IRequest and IRequestHandler is:
public class GenerateFilesController : ApiBaseController
{
public GenerateFilesController(IOptions<AppSettings> appSettings) : base(appSettings)
{
}
[HttpPost]
[SwaggerOperation(Tags = new[] { "Administration/Document" })]
public async Task<string> List<T>([FromBody] GenerateJSONQuery<T> data, [FromHeader] string Authorization)
{
return await Mediator.Send(data);
}
}
and NewbornByBirthDateViewModel is example VieWModel that I need to serialize into JSON.
public class ClientNewbornByBirthDateViewModel
{
[TranslatedFieldName("Identifier", LanguageEnum.EN)]
public int Id { get; set; }
public string Institution { get; set; }
[TranslatedFieldName("Men", LanguageEnum.EN)]
public int MaleTotal { get; set; }
[TranslatedFieldName("Women", LanguageEnum.EN)]
public int FemaleTotal { get; set; }
public int Year { get; set; }
public int Month { get; set; }
}
I am pretty sure that my thinking way is bad, and that I need to do some kind of reflection, but I do not know how. I can not send only type of ViewModel from frontend, and then select all from db with context.Set<T>() because there can be filters, and those filters depends on which ViewModel is selected, so I must pass object with data from frontend to JSONGenerate logic and then reflect it to specific ViewModel on backend.
Your application must first understand classes and their types before attempting to use reflection by passing the data type name as a parameter.
For that get all the data types using reflection on which you want to
reflect your data on then filter out by using
TypeOfList.
Use this link to get all classes details within a namespace.
How can I get all classes within a namespace?
Hi I'm looking to create a simple webhook receiver and dump the data into a table.
This is for receiving SMS using Zipwhip. Zipwhip will send a post with JSON.
Need to receive the JSON and process.
What is a simple way to accomplish this.
Thanks in advance.
In ServiceStack your callback would just need to match the shape of your Response DTO, e.g:
[Route("/path/to/callback")]
public class CorpNotes
{
public int Departments { get; set; }
public string Note { get; set; }
public DateTime WeekEnding { get; set; }
}
// Example of OrmLite POCO Data Model
public class MyTable {}
public class MyServices : Service
{
public object Any(CorpNotes request)
{
//...
Db.Insert(request.ConvertTo<MyTable>());
}
}
Example uses Auto Mapping Utils to populate your OrmLite POCO datamodel, you may want to do additional processing before saving the data model.
If the callback can send arbitrary JSON Responses in the payload you can use an object property to accept arbitrary JSON however we'd recommend using Typed DTOs wherever possible.
This can be what the receiving method in your controller can look like on the receiving side. Make sure that your receiving and sending json object match.
[HttpPost]
[Route("Edit")]
public JsonResult Edit([FromBody] CorpNotes newMessage)
{return Json(TotalWeekNoteSearch);}
public class CorpNotes
{
public int Departments { get; set; }
public string Note { get; set; }
public DateTime WeekEnding { get; set; }
}
I am actually working on a .net project receiving Json from a Angular front end, so this should be the same concept. Also make sure that what you are receiving is truly a workable object such as.
{Departments: 4, Note: "This is notes 2020Q1W13", WeekEnding: "2020-01-25T00:00:00"}
Also try looking into this example which would be helpful in regards to webhooks.
public class MyWebHookHandler : WebHookHandler
{
public MyWebHookHandler()
{
this.Receiver = "custom";
}
public override Task ExecuteAsync(string generator, WebHookHandlerContext context)
{
CustomNotifications notifications = context.GetDataOrDefault<CustomNotifications>();
foreach (var notification in notifications.Notifications)
{
...
}
return Task.FromResult(true);
}
}
The type of the data is typically JSON or HTML form data, but it is possible to cast to a more specific type if desired.
I have configured this two entities:
Host.cs
public class Host : FullAuditedEntity<int>
{
[Required]
public string Name { get; set; }
public List<HostLine> HostLines { get; set; }
}
HostLine.cs
public class HostLine: FullAuditedEntity<int>
{
[Required]
public string Name { get; set; }
public Host Host { get; set; }
}
Manually, I inserted in the DB one tuple for Host and HostLine, linking them accordingly.
select Id, Name from [MyDB].dbo.Hosts;
Id | Name
-----------
1 | Host1
select Name, HostId from [MyDB].dbo.HostLines;
HostId | Name
------------------
1 | HostLine1
The HostLine's FK to the Host table is configured as you can see in the screenshot below.
Then, I implemented a simple Service which extends AsyncCrudAppService to provide CRUD operation on both the Host and HostLine entities.
public class HostsAppService : AsyncCrudAppService<Host, HostDto, int, PagedResultRequestDto, CreateHostDto, HostDto>, IHostsAppService
{
public HostsAppService(IRepository<Host> repository)
: base(repository)
{
}
protected override HostDto MapToEntityDto(Host entity)
{
return base.MapToEntityDto(entity);
}
}
I added the override to the method MapToEntityDto in order to see the data read from the DB (it will be removed).
When I call the Get REST method of the service via the Angular client I can reach the MapToEntityDto() method, but the Host entity does not have a value for the HostLines List field.
So it seems that the Host repository is not reading the linked data from the HostLine table.
Am I lacking some kind of configuration to let the Host repository read also the HostLine data?
Thank you
You need to include the HostLines manually with the below code.
public class TaskAppService : AsyncCrudAppService<Host, HostDto, int, PagedResultRequestDto, CreateHostDto, HostDto>, IHostsAppService
{
//...
protected override IQueryable<Task> CreateFilteredQuery(GetAllTasksInput input)
{
return base.CreateFilteredQuery(input).Include(x=>x.HostLines);
}
//...
}
Further information see https://aspnetboilerplate.com/Pages/Documents/Application-Services#crud-permissions
I need plan for build Notifications/Alerts system.
I have object named "Campaign" and it have "Status". Status can be Accepted, Rejected, Supplement, Work and others.
I want send Notifications/Alerts when the Status change.
E.q. e-mail notification and alert in my portal.
I don't want make it all in one controller where I operate on Campaign. So I was thinking about Delegates and Events. But in last I don't know enought to do it.
What I thinking about:
Domain model:
class Campaign {
CampaignStatus Status { get; set;}
}
abstract class Notification {
// properties
}
class EmailNotification {
// properties specific for email
}
class Alert {
// properties specific for alerts
}
class CampaignAlert {
// properties specific for campaign alerts
}
Services:
INotificationsService {
Send();
}
IAlertsService : INotificationsService {
Get(); // I need showing list of alerts too
GetAll();
Update(); // for updating info if alert was viewed.
Save(); // I need saving alerts in db.
}
And how I can do it with events? So much automatic as can. Ofcourse I can manualy call the AlertsService and make alert. But this is bad ;)
I was thinking about adding delegate and event to Campaign.
class Campaign {
public delegate void CampaignStatusChange(object sender, EventArgs e);
public event CampaignStatusChange OnCampaignStatusChange;
}
And connect event with:
class CampaignStatusChangeHandler {
public CampaignStatusChangeHandler(IRepository<bla bla> repository, INotificationsService notificationService) {
// these will be inject via ctor
}
//
}
I want made it as much as I can with SOLID, KISS, and DRY. Ofcourse with TDD and I using IoC to inject objects ;)
Summary I need notification service that I can indepentend send emails and alerts. I need display alerts on frontend.
My alert domain model like that:
public abstract class Notification
{
public string Title { get; set; }
public string Content { get; set; }
public DateTime Created { get; set; }
public NotificationType Type { get; set; }
}
public enum NotificationType
{
Email,
Alert
}
public class EmailNotification : Notification
{
public string From { get; set; }
public ICollection<string> To { get; set; }
public ICollection<string> Bcc { get; set; }
}
public class Alert : Notification
{
public object LinkedObject { get; set; }
public bool WasSeen { get; set; }
}
public class CampaignAlert : Alert
{
public CampaignAlertType CampaignAlertType { get; set; }
}
public enum CampaignAlertType
{
Accepted,
Rejected,
Active,
Finished
}
When I want to send Alert to user I want send email sometimes and alert.
Sometimes I want send only email and only alert.
I wouldn't use delegates and events here. Calling a method is much more transparent and you wouldn't have any benefits of using delegates and events.
My structure would look like that:
interface ICampaignService
{
// It's business logic
// 1. Updates campaign
// 2. Creates notification using builder
// 3. Uses notification sender to send notification
// (4. creates alert object for notification)
void UpdateCampaignStatus(int campaignId, Status status);
}
// Builds different notifications based on different
// campaign statuses. For instance assign different
// email templates and use different text.
interface INotificationBuilder<TNotification> where TNotification : Notification
{
TNotification Build();
}
interface INotificationSender
{
Send(Notification notification);
}
interface IAlertsRepository
{
Get();
GetAll();
Update();
Create();
}
Also possible (if there are different types of notifications)
// If you want to send different types of notifications like
// Email, Push, SMS etc. Each notification type requires different
// logic for sending notification. Strategy pattern is perfect here.
interface INotificationStrategy : INotificationSender
{
Send(Notification notification);
}
It's all depends on your application extensibility requirements. SOLID is very important, but make sure to avoid over-engineering (you mentioned KISS :)).
I'm working with ASP.NET MVC application which is based on Identity sample available via NuGet. Because of this I already have some classes to work with the database e.g. ApplicationDbContext.
Say, I decided to let users leave requests for the administrator. I've added the Request class to the models:
public class Request
{
public int Id { get; set; }
public string Message { get; set; }
public ApplicationUser User { get; set; }
}
Since the sample uses different managers to work with users, roles, etc, I've decided to create another one called ApplicationRequestManager inside the Identity.config file (though I'm not sure it's a good practice).
public class ApplicationRequestManager : IRequestManager
{
private ApplicationDbContext db = new ApplicationDbContext();
public void Add(Request request)
{
db.Requests.Add(request);
db.SaveChanges();
}
...
}
This class uses the ApplicationDbContext to work with the database and has some methods to create a request, find it and so on.
I've created a method responsible for sending request inside the Manage controller:
public ActionResult SendRequest(IndexViewModel model)
{
Request request = new Request { Message = model.Message, User = UserManager.FindById(User.Identity.GetUserId()) };
requestManager.Add(request);
return View();
}
When this method is invoked, I get the following exception:
An entity object cannot be referenced by multiple instances of IEntityChangeTracker
If I understood correctly, the reason of exception is that I use one ApplicationDbContext to get User - via UserManager and I use another ApplicationDbContext to add the request - via RequestManager, so my request is attached to two contexts. As far as I know, such mistake can be avoided by passing the same context to both UserManager and RequestManager. However, UserManager gets its context via the OwinContext together with other managers:
// Configure the db context, user manager and role manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
How can I make my own manager follow that pattern as well? I've tried to use the CreatePerOwinContext method like
app.CreatePerOwinContext<ApplicationRequestManager>(ApplicationRequestManager.Create);
And I've also tried to implement the Create method following the RoleManager example
public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context)
{
return new ApplicationRoleManager(new RoleStore<ApplicationRole>(context.Get<ApplicationDbContext>()));
}
But I don't have any Store for my requests so I don't know what I should do with the 'new RoleStore' part. How could I solve that problem?
Updated:
I've tried Gert's solution and it worked:
public class Request
{
public int Id { get; set; }
public string Message { get; set; }
[ForeignKey("User")]
public int ApplicationUserId { get; set; }
public ApplicationUser User { get; set; }
}
var userId = User.Identity.GetUserId();
Request request = new Request
{
Message = model.Message,
ApplicationUserId = userId
};
I've also tired another way using HttpConext.Current.GetOwinContext().Get method. I've added the following line to my ApplicationRequestMananger:
public ApplicationRequestManager()
{
this.db = HttpContext.Current.GetOwinContext().Get<ApplicationDbContext>();
}
And it worked fine with the original Request class.
The question is, what advantages and disadvantages does each way have? I've read about foreign keys and I understand the general idea quite well; but I don't really understand what problems can 'HttpContext.Current.GetOwinContext().Get()' cause. Should I use it since it's simpler than adding foreign keys?
The trouble with your design is that each manager has its own context. Seeing this example, I think each manager should call...
db = context.Get<ApplicationDbContext>();
...or receive the request-bounded context in their constructor.
Apart from that, you could make this much simpler by exposing the foreign field to ApplicationUser (ApplicationUserId?) as a primitive property in Request:
public class Request
{
public int Id { get; set; }
public string Message { get; set; }
[ForeignKey("User")]
public int ApplicationUserId { get; set; }
public ApplicationUser User { get; set; }
}
And then create Request like so:
var userId = User.Identity.GetUserId();
Request request = new Request
{
Message = model.Message,
ApplicationUserId = userId
};
This is refered to as foreign key associations, as opposed to independent associations that only have a reference navigation property.