[英]How to bypass blazor wasm routing system and make calls to the server
我有一個 blazor wasm 托管應用程序,用戶可以在其中通過填寫表格來創建帳戶。 創建帳戶后,會向用戶發送一個 email,其中包含一個鏈接,用戶必須點擊該鏈接以確認他/她對 email 地址的所有權。 該鏈接指向我服務器中的一個操作方法。 同一台服務器托管 blazor wasm 應用程序和 API。
問題是,當用戶單擊該鏈接時,請求不會發送到服務器。 相反,blazor 會攔截調用並嘗試路由到頁面。
我怎樣才能使這項工作? 我怎樣才能創建一個指向我服務器中的操作的鏈接,在單擊時實際上將它發送到服務器? 換句話說,如果可能的話,如何繞過 blazor 的路由系統?
更新:
Url.Action("actionName", "controllerName", actionParam, Request.Scheme);
. 該鏈接目前看起來像https://localhost:5001/api/user/confirmaemail?confirmationtoken=xyz&useremail=abc
<NotFound />
組件(App.razor 文件)中的內容。 注意:這不是錯誤。 這是 balzor wasm 的正常行為。 如果應用程序托管在www.foo.com
,那么所有對foo.com
(例如www.foo.com/bar
)的調用實際上不會對foo.com
進行,但會被 blazor 攔截並視為應用程序中頁面的路由。 但是,這阻止了我,因為我的 API 與應用程序具有相同的基址(應用程序目前位於localhost:5001/
,而 API 位於localhost:5001/api/xyz
),因此 blazor 阻止了單擊鏈接時調用服務器。 問題是如何解決這個問題? 如果不可能,我還有哪些其他選擇來實施此流程?
所以我通過將 Action 方法設置為 GET 方法而不是 POST 來解決問題。 仔細想想,這很合乎邏輯:當用戶點擊他/她通過 email 收到的鏈接時,將發出 GET,而不是 POST。
我還了解到,僅當您在地址欄中輸入地址時,blazor 才會將您路由到頁面。 如果您單擊鏈接,將發出請求。 我之所以認為 blazor 是在攔截請求,是因為單擊鏈接會將我重定向到一個頁面,但實際上,這只是一種后備機制。 您可以在configure
方法中看到它:
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
// the link clicked issues a GET. My action is a POST.
// So no action is found. It falls back to the index.html
// which is the entery point of my app. Blazor takes over
// from here and tries to find a page for the url requested.
endpoints.MapFallbackToFile("index.html");
});
我遇到過同樣的問題。 我使用 JS Interop 來修復它。 代碼如圖所示。
在 /wwwroot/index.html 添加以下腳本。
<script>
function downloadfile(filename, fileContent) {
var element = document.createElement('a');
element.setAttribute('href', fileContent);
element.setAttribute('download', filename);
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}
</script>
在 Blazor WASM Razor 組件中,在 @code 中添加以下 function。
private async void DownloadFile(string fileName)
{
//Get the file from the Server Side
//Convert fileName string to String Content
var response = await httpService.PostAsync(
url:"/api/download", content:fileNameStringContent);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
await JSRuntime.InvokeVoidAsync("downloadfile", fileName, content);
}
}
在服務器中添加以下 Controller.Action
[HttpPost("download")]
public async Task<string> Download(string fileName)
{
var fileContent = GetFileAsBytes(fileName);
var base64String = "data:application/pdf;base64," + Convert.ToBase64String(fileContent);
return base64String;
}
private async Task<byte[]> GetFileAsBytes(string fileName)
{
try
{
var folderPath = Path.Combine(_env.ContentRootPath, "folder");\
if (!Directory.Exists(folderPath))
return null;
var filePath = Path.Combine(folderPath, fileName);
if (!File.Exists(filePath))
return null;
var fileBytes = await File.ReadAllBytesAsync(filePath);
return fileBytes;
}
catch
{
return null;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.