У меня есть класс, который можно сериализовать в файл json. Я хочу разрешить пользователям загружать файл json.
Как я могу сгенерировать файл в памяти, а затем загрузить его браузером ??
Я думаю, мне нужен какой-то поток, но как мне сделать так, чтобы он загружался потом? Я бы хотел избежать JS, так как я ничего о нем не знаю
Я размещаю это на страницах github, смогу ли я создать там текстовый файл из кода? Не говорю, что думаю, что это невозможно, просто пытаюсь предвидеть трудности. Итак, если я правильно вас понял, я создаю файл, заполняю его строковым содержимым, а затем создаю загрузку для этого файла?
Я не думаю, что это лучшая практика, но я бы хотел включить временный каталог в свой проект и, по сути, записать и временно сохранить файл во временный каталог, а затем сразу же удалить его. Теперь, если бы вы были на реальном сервере и точно знали, что эти файлы станут слишком большими, то вы определенно не захотели бы этого делать. Но файлы JSON крошечные, и, насколько я знаю, страницы github не убьют вас, если вы используете часть их пространства.
Если бы вы могли добавить несколько примеров, я бы предпочел это решение JS. Но я действительно понятия не имею, куда добавить весь этот код, который вы уподобили в статье…
Я сам едва работал с Blazor, и на самом деле я не пытался сделать это сам даже в ASP.NET, что помешало мне опубликовать свой собственный ответ. Чтобы начать очень просто, я бы сказал, поместите эту логику в метод внутри блока @code{}
, который привязывается как событие к предполагаемой кнопке загрузки. Попробуйте и заставьте его работать таким образом. Оттуда вы можете рассмотреть возможность перемещения его в свою внутреннюю структуру MVC/MVVM, если вы даже используете это для Blazor.
Вот как я это сделал в своем проекте с JS Interop и System.Text.Json. Этот код не использовался мной уже пару месяцев, и я не могу его протестировать прямо сейчас. Но это сработало, когда я добавил его.
Код блейзера:
@using System.Text.Json
@using Microsoft.JSInterop
@inject IJSRuntime JSRuntime
...
async Task downloadObject(object objectToSave, string fileName)
{
var obj = JsonSerializer.Serialize(objectToSave);
var fileStream = new MemoryStream(new UTF8Encoding(true).GetBytes(obj));
using var streamRef = new DotNetStreamReference(stream: fileStream);
await JSRuntime.InvokeVoidAsync("downloadFileFromStream", fileName, streamRef);
}
JavaScript:
window.downloadFileFromStream = async (fileName, contentStreamReference) => {
const arrayBuffer = await contentStreamReference.arrayBuffer();
const blob = new Blob([arrayBuffer]);
const url = URL.createObjectURL(blob);
const anchorElement = document.createElement('a');
anchorElement.href = url;
if (fileName) {
anchorElement.download = fileName;
}
anchorElement.click();
anchorElement.remove();
URL.revokeObjectURL(url);
}
Я хотел избежать JS, но… В итоге сделал это. Работает как шарм.
Итак, в newtonsoft
JsonConvert.SerializeObject()
возвращает строку, поэтому получить ее в текстовом файле очень просто. Что касается разрешения на загрузку файла, здесь должна быть применима эта статья для ASP.NET. Не уверен, каким должен быть точный Content-Type, учитывая, что это текстовый файл JSON, я предполагаю, что предпочитаю типизацию, используемую для .txt.