Hi @ismcagdas, thanks for giving over your time. I'm still not sure how to create the code in my Core project and call it from my Hub when the Core project is not available from the Web.Core project (and vice-versa). So I will try and explain with some code. The use case is that each tenant has a set of default Word documents held in Azure blob storage. When a new entity (in my case, a resident in a care home) is added to the system the user selects a set of default documents for the resident. The list of documents is passed back to the server layer (NcDocumentAppService):
[AbpAuthorize]
public async Task<string> CreateDefaultDocuments(LoadDefaultDocumentsInput input)
{
var tenancyName = await GetTenancyNameFromTenantId();
var targetContainer = await _blobMethods.SetUpContainer(tenancyName);
_blobMethods.cloudBlobContainer = targetContainer;
var ncEntity = ObjectMapper.Map<NcEntityDto>(await _ncEntityRepository.FirstOrDefaultAsync(input.NcEntityId));
var sourceFolderName = "documentTemplates/ncEntities";
foreach (var documentTemplateId in input.NcDocumentTemplateIds)
{
var documentTemplate = ObjectMapper.Map<NcDocumentTemplateDto>(await _ncDocumentTemplateRepository.FirstOrDefaultAsync(documentTemplateId));
var SubFolder = documentTemplate.Uri;
var defaultDocumentTemplate = await DownloadDefaultDocument(sourceFolderName, documentTemplate.DisplayName);
var mergedDocument = MergeDocument(defaultDocumentTemplate, ncEntity, tenancyName);
var documentDefault = await _ncDocumentDefaultRepository.FirstOrDefaultAsync(m => m.Id == documentTemplate.NcDocumentDefaultId);
var targetFolderName = await GetFolderBreadcrumb(documentDefault.NcDocumentFolderId);
var metaData = LoadMetaData(GetContentType(documentTemplate.DisplayName), documentTemplate, targetFolderName, ncEntity.Id.ToString());
var blob = await LoadDocument(mergedDocument, metaData, documentTemplate.DisplayName, GetContentType(documentTemplate.DisplayName));
var newDocument = await NewCreateOrEditNcDocumentInput(documentTemplate.DisplayName, documentTemplate, ncEntity, blob.Uri.ToString());
await CreateOrEdit(newDocument);
// I WANT TO CALL NcDocumentHub.SendDocumentMergedMessage() HERE AND UPDATE THE UI TO SHOW THE DOCUMENT HAS BEEN LOADED
}
return "";
}
The service method gets the default document template from the database, downloads from blob storage, carries out a merge using known entity values and then uploads the merged document to blob storage and then persists a control record in the database. The process can take up to 10 seconds per document and there are 20-30 documents to prepare. Therefore I would like to use SignalR to update the UI with a messagefor each document which has been downloaded, merged, uploaded and persisted. Here is a simple Hub class to go along with it.
using Abp.Dependency;
using Abp.Runtime.Session;
using Castle.Core.Logging;
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;
namespace Nuagecare.Web.App.SignalR.NcDocument
{
public class NcDocumentHub : Hub, ITransientDependency
{
public IAbpSession AbpSession { get; set; }
public ILogger Logger { get; set; }
public NcDocumentHub()
{
AbpSession = NullAbpSession.Instance;
Logger = NullLogger.Instance;
}
public async Task SendDocumentMergedMessage(string documentName)
{
await Clients.All.SendAsync("getDocumentMergedMessage", string.Format("{0} merged and loaded.", documentName));
}
}
}
How do I hook this together? Sorry to be such a pain but I've been going round in circles for a couple of days.
HI @ismcagdas, sorry but I'm not sure exactly what you mean here. The code is a new hub and I want to call a method in the hub from my service (ProjectName.Application) project. What code, exactly, do I move to the ProjectName.Core project? The hub? If so which nuget packages should be added to ProjectName.Core to support abp's implementation of SignalR? Sorry, but it's not exactly clear from the documentation. I tried to follow your code for notifications but this involves abp dll's and, in the end, it was unfathomable for me.
Done. User lockout
This is something I have also asked for. The simple ability to have a user in the host with access to certain tenants. It would be a great feature.
@bbakermmc, I just found this in my junk folder, go figure... Thanks for this.
@botcoredev, I would also like to do this and found Microsoft's instructions bewlidering when I looked at them. Does anyone have some base instructions on how to do this?
Thanks, @ismcagdas, always a pleasure!
.NET Core, Angular, 6.8.0, aspnet framework 4.6. I have refactored and continued but would still like to know best practise.
@maliming, That's great, I understand relationships but they key here is "Open EDM in XML" and "put into the NcDocumentDocumentTag table in the <AssociationSetMapping/> section.". How, exactly, do I do that with .Net Zero. This isn't a show stopper, I will refactor and place an Id column in my link table and use .ThenInclude() to get around the problem. But I was wondering....
Hi @maliming, Thanks for getting back.
[Table("NcDocument")]
public class NcDocument : FullAuditedEntity<int>, IMustHaveTenant, IExtendableObject
{
public int TenantId { get; set; }
public int NcDocumentTypeId { get; set; }
public int? NcDocumentTemplateId { get; set; }
public int NcDocumentCategoryId { get; set; }
public string DisplayName { get; set; }
public string ReportString { get; set; }
public string ExtensionData { get; set; }
public string Uri { get; set; }
public virtual NcDocumentTemplate DocumentTemplate { get; set; }
public virtual NcDocumentCategory DocumentCategory { get; set; }
public virtual NcDocumentType DocumentType { get; set; }
public List<NcDocumentTag> DocumentTags { get; set; }
public List<NcDocumentHistory> DocumentHistory { get; set; }
}
[Table("NcDocumentTag")]
public class NcDocumentTag : IMustHaveTenant
{
public int Id { get; set; }
public int TenantId { get; set; }
public int NcDocumentTagTypeId { get; set; }
public string DisplayName { get; set; }
}