Attach Files to Objects
- 4 minutes to read
This lesson describes how to attach file collections to objects.
In this lesson you will do the following:
- Add the File Attachment Module to the application.
- Implement new entity classes:
Resume
to store a Contact’s resume information andPortfolioFileData
to save file data collection items.
Note
Before you proceed, take a moment to review the previous lessons:
Step-by-Step Instructions
Add the DevExpress.ExpressApp.FileAttachment.Blazor NuGet package to the MySolution.Blazor.Server project and the DevExpress.ExpressApp.FileAttachment.Win NuGet package to the MySolution.Win project. See the following topic for more information on how to install DevExpress NuGet packages: Choose Between Offline and Online DevExpress NuGet Feeds.
In the MySolution.Blazor.Server project, open the Startup.cs file and add the File Attachment module to the application builder. Do the same in the Startup.cs file of the MySolution.Win project:
public class Startup { // ... public void ConfigureServices(IServiceCollection services) { // ... services.AddXaf(Configuration, builder => { builder.UseApplication<MySolutionBlazorApplication>(); builder.Modules // ... .AddFileAttachments(); // ... }); // ... } }
If you add the File Attachment Module when you create an XAF application, the Solution Wizard generates the code that adds the File Attachment Module automatically.
In the MySolution.Module\Business Objects folder, create the
Resume
class. Replace the generated class declaration with the following code:using DevExpress.ExpressApp.DC; using DevExpress.Persistent.Base; using DevExpress.Persistent.BaseImpl.EF; using System.Collections.ObjectModel; namespace MySolution.Module.BusinessObjects { [DefaultClassOptions] [ImageName("BO_Resume")] public class Resume : BaseObject { [Aggregated] public virtual IList<PortfolioFileData> Portfolio { get; set; } = new ObservableCollection<PortfolioFileData>(); public virtual Employee Employee { get; set; } [Aggregated] public virtual FileData File { get; set; } } }
Add the
Resume
property to theEmployee
class:using System.ComponentModel.DataAnnotations.Schema; namespace MySolution.Module.BusinessObjects { [DefaultClassOptions] [ObjectCaptionFormat("{0:FullName}")] [DefaultProperty(nameof(FullName))] public class Employee : BaseObject { // ... public virtual IList<Resume> Resumes { get; set; } = new ObservableCollection<Resume>(); } // ... }
Create the
PortfolioFileData
class. Replace the generated class declaration with the following code:using DevExpress.ExpressApp.Model; using DevExpress.Persistent.Base; using DevExpress.Persistent.BaseImpl.EF; using DevExpress.Persistent.Validation; namespace MySolution.Module.BusinessObjects { [DefaultClassOptions] [ImageName("BO_FileAttachment")] public class PortfolioFileData : BaseObject { [RuleRequiredField("PortfolioFileDataRule", "Save", "File should be assigned")] public virtual FileData File { get; set; } public virtual Resume Resume { get; set; } public virtual DocumentType DocumentType { get; set; } public override void OnCreated() { DocumentType = DocumentType.Unknown; } } public enum DocumentType { SourceCode = 1, Tests = 2, Documentation = 3, Diagrams = 4, Screenshots = 5, Unknown = 6 } }
Add the Required attribute to the
Resume
property in thePortfolioFileData
class.// ... namespace MySolution.Module.BusinessObjects; [DefaultClassOptions] [ImageName("BO_FileAttachment")] public class PortfolioFileData : BaseObject { //... [Required] public virtual Resume Resume { get; set; } //... }
The
Resume
andPortfolioFileData
entities are connected with a One-to-Many relationship. For more information on how to create such relationships between entities, refer to the following lesson: Configure a One-to-Many Relationship.In the EF Core-based application, a deletion of a master object does not delete the related objects. In this lesson, we use the Required attribute to configure the associations between classes. This way you can delete the referenced objects with the master object and avoid integrity violation.
Alternatively, you can use the Fluent API and specify the OnDelete method for the
Portfolio
-Resume
relationship as described in the following topic: The Fluent API OnDelete Method.Open the MySolution.Module.BusinessObjects\MySolutionDbContext.cs file and add the properties of
Resume
andPortfolioFileData
types toDbContext
:public class MySolutionEFCoreDbContext : DbContext { //... public DbSet<Resume> Resumes { get; set; } public DbSet<PortfolioFileData> FileAttachments { get; set; } }
Add a migration and update the database. See the following section for details: Use a DBMS: Setup Migrations.
Run the application. Open the Resume List View and create a new Resume object. Fill the Employee field and add a new Portfolio File Data object. In the Portfolio File Data window, select the file that you wish to attach.
- ASP.NET Core Blazor
- Windows Forms
Users can click the file link to download the resume file.
To get a file stored within a PortfolioFileData
object in code, use the SaveToStream(Stream) method of its File
property.