Point 1 and 2 checked and implemented For point 3 -- the downloaded project have build error so i updated i can attach the version information here ElsaDemoApp.Server.csproj.txt
I have checked this with swagger i am giving you detail here
Request from swagger https://localhost:44371/api/language-management/language-texts/BookMaster/hi/BookMaster%3A%3ABookPrices?value=%E0%A4%95%E0%A4%BF%E0%A4%A4%E0%A4%BE%E0%A4%AC%20%E0%A4%95%E0%A5%80%20%E0%A4%95%E0%A5%80%E0%A4%AE%E0%A4%A4
Response -- Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints. Matches:
Volo.Abp.LanguageManagement.LanguageTextController.UpdateAsync (Volo.Abp.LanguageManagement.HttpApi)
Elephant.LanguageTexts.LanguageTextController.UpdateAsync (Elephant)
at Microsoft.AspNetCore.Routing.Matching.DefaultEndpointSelector.ReportAmbiguity(Span1 candidateState) at Microsoft.AspNetCore.Routing.Matching.DefaultEndpointSelector.ProcessFinalCandidates(HttpContext httpContext, Span1 candidateState)
at Microsoft.AspNetCore.Routing.Matching.DefaultEndpointSelector.Select(HttpContext httpContext, Span`1 candidateState)
at Microsoft.AspNetCore.Routing.Matching.DfaMatcher.MatchAsync(HttpContext httpContext)
at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
at Volo.Abp.AspNetCore.Tracing.AbpCorrelationIdMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
at Microsoft.AspNetCore.Builder.UseMiddlewareExtensions.InterfaceMiddlewareBinder.<>c__DisplayClass2_0.<
Accept: / Accept-Encoding: gzip, deflate, br, zstd Accept-Language: en-US,en;q=0.9 Connection: close Content-Length: 0 Cookie: .AspNetCore.Mvc.CookieTempDataProvider=CfDJ8KJd1SFUIWtGszVVfvyHcAM86aAOknmSyS75ugsbS-OQHOHaLTQ-D7Wu2XidOzWKtDjUFBnDwGiGFKKtFXbf6HRbK4D-oeBgGTCjN3Zhv0V-hVYFb5vQd5yr6EvKOlWj4cGV_u7fBvpwQTs9UH_uXqOG0gmoxndoENqSftaC8mz; .AspNetCore.Antiforgery.1I8H_rb8Gbk=CfDJ8KJd1SFUIWtGszVVfvyHcAOq8QX2r7zgWtfILABprWQghfDl0kzmAxVIMbjzoDKEIQPtFFz180D5GL2Q6gVqVHkb4lJi_1kXsnN_Z5U0tmEDhdfc3HrQK4JCzWV5lxFGk0ph4dDrjX60EwSSaWY0QZQ; .AspNetCore.Identity.Application=CfDJ8KJd1SFUIWtGszVVfvyHcAMqVG5Kxpogslq5eiKs9s0uqUnzHNIHuKYEX6R3dQ0oWcQ96HDQn8P6Y2X9BWVgRkc-5xIfZX7y6w43YTJDxoSbq0JsCKdsiHmPqJHdPUDdpz1pxHS90wxxrKk_n353oG8C5X7RmxCywxm145Z0ZjQ2tvbl_qfSsv-gbEwTJyWtVTQX92ZI8jnIWKLtwOWy6ypY2jizgtA3u3RfA8bZ1xtI9rJwh4K71QjrnfQ20KG_GcFgnZ8WdCXQmeleWtZRsauwPsQiDJHjpxHl-KNlzDKGWw1Fvlmrxlr7uVUVZ7Pru7ELv-7TV8wtP-PlZPpJ9TDdQqknQF__mNCk4A-B_QnV6GDVI8j4tmPL1OOZSLgQLpjv601x-2SFJSRHeJCwoaZccoG1oV5Stuun85vSFJdyP2BjB_6tFQZGbOmUtdrkdY6weQByyxBCatg2olM90HRXH501dFrPuNk3ukiuJ8IjisXLxPuQFq7dy9sxhFK7xAIi-m_5mmxuX4Mv3cAT74VJJBNpoPn8Yc4Gj9YRJtFZDxCQt4j8aRPkFh78tZWFjpqhSagg2DXV0WQA5EAOJ347cfYQVHP0DkPvIPrxOb7J561fzbXv9qVWwBcSi5L__B8ePIR2h8cgqzOueTy5RPydgCZ6K5LS4mSlrxbvyLNdHXhUxGYaUPQcsNRX95FEWa_uvOk1WE02lqLqqcNC1Z2KOhQQ3dH9lOygJDdbTpXbz9YRITHNXZXaccaLm1vLUsRP7nX_2E3lP3c7JqdTQUdh7bonbnkcLhkB84bppx9T8r8C4fcBRbF_gU30S8DldAvOtPfQQKH-p74nIyx3JRHSr2LyFbfphP4uhey8pKyt4qLy7DFwPeUXvZlEMjUBrPjr_dYCplB-C4c1f5JnQuVV4w1RvEAOnvdNCtPlZvj; XSRF-TOKEN=CfDJ8KJd1SFUIWtGszVVfvyHcAMHXZo8P6c3EkUEGL8L-x5Ak1-eW-35Nkyvh64cM06uhk-pt7V27ss5h0ZJQ5OAQ-oXWxNRASebHtNVsGQ3--1EsToSuuuU63QYCbwH66o9xPy-iFWkVkYKnd-bDEA9jZ6tEEpAjI36kaAw21clumhO1JAGwguRkv5VEHokS7ua3g Host: localhost:44371 Referer: https://localhost:44371/swagger/index.html User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36 Edg/150.0.0.0 requestverificationtoken: CfDJ8KJd1SFUIWtGszVVfvyHcAMHXZo8P6c3EkUEGL8L-x5Ak1-eW-35Nkyvh64cM06uhk-pt7V27ss5h0ZJQ5OAQ-oXWxNRASebHtNVsGQ3--1EsToSuuuU63QYCbwH66o9xPy-iFWkVkYKnd-bDEA9jZ6tEEpAjI36kaAw21clumhO1JAGwguRkv5VEHokS7ua3g sec-ch-ua-platform: "Windows" x-requested-with: XMLHttpRequest sec-ch-ua: "Not;A=Brand";v="8", "Chromium";v="150", "Microsoft Edge";v="150" sec-ch-ua-mobile: ?0 origin: https://localhost:44371 sec-fetch-site: same-origin sec-fetch-mode: cors sec-fetch-dest: empty priority: u=1, i X-Correlation-Id: 00ff3e7f9deb4abaaf22519e667e3a1c
With help of below ticket we have implemented the extended code to attach file with chat Our Support Ticket
We have used controller `using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.BlobStoring;
namespace Elephant.ChatAttachment;
///
private static readonly HashSet<string> AllowedMimeTypes = new(StringComparer.OrdinalIgnoreCase)
{
// Images
"image/jpeg", "image/png", "image/gif", "image/webp", "image/bmp", "image/svg+xml",
// Documents
"application/pdf",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.ms-excel",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.ms-powerpoint",
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
// Archives & generic
"application/zip",
"application/x-zip-compressed",
"text/plain",
"text/csv",
};
private readonly IBlobContainer<ChatAttachmentContainer> _blobContainer;
public ChatAttachmentController(IBlobContainer<ChatAttachmentContainer> blobContainer)
{
_blobContainer = blobContainer;
}
/// <summary>
/// Accepts a single file via multipart/form-data, stores it in the
/// chat-attachment blob container, and returns the blob metadata.
/// </summary>
[HttpPost("upload")]
[Consumes("multipart/form-data")]
[RequestSizeLimit(MaxFileSizeBytes + 4096)] // small extra for form overhead
[ApiExplorerSettings(IgnoreApi = true)] // Swashbuckle 10.x cannot introspect IFormFile; injected via ChatAttachmentDocumentFilter
public async Task<ChatAttachmentDto> UploadAsync([FromForm] IFormFile file)
{
if (file == null || file.Length == 0)
{
throw new Volo.Abp.UserFriendlyException("No file was uploaded.");
}
if (file.Length > MaxFileSizeBytes)
{
throw new Volo.Abp.UserFriendlyException(
$"File size {file.Length / (1024 * 1024):F1} MB exceeds the 20 MB limit.");
}
var mimeType = file.ContentType?.ToLowerInvariant() ?? "application/octet-stream";
if (!AllowedMimeTypes.Contains(mimeType))
{
throw new Volo.Abp.UserFriendlyException(
$"File type '{mimeType}' is not allowed.");
}
var blobId = Guid.NewGuid().ToString("N");
await using var stream = file.OpenReadStream();
await _blobContainer.SaveAsync(blobId, stream, overrideExisting: false);
return new ChatAttachmentDto
{
BlobId = blobId,
FileName = file.FileName,
MimeType = mimeType,
Size = file.Length,
};
}
/// <summary>
/// Streams an uploaded attachment back to the caller.
/// The blob ID acts as an opaque capability token — any authenticated user
/// who possesses the ID may download the file.
/// </summary>
[HttpGet("{blobId}")]
public async Task<IActionResult> DownloadAsync(string blobId)
{
if (string.IsNullOrWhiteSpace(blobId))
{
return BadRequest();
}
var stream = await _blobContainer.GetOrNullAsync(blobId);
if (stream == null)
{
return NotFound();
}
// We do not persist the original MIME or filename on the server,
// so we serve as octet-stream. Clients that know the MIME from the
// attachment token can render appropriately without relying on this header.
return File(stream, "application/octet-stream");
}
} `
Now we are using these api's in react.js UI .We are storing data in sql table using blob container.
All the delete request completes successfully Only after the delete request completes , i try to reupload the same file then i get the concurrency error.
I'm encountering an issue when calling the Language Text Update API: PUT /api/language-management/language-texts/{resourceName}/{cultureName}/{name} The request fails with a 500 Internal Server Error, and the browser reports it as a CORS issue. Request URL: https://localhost:44371/api/language-management/language-texts/AbpAccount/de-DE/AccessDenied?value=Zugriff+abgelehnt! Browser Error: Access to XMLHttpRequest at 'https://localhost:44371/api/language-management/language-texts/AbpAccount/de-DE/AccessDenied?value=Zugriff+abgelehnt!' from origin 'http://localhost:44347' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Failed to load resource: net::ERR_FAILED
Thanks for your help i am able to do this now,
can you please explain this section Then point the container to it:
[BlobContainerName("CompanyDocument")] public class CompanyDocumentContainer { }
Configure<AbpBlobStoringOptions>(options => { options.Containers.Configure<CompanyDocumentContainer>(container => { container.ProviderType = typeof(CompanyDocumentBlobProvider); }); });
Thanks For your help i am able to do the changes at my end. One more thing i want to ask on this point the AbpBlobs table which contains the main binary data of files. can we make it multiple like AbpBlobs_CompanyDocument , AbpBlobs_AccountStatements etc like this?
Hi, I am able to save document using IBlobContainer I kept [FileDescriptors] and CompanyDocument in one databaseA and [AbpBlobContainers] , [AbpBlobs] is in another database say DatabaseB. As per my understanding AbpBlobs contains the file data which is now in DatabaseB. can we cuztomize this and have the main table which has content in DatabaseA only with companyDocument table? If you want to know or asking more about this then please let me know. Thanks
Hi,
I understand this. but is there an option to generate a new project in say Blazor? We are comfortable with React also but just want to make sure that the modular monolith type of project is available only with React and not Blazor.
I would appreciate if some one from the support team can post a reply to my first message.
thanks