I am trying to download an image from a server (C# Web API). I send a FileStream as a response from the server and on the React client I read it as a blob. This works well with all file extensions except svg. I can't understand why.
Server action:
public async Task<ManagerResult> Get(Guid id)
{
ManagerResult res = new ManagerResult();
try
{
ImageModel image = await _mainContext.Images.FindAsync(id);
string path = image.PhysicalPath;
FileStream file = File.Open(path, FileMode.Open);
res.Success = true;
res.Data = file;
}
catch (Exception exc)
{
res.Success = false;
res.Error = exc.Message;
}
return res;
}
I think that the whole idea of opening a stream and not closing it is bad, but I don't know how else to send a blob.
React side (fetch image):
const imagesGet = async (guid) => {
const url = `${API_PREFIX}/images/get?id=${guid}`
const response = await fetch(url, { method: 'GET', headers: authHeader() })
//Error
const error = responseError(response)
if (error) {
toast.error(error)
return null
}
//Success
const body = await response.blob()
return body
}
React side (create object url):
useEffect(() => {
api.images.get(guid).then((data) => {
const url = URL.createObjectURL(data)
setSRC(url)
}).catch(console.log)
}, [guid, setSRC])
Result:
CodePudding user response:
I think, for a svg data, you need to specify blob type. Such crude is following.
const blob = new Blob([data], {
type: 'image/svg xml; charset=utf8'
});
As you know svg is determined by content-type
field in a header.
The following method helps to determine. If it is svg set type
as I wrote, otherwise not, or just type: 'image'
. If there is still an issue on type
, you can make use of the answer.
async function urlIsSvg(url) {
const r = await fetch(url, {method: 'HEAD'});
return r.headers.get('content-type') === 'image/svg xml';
}
CodePudding user response:
To correctly send files, you need to use FileStreamResult (for Stream) or FileContentResolution (for byte[]). Just use the Controller.File(you_data, mime_type), it will choose the right Resilt on its own.