【问题标题】:Dynamic JavaScript returned by webapiwebapi 返回的动态 JavaScript
【发布时间】:2013-01-07 15:05:50
【问题描述】:

我正在使用 requirejs 为我的页面加载 JavaScript。我有一个 webApi 路由,它动态地从文件中读取并使用 Newtonsoft JObject 返回 JSON。然后在客户端我获取结果并将其分配给本地 JavaScript 变量。

define(['jquery'], 函数 ($) {

function dynoFile() {
    $.get('/api/resources/dynofile', function (results) {
        myNamespace.dynoFile = results;
    });
}

return new dynoFile(); });

此示例确实有效,但它会导致其他预期 myNamespace.dynoFile 存在的 JavaScript 文件出现问题。由于这个文件加载得很好,其他文件不会等待 $.get 完成。

是否有可能让 web api 方法只返回 JavaScript 并让浏览器将其识别为 JavaScript 而不仅仅是文本?我尝试在 web api 中设置响应标头以及返回生成的脚本的多种方式。

这可能吗?

更新:

更详细地说,我正在使用我的 Web API 来处理我的资源文件并将 JSON 返回给客户端,因为它是一个单页应用程序。我希望只从我可以使用 RequireJS 加载的 Web API 返回 JavaScript。我现在将它作为 JSON 工作,并认为我会分享我所拥有的。

这是我的 WebApi 方法,它读取资源文件并将其作为 JSON 返回:

public JObject Get()
{
    var data = new JObject();

    var type = typeof(Translations);
    var properties = type.GetProperties();

    foreach (var property in properties)
    {
        if (property.Name != "ResourceManager" && property.Name != "Culture")
        {
            data.Add( property.Name, property.GetValue(type, null).ToString());
        }
    }

    HttpContext.Current.Response.Headers.Add("Content-Type", "application/json");

    return data;
}

这是我的 translations.js 文件:

define(['jquery', 'underscore'], function ($) {

    function translations() {
    }

    _.extend(translations.prototype, {
        target: '/api/resources/translations',

        getTranslations: function () {
            return $.ajax({
                url: 'api/resources/translations',
                type: 'GET',
                dataType: 'json'
            });
        }
    });

    return (translations);
});

由于我的其他几个文件依赖于现有的翻译,我需要在 main.js 中嵌套 2 条 RequireJS 语句:

requirejs(['application/translations', 'whatever other resources that can load that don't depend on translations'], function () {
    var trans = new translations();

    trans.getTranslations()
        .done(function (result) {
            // set translations into a variable, we chose it to be part of the global namespace
            window.Translations = result;

            // load remaining dependencies that require translations to exist
            requirejs(['myotherjsfiles', 'blahblah', function () {
                // you get the idea...
            });
        });
});

这允许我的翻译首先加载(使用任何非依赖文件,如 bootstrap、jquery 等),然后再加载我所有依赖的 JavaScript 文件。我还针对 RequireJs 优化方法对此进行了测试,它能够解决嵌套需求。希望这可以帮助其他人了解如何将翻译下放到客户端和/或如何使用 RequireJS 加载动态模块。

如果有人知道如何让 WebApi 返回 JavaScript,我很想听听!

干杯!

【问题讨论】:

  • 它不会解决您的问题,您有 2 个选项:使其余代码异步并等待 api 调用的结果,或者使您的 AJAX 调用同步,这将阻止应用程序的执行正在等待服务器的响应。
  • 之前我将 $.get 更改为 $.ajax 并将 async 指定为 false,但是,这并没有延迟 requirejs 加载下一个文件。没有办法构建 JavaScript 字符串并能够将其作为 JavaScript 接收,这似乎很奇怪。我不认为选项 1 是一个可行的选项。
  • 你能写出你尝试过的同步操作的代码吗?以及使用该函数的上下文?事实是,你的代码看起来有点奇怪。
  • 用我的工作解决方案更新了我的原始问题。希望我仍然知道如何从 Web API 返回 JavaScript...

标签: javascript asp.net-web-api


【解决方案1】:

你想要这个问题: Is there a way to force ASP.NET Web API to return plain text?

您不需要创建PlainTextFormatter(我认为唯一的好处是在请求text/plain 时自动捕获?),您只需要一个辅助方法:

    /// <summary>
    /// Generate raw content from the given string output.
    /// <para>See https://stackoverflow.com/a/13028027/1037948 and https://stackoverflow.com/a/11582207/1037948 </para>
    /// </summary>
    /// <param name="responseBody"></param>
    /// <param name="mediaType"></param>
    /// <returns></returns>
    private HttpResponseMessage getRawResponse(string responseBody, string mediaType = "text/plain") {

        var response = Request.CreateResponse(HttpStatusCode.OK);
        response.Content = new StringContent(responseBody, Encoding.UTF8, mediaType);
        return response;
    }

那么对于任何GetSomething 方法,你写:

    public object GetMySomething1() {

        return getRawResponse(string.Format(@"window.SomeValue = {{{0}}}",
                            string.Join(",",
                                        Enum.GetValues(typeof(RandomEnum)).Cast<RandomEnum>().Select(o => string.Format("{0}:\"{1}\"", o, o)))
            ));
    }

这会导致对/myapicontroller/getmysomething1/ 的请求(假设您的路由设置为允许操作)返回:

window.SomeValue = {RandomValue1:"RandomValue1",RandomValue2:"RandomValue2",...}

【讨论】:

    猜你喜欢
    • 2012-04-30
    • 1970-01-01
    • 2012-07-24
    • 1970-01-01
    • 2015-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多