Base solution for your next web application
Open Closed

File upload and storage E.g., PDFs, .JPGs etc. #10519


User avatar
0
KarakTheWise created

Version 9.2.0 Angular .NET Core

Greetings,

My solution requires that the client store multiple PDF contract documents for their clients. I'm not sure what the best solution is for this issue. I know the standard Angular upload component stores the files locally. I don't how this translates to a hosted solution in a couple a ways:

1.) How does that work for many tenants? 2.) How would I retrieve a historical listing of documents such a contracts sent to a customer by a particular tenant?

I can see storing some informatio in SQL such as date created etc. but as to where the actual file sits and how it's retieved for a particular tenant is something I'm unsure of. Please advise :)

Thanks!


9 Answer(s)
  • User Avatar
    0
    musa.demir created

    Hi @KarakTheWise

    AspNet Zero uses IBinaryObjectManager to store file.See: https://github.com/aspnetzero/aspnet-zero-core/blob/dev/aspnet-core/src/MyCompanyName.AbpZeroTemplate.Core/Storage/IBinaryObjectManager.cs. It's default implementation uses db to store it but you can override it with any implementation you want. https://github.com/aspnetzero/aspnet-zero-core/blob/dev/aspnet-core/src/MyCompanyName.AbpZeroTemplate.Core/Storage/DbBinaryObjectManager.cs

  • User Avatar
    0
    KarakTheWise created

    Excellent! I'll take a look at that today. I think that's exactly what I'm looking for. Thank you :)

  • User Avatar
    0
    KarakTheWise created

    I've been working through the binary object upload process and have been using the Angular component change-profile-picture-modal as my starting point. There are a couple points where I'm not following the code:

    1.) initFileUploader() calls the upload process but appears to be called on show() when the modal is opened. I'm a bit lost on how this works due to the fact I haven't yet selected and file at this point. I see that it works but not how.

    2.) The save() function calls this.uploaded.uploadAll() if useGravatarProfilePicture is false. I am unable to find any documentation as to how uploadAll() actually does.

    Any advise and direction would be most helpful. Thank you once again!

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    1. initFileUploader actaully doesn't initiate the upload progress. It just configures the uploader with necessary information, see https://github.com/aspnetzero/aspnet-zero-core/blob/dev/angular/src/app/shared/layout/profile/change-profile-picture-modal.component.ts#L77
    2. You can access the documentation for the uploader we are using here https://valor-software.com/ng2-file-upload/
  • User Avatar
    0
    KarakTheWise created

    Ok, I think I found some of my issues. Do I need to make a controller like the ProfileControllerBase to use like you did?:

    this.uploader = new FileUploader({ url: AppConsts.remoteServiceBaseUrl + '/Profile/UploadProfilePicture' });

    It took me a bit to find since I was presuming it was an api service.

    I tried puttung /api/services/app/GuestEvent/UploadGuestContract and I'm getting a 415 error. If I just use this.uploader = new FileUploader({ url: AppConsts.remoteServiceBaseUrl + '/GuestEvent/UploadGuestContract' }); I get a 404.

    I notice the updateProfilePicture() funciton is a call to the api service Profile. this._profileService.updateProfilePicture(input) I guess I'm not sure how the two play nicely together :)

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    You don't need a ControllerBase but you must create a Controller in the Host project similar to https://github.com/aspnetzero/aspnet-zero-core/blob/dev/aspnet-core/src/MyCompanyName.AbpZeroTemplate.Web.Host/Controllers/ProfileController.cs and it must contain the UploadGuestContract action. In that case, you can use it like below;

    this.uploader = new FileUploader({ url: AppConsts.remoteServiceBaseUrl + '/GuestEvent/UploadGuestContract' });
    

    Could you tyr like this ? If it doesn't work for you, please share your GuestEventController code.

    Thanks,

  • User Avatar
    0
    KarakTheWise created

    UPDATE: I was able to get everything into the byte array and into the database. My next process is now getting the byte array out of the database and back into a loadable PDF document.

    Thank you for the help! Yes, I was able to get that far yesterday. I ended up making a ControllerBase because I wasn't sure if that was needed. Then I made a GuestEventController that inherits from the base.:

    public class GuestEventController : GuestEventControllerBase { public GuestEventController( ITempFileCacheManager tempFileCacheManager, IBinaryFileUploadManager binaryFileUploadManager, IGuestEventAppService guestEventAppService) : base(tempFileCacheManager, binaryFileUploadManager, guestEventAppService) { } }

    In my Angular .ts file I was able to get this to work and it is being sent to the controller. this.uploader = new FileUploader({ url: AppConsts.remoteServiceBaseUrl + '/GuestEvent/UploadGuestDocument' }); `` May main issue now is that I'm trying to get a PDF, not an image inserted as a binary object into the database. All the code I've been able to find so far online is wanting a literal file location because all the examples are using this to get the file: System.IO.FileStream fileStream = new System.IO.FileStream(input.FileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);

    The issue is that the file is not found on \...\ASPNET-Zero\Resolution\aspnet-core\src\Resolution.Web.Host\GuestContractTest_05.pdf' . I am needing to deal with it virtually as a passed object like you do with the image. I don't know if I'm makging sense?

    This is what I have right now but again, it is expecing a physical path:

    var contractFile = _tempFileCacheManager.GetFile(input.FileToken); System.IO.FileStream fileStream = new System.IO.FileStream(input.FileName, System.IO.FileMode.Open, System.IO.FileAccess.Read); System.IO.BinaryReader binaryReader = new System.IO.BinaryReader(fileStream); long byteLength = new System.IO.FileInfo(input.FileToken).Length; contractFile = binaryReader.ReadBytes((Int32)byteLength); fileStream.Close(); fileStream.Dispose(); binaryReader.Close(); return new UploadGuestDocumentOutputDto { FileToken = input.FileToken, Name = input.FileName, FileType = input.FileType, Bytes = contractFile }; ``That's where I'm at right now. If I just knew the correct 'thread to pull' as it were, I think I'd be on my way. Thanks again for the help and any advice is most welcome!

  • User Avatar
    0
    musa.demir created

    Hi @KarakTheWise

    Can you please share all related part of your code with us so that we can try to reproduce it?

  • User Avatar
    0
    KarakTheWise created

    Hi,

    Just wanted say thank for all the help. I think I'm far enough along that I can close the ticket. Right now I have a find a solution for displaying the a PDF from a byte array. There's quite a bit on Stack and other places where I'm sure I can find a solution in the next few days. Thanks again for the guidance to get to this point!