我已经构建了一个API端点来从中获取可用语言。在我的MVC
应用程序中,我有一个帮助程序来获取语言异步。该方法定义如下:
public static async Task<Languages> GetLanguagesAsync()
{
var apiResponse = await APIHelper.GetContentGetAsync("Languages").ConfigureAwait(false);
return apiResponse.LanguagesDataModel;
}
在我的View
中,我想将下拉列表绑定到用户可以选择的可用语言列表。
@ Html.DropDownListFor(m =&gt; m.Language,LanguageHelper.AvailableLanguages)
getter
定义如下:
public static IEnumerable<SelectListItem<string>> AvailableLanguages
{
get
{
var result = GetLanguagesAsync().Result;
return new List<SelectListItem<string>>(result.Languages.Select(l => new SelectListItem<string> {Value = l.Key, Text = l.Value}));
}
}
但是,我总是在第var result = GetLanguagesAsync().Result;
行收到错误,这是here最受欢迎的答案。
抛出的异常是
此时无法启动异步操作。异步操作只能在异步处理程序或模块中启动,或者在页面生命周期中的某些事件中启动。如果在执行页面时发生此异常,请确保将页面标记为&lt;%@ Page Async =&#34; true&#34; %取代。此异常也可能表示尝试调用&#34; async void&#34;方法,在ASP.NET请求处理中通常不受支持。相反,异步方法应该返回一个Task,调用者应该等待它。
如上所述here,被叫操作标记为async
。
答案 0 :(得分:1)
今天的Razor代码无法处理异步调用,即使您使用同步阻塞(is a design mistake)来封装这些调用。操作为async
的事实并不重要,因为这是在操作完成后处理视图期间。
ASP.NET Core中添加了异步视图;但是,它应该仍然是一个不常见的用例。
一般来说,您的选择是:
在这个具体案例中,我同意Panagiotis的意见,即每个应用程序只能加载一次这种不变的信息,而不是每次调用一次。在Lazy<T>
内包装同步实现将是最简单的解决方案。