[英]How to deserialize JSON string from file input
我正在開發一個測試應用程序來證明一些功能,我想要完成的部分工作涉及用戶填寫一個表單,一旦提交下載一個包含表單中所有值的 JSON 文件。 在那里,用戶然后將 JSON 文件發送給另一方,另一方將獲取該文件並使用它來填寫表單上的其他信息,同時保留原始用戶的選擇。
這是我到目前為止所得到的。
數據模型
public class TableDemo
{
public List<Location> Locations { get; set; }
public List<User> Users { get; set; }
public TableDemo()
{
Locations = new List<Location>();
Locations.Add(new Location());
Users = new List<User>();
Users.Add(new User());
}
}
public class Location
{
[Required]
public string Street { get; set; }
[Required]
public string City { get; set; }
[Required]
public string State { get; set; }
[Required]
public string Zip { get; set; }
}
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
}
Controller
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
TableDemo model = new TableDemo();
return View(model);
}
// This is where the user fills out the original form which downloads to their machine as a JSON file.
[HttpPost]
public IActionResult Index(TableDemo model)
{
string jsonString;
var options = new JsonSerializerOptions
{
WriteIndented = true
};
jsonString = JsonSerializer.Serialize(model, options);
byte[] jsonFileArray = Encoding.ASCII.GetBytes(jsonString);
return File(jsonFileArray, "application/json", "testJson.json");
}
// Where the second user inputs the file from the first user
[HttpGet]
public IActionResult ImportForm()
{
return View();
}
// the jsonString argument is always null here
[HttpPost]
public IActionResult ImportForm(string jsonString)
{
TableDemo model = JsonSerializer.Deserialize<TableDemo>(jsonString);
return View("IndexDeserialized", model);
}
}
查看 (ImportForm.cshtml)
@section Scripts{
<script>
function showFile(input) {
let file = input.files[0];
let reader = new FileReader();
reader.readAsText(file);
reader.onload = () => {
console.log(reader.result);
let jsonContent = $('#jsonContent');
jsonContent.append(reader.result);
};
reader.onerror = function () {
console.log(reader.error);
};
};
</script>
}
<body>
<form name="form" method="post" enctype="multipart/form-data">
<div class="form-group">
<input type="file" class="form-control" name="file" onchange="readDocument(this)" />
</div>
<div id="jsonContent">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</body>
從初始視圖生成的我的 JSON 文件的內容
{
"Locations": [
{
"Street": "12345 Test Drive",
"City": "Chicago",
"State": "IL",
"Zip": "55555"
},
{
"Street": "12345 Test Drive",
"City": "ABC",
"State": "IL",
"Zip": "60441"
},
{
"Street": "1234",
"City": "asdasd",
"State": "asdasd",
"Zip": "asdasd"
}
],
"Users": [
{
"FirstName": "asdas",
"LastName": "dasdsa",
"PhoneNumber": "dasd"
},
{
"FirstName": "sadasd",
"LastName": "dsadas",
"PhoneNumber": "asdasd"
}
]
}
所以從這里我有點迷路了。 我嘗試了幾種方法,在這些方法中我提交文件並為ImportForm
設置相應的HttpPost
操作,該操作采用 JSON string
的字符串,甚至是IFormFile
用於提交整個文件以在我將其放入 memory 后進行反序列化.
我不想將文件保存在任何地方,我試圖直接從文件中提取實際的 JSON 文本,將其反序列化回TableDemo
object 並導航到填充了值的新頁面,但所有嘗試都導致要么死在我需要一個文件路徑的地方結束(我也不想將這些文件存儲在任何地方),或者在嘗試將 JSON 字符串發送到 Z594C103F2C6E04C30CAZAB059F03E 操作時得到 null 對象。
如何簡單地獲取 JSON 文件的內容,反序列化回TableDemo
object 並在新頁面上顯示這些值?
System.Text.Json提供了一種簡單的方法來完成您的要求,
"提供將對象或值類型序列化為 JSON 並將 JSON 反序列化為對象或值類型的功能。 "
使用JsonSerializer
API 您可以使用返回string
的Serialize()
和返回object
的Deserialize()
。
一個簡單的例子是:
TableDemo table = System.Text.Json.JsonSerializer.Deserialize(jsonInputString, typeof(TableDemo), options);
有關此 API 的更多信息。
If you're using .NET Framework (rather than .NET Core) you'll need to install the NuGet package in the Package Manager console:
> Install-Package System.Text.Json -Version 4.7.2
好的,這是我的答案。 我瀏覽了您的代碼,並且幾乎沒有問題。 如果我需要為您解決所有問題,則需要一些時間。 但這里有一些建議,您可以將其提升到一個新的水平。
您正在嘗試使用多部分形式更新文件,但您正在嘗試獲取字符串。 您的文件包含 json 的字符串是正確的,但它仍然是一個文件。 所以我們需要處理那部分。
因此,您都在嘗試使用 JavaScript 並在視圖中顯示數據。 在我的示例中,我專注於在您的IndexDeserialized
中顯示數據,而 JavaScript 部分留給另一個問題。
這是我所做的和建議的:
在您的 controller 中,刪除以下方法並將其替換為我發布的方法:
[HttpPost]
public IActionResult ImportForm(string jsonString)
{
TableDemo model = JsonSerializer.Deserialize<TableDemo>(jsonString);
return View("IndexDeserialized", model);
}
新方法,這只是一個簡單的例子,它可以讀取您上傳的文件並將其結果返回到同一頁面。
[HttpPost]
public async Task<IActionResult> ImportFormOnPost()
{
string jsonString = string.Empty;
if (HttpContext.Request.Form.Files[0] != null)
{
var file = HttpContext.Request.Form.Files[0];
await using (MemoryStream ms = new MemoryStream())
{
await file.CopyToAsync(ms);
jsonString = Encoding.UTF8.GetString(ms.ToArray());
}
}
TableDemo model = JsonSerializer.Deserialize<TableDemo>(jsonString);
return View("IndexDeserialized", model);
}
在您的 ImportForm 中,您缺少操作,在這種情況下,我們將發布到ImportFormOnPost
方法:
<form name="form" method="post" enctype="multipart/form-data" action="ImportFormOnPost">
<div class="form-group">
<input type="file" class="form-control" name="file" />
</div>
<div id="jsonContent">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
<div style="margin-top:15px">
<output form="uploadForm" name="result"></output>
</div>
</form>
最后,我們在IndexDeserialized
中展示您的數據:
@model FileUploaderApp.Models.TableDemo
<p>Number for locations: @Model?.Locations?.Count</p>
@if (Model != null)
{
foreach (var user in @Model.Users)
{
<p>@user.FirstName @user.LastName</p>
}
}
在前端使用 JavaScript 時,可以將您的數據顯示為 JSON object,但我認為這部分是自己的問題。
請記住,這只是示例,您可以在此基礎上做很多事情。
最終結果如下所示:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.