From c9752d39e9771ce125b9b762976f61ff9e7793bd Mon Sep 17 00:00:00 2001 From: Daniel Klein Date: Wed, 17 Dec 2025 13:37:35 +0100 Subject: [PATCH 1/3] Refactor file handling in SubmodelController - Updated variable declarations to use `var` for improved readability. - Added logic to delete existing files associated with `fileElement` before uploading a new file to prevent conflicts. - Changed file creation to use `await using` for better asynchronous performance. --- .../SubmodelController.cs | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/basyx-dotnet-components/BaSyx.API.Http.Controllers/AssetAdministrationShell/SubmodelController.cs b/basyx-dotnet-components/BaSyx.API.Http.Controllers/AssetAdministrationShell/SubmodelController.cs index 7578c0c..ccfab5d 100644 --- a/basyx-dotnet-components/BaSyx.API.Http.Controllers/AssetAdministrationShell/SubmodelController.cs +++ b/basyx-dotnet-components/BaSyx.API.Http.Controllers/AssetAdministrationShell/SubmodelController.cs @@ -927,26 +927,28 @@ public async Task PutFileByPath(string idShortPath, IFormFile fil if (fileElementRetrieved.Entity.ModelType != ModelType.File) { - Result result = new Result(false, new ErrorMessage($"ModelType of {idShortPath} is not File but {fileElementRetrieved.Entity.ModelType}")); + var result = new Result(false, new ErrorMessage($"ModelType of {idShortPath} is not File but {fileElementRetrieved.Entity.ModelType}")); return result.CreateActionResult(CrudOperation.Retrieve); } - IFileElement fileElement = fileElementRetrieved.Entity.Cast(); + var fileElement = fileElementRetrieved.Entity.Cast(); - // keep existing path if available, otherwise set path to uploaded file name - string fileName; - if (fileElement.Value.Value != null) - fileName = fileElement.Value.Value.TrimStart('/'); - else + // Delete existing file if any + if (!string.IsNullOrEmpty(fileElement.Value.Value)) { - fileName = file.FileName; - fileElement.Value.Value = "/" + fileName.Replace("\\", "/"); + var fileProvider = hostingEnvironment.ContentRootFileProvider; + var existingFile = fileProvider.GetFileInfo(fileElement.Value.Value.TrimStart('/')); + if (existingFile.Exists && !string.IsNullOrEmpty(existingFile.PhysicalPath)) + System.IO.File.Delete(existingFile.PhysicalPath); } + + var fileName = file.FileName; + fileElement.Value.Value = "/" + fileName.Replace("\\", "/"); var filePath = Path.Combine(hostingEnvironment.ContentRootPath, fileName); Directory.CreateDirectory(Path.GetDirectoryName(filePath)); - using (var stream = System.IO.File.Create(filePath)) + await using (var stream = System.IO.File.Create(filePath)) { await file.CopyToAsync(stream); } From fd48ab5df6c6065bdc936301a56ce046d46fcbca Mon Sep 17 00:00:00 2001 From: Daniel Klein Date: Wed, 17 Dec 2025 13:38:07 +0100 Subject: [PATCH 2/3] Refactor variable declarations and reset file value Refactored the code to use `var` for variable declarations, enhancing readability. Added a line to reset `fileElement.Value.Value` to an empty string before returning an `Ok()` response, indicating a reset after processing. --- .../AssetAdministrationShell/SubmodelController.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/basyx-dotnet-components/BaSyx.API.Http.Controllers/AssetAdministrationShell/SubmodelController.cs b/basyx-dotnet-components/BaSyx.API.Http.Controllers/AssetAdministrationShell/SubmodelController.cs index ccfab5d..2c10ad4 100644 --- a/basyx-dotnet-components/BaSyx.API.Http.Controllers/AssetAdministrationShell/SubmodelController.cs +++ b/basyx-dotnet-components/BaSyx.API.Http.Controllers/AssetAdministrationShell/SubmodelController.cs @@ -978,20 +978,22 @@ public IActionResult DeleteFileByPath(string idShortPath) if (fileElementRetrieved.Entity.ModelType != ModelType.File) { - Result result = new Result(false, new ErrorMessage($"ModelType of {idShortPath} is not File but {fileElementRetrieved.Entity.ModelType}")); + var result = new Result(false, new ErrorMessage($"ModelType of {idShortPath} is not File but {fileElementRetrieved.Entity.ModelType}")); return result.CreateActionResult(CrudOperation.Retrieve); } - IFileElement fileElement = fileElementRetrieved.Entity.Cast(); - string fileName = fileElement.Value.Value.TrimStart('/'); + var fileElement = fileElementRetrieved.Entity.Cast(); + var fileName = fileElement.Value.Value.TrimStart('/'); - IFileProvider fileProvider = hostingEnvironment.ContentRootFileProvider; + var fileProvider = hostingEnvironment.ContentRootFileProvider; var file = fileProvider.GetFileInfo(fileName); if (file.Exists && !string.IsNullOrEmpty(file.PhysicalPath)) System.IO.File.Delete(file.PhysicalPath); else return NotFound(new { message = "Physical file not found", itemId = file.PhysicalPath }); + + fileElement.Value.Value = string.Empty; return Ok(); } From cce48e0c16cee2e7800346abaa5b7590949015d9 Mon Sep 17 00:00:00 2001 From: Daniel Klein Date: Wed, 17 Dec 2025 13:40:13 +0100 Subject: [PATCH 3/3] Update docu --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a6ffb16..2f71ede 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Make sure Visual Studio is closed the first time you run these scripts. The firs - Fixed put '/submodels/{submodelIdentifier}' endpoint to replace submodel instead of update the submodel (SubmodelRepositoryController) - Fixed Submodel element serialization to write `valueType` property tp use XSD data type definition (SubmodelElementConverter) - The processing of values for Boolean properties has been corrected when these are provided as strings via the REST API. The return format for Boolean values via the REST API has been improved (upper- / lower-case). +- Fix the set of file names and values if the attachment is posted, deleted or put to a file sub-model element. ## Features - Add Submodel Registry HTTP Server (SubmodelRegistryHttpServer)