Great! It does the trick! Thank you very much!!!
Yes. I tried that, but if I removed that code, it goes back without detail message to Client side. I still only get the general message "An internal error occurred during request".
This is what I am looking for! I want to return the "500 - internal error" to client during development/staging, because not all developers has right to access host server to get the log file.
I followed ismcagdas' example to set "SendAllExceptionsToClients = true;" in SNetWebHostModule. It works, but I get the whole stacks message which is hard to read. I want to filter out some key words and convert to a brief, easy to understand message. So, I tried following suggestion of aaron and alper by adding a class into *Web.Host/Startup, but there is no different. I still get the whole stacks messages. Here is my code:
namespace *.Web.Startup
{
public class ExceptionFilter : IExceptionFilter, IExceptionToErrorInfoConverter, ITransientDependency
{
public IExceptionToErrorInfoConverter Next { set => throw new NotImplementedException(); }
public ErrorInfo Convert(Exception exception)
{
return new ErrorInfo(exception.Message.Substring(0, 20));
}
public void OnException(ExceptionContext context)
{
if (context.Exception is UserFriendlyException)
{
return;
}
context.Exception = new UserFriendlyException("We could not service your request at this stage, please try again later", context.Exception);
}
}
}
public IServiceProvider ConfigureServices(IServiceCollection services)
{
//MVC
services.AddMvc(options =>
{
options.Filters.Add(new CorsAuthorizationFilterFactory(DefaultCorsPolicyName));
options.Filters.AddService(typeof(ExceptionFilter));
});
What did I miss?
Thanks,
Solved. I wrongly understand the "FileToken". It is used as an encrypted file name, instead of a directory.
Just change the code:
if (!Directory.Exists(filePath))
Directory.CreateDirectory(filePath);
File.Copy(fileSource, Path.Combine(filePath, fileName));
as
File.Copy(fileSource, filePath);
It solved my issue.
Now, my next questions:
Thanks,
I figured out my first question, but not 100%. Here is my tests:
I like to keep as simple as possible at my first test. I created a method in FileController:
public ActionResult DownloadTestFile()
{
var filePath = @"C:\x.xlsx";
if (!System.IO.File.Exists(filePath))
{
throw new UserFriendlyException(L("RequestedFileDoesNotExists"));
}
var fileBytes = System.IO.File.ReadAllBytes(filePath);
return File(fileBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
It works fineas I use a browser and url: <a class="postlink" href="http://localhost:22742/File/DownloadTestFile">http://localhost:22742/File/DownloadTestFile</a>.
Now, I want to add a fileToken on it. I created a service:
public class FileAppService : *AppServiceBase, IImageAppService
{
private readonly IAppFolders _appFolders;
public FileAppService(IAppFolders appFolders)
{
_appFolders = appFolders;
}
public FileDto GetFile()
{
var fileSource = @"C:\x.xlsx";
var fileName = "example.xlsx";
var file = new FileDto(fileName, MimeTypeNames.ApplicationVndOpenxmlformatsOfficedocumentSpreadsheetmlSheet);
var filePath = Path.Combine(_appFolders.TempFileDownloadFolder, file.FileToken);
if (!Directory.Exists(filePath))
Directory.CreateDirectory(filePath);
File.Copy(fileSource, Path.Combine(filePath, fileName));
return file;
}
}
This service works fine. When I test it on swager, it give out a FileDto:
"result": {
"fileName": "example.xlsx",
"fileType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"fileToken": "9a864412394442758089b4256029cd48"
}
I confirmed It copies the file on C:\aspnet-core\src\SNet.Web.Host\wwwroot\Temp\Downloads\9a864412394442758089b4256029cd48\example.xlsx
However, when I try to download the file by url: <a class="postlink" href="http://localhost:22742/File/DownloadTempFile?fileType=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet&fileToken=9a864412394442758089b4256029cd48&fileName=example.xlsx">http://localhost:22742/File/DownloadTem ... ample.xlsx</a>,I get exception on code:
throw new UserFriendlyException(L("RequestedFileDoesNotExists"));
What did I miss? Does the "_appFolders.TempFileDownloadFolder" in FileController point to a different location?
Thanks,
Sorry, still don't understand. My need is simple: I have a file "x.jpg" stored in server folder "C:/Files/". How do I code something to let user download it to client side? Can you show me an code example?
I also need to deal other use-cases about files soon, such as embedding a file (e.g. a picture) into json object, and uploading files into server. I wonder if AspNetZero have built-in functions or easy-to-follow instructions about file handling. If not, it is understandable. I may stop digging it in AspNetZero and try other alternatives for handling files. Can you clarify this?
Thank you!
@drenton Thank you for your clue.
I found the class of "FileDownloadService" and "FileController", and studied some examples (e.g. getUsersToExcel). It seems to convert a file into a FileDto and return this FileDto as JSON format {"fileName", "fileType", "fileToken"}, but I still couldn't understand how to convert a file content to "fileToken" in server side and how to convert back the FileDto to original file and save it on client side.
Is there any instruction/tutorial/example about it? Let's say, I have a file example.jpg stored in folder App_Data. How do I build a service on both of Core and Angular sides?
Thanks,
I am using Core + Angular version, and need to return a file (.jpg, .xlsx, .pdf, and so on) to client site. It seems that our API can ONLY return a JSON object, as I know. Is it possible to return a file?
Thanks,
I am using Core+Angular version 5.0.4. Usually, there is no App_Data folder in published files, but when I deployed the published files into IIS and after the first run, the App_Data folder will be created on root and contains Log.txt file.
Recently, the App_Data folder never show up after deployed on IIS. I can run the program, but can't find/trace the Log.txt file.
What do I possibly miss?
Thanks,
The above aaron's code works fine in my methods. Now I have multiple methods (createObj, updateObj, GetObj, and so on) which need the same username, so I moved the same code into the service class constructor. The "GetCurrentUser().UserName;" always throw out exception: Invalid object name 'AbpUsers'.
What do I miss?
Thanks,