admin管理员组

文章数量:1417034

I am using requirejs to load JavaScript for my page. I have a webApi route that dynamically reads from a file and returns JSON using the Newtonsoft JObject. On the client side I then take the result and assign it to a local JavaScript variable.

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

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

return new dynoFile(); });

This example does work, however it causes problems with other JavaScript files that expect myNamespace.dynoFile to exist. Since this file loaded just fine, the other files don't wait around for the $.get to plete.

Is it possible to have a web api method return just JavaScript and have the browser recognize it as JavaScript and not just text? I've attempted to set response headers in the web api and a variety of ways to return the script that is generated.

Is this possible?

UPDATE:

To go into a little more detail, I am using my Web API to process my resources file and return JSON to the client as it is a single page app. I was hoping to just return JavaScript from my Web API that I could use RequireJS to load. I have it working now as JSON and thought I would share what I have.

Here is my WebApi method that reads a resource file and returns it as 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;
}

Here is my translations.js file:

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);
});

Since several of my other files depend on the the translations existing, I needed to nest 2 RequireJS statements in my main.js:

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...
            });
        });
});

This allows my translation to load first (with any non dependent files such as bootstrap, jquery, etc.) and then load all my dependent JavaScript files after. I also tested this against the RequireJs optimization method and it's able to resolve the nested requires. Hopefully this helps someone else out with how to get translations down to the client and/or how to use RequireJS to load dynamic modules.

If anyone knows how to get WebApi to return JavaScript, I would love to hear about it!

Cheers!

I am using requirejs to load JavaScript for my page. I have a webApi route that dynamically reads from a file and returns JSON using the Newtonsoft JObject. On the client side I then take the result and assign it to a local JavaScript variable.

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

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

return new dynoFile(); });

This example does work, however it causes problems with other JavaScript files that expect myNamespace.dynoFile to exist. Since this file loaded just fine, the other files don't wait around for the $.get to plete.

Is it possible to have a web api method return just JavaScript and have the browser recognize it as JavaScript and not just text? I've attempted to set response headers in the web api and a variety of ways to return the script that is generated.

Is this possible?

UPDATE:

To go into a little more detail, I am using my Web API to process my resources file and return JSON to the client as it is a single page app. I was hoping to just return JavaScript from my Web API that I could use RequireJS to load. I have it working now as JSON and thought I would share what I have.

Here is my WebApi method that reads a resource file and returns it as 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;
}

Here is my translations.js file:

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);
});

Since several of my other files depend on the the translations existing, I needed to nest 2 RequireJS statements in my main.js:

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...
            });
        });
});

This allows my translation to load first (with any non dependent files such as bootstrap, jquery, etc.) and then load all my dependent JavaScript files after. I also tested this against the RequireJs optimization method and it's able to resolve the nested requires. Hopefully this helps someone else out with how to get translations down to the client and/or how to use RequireJS to load dynamic modules.

If anyone knows how to get WebApi to return JavaScript, I would love to hear about it!

Cheers!

Share Improve this question edited Jan 24, 2013 at 16:24 Jesse Sanders asked Jan 23, 2013 at 23:46 Jesse SandersJesse Sanders 5216 silver badges13 bronze badges 4
  • It wont solve your problem you have 2 options : make the rest of the code async and wait for the result of the api call OR make your AJAX call synchronous which will block the execution of the application as you are waiting for a response from the server. – mpm Commented Jan 24, 2013 at 0:43
  • Earlier I changed my $.get to $.ajax and specified async to false, however, that did not delay requirejs from loading the next file. It just seems odd that there isn't a way to build a string of JavaScript and be able to receive it as JavaScript. I don't see Option 1 as a viable option. – Jesse Sanders Commented Jan 24, 2013 at 0:49
  • Can you write the code you tried for a synchronous operation ? and the context in which the function is used ? the truth is , your code looks a little strange. – mpm Commented Jan 24, 2013 at 0:51
  • Updated my original question with my working solution. Wish I still knew how to return JavaScript from a Web API though... – Jesse Sanders Commented Jan 24, 2013 at 16:25
Add a ment  | 

1 Answer 1

Reset to default 4

You want this question: Is there a way to force ASP.NET Web API to return plain text?

You don't need to create a PlainTextFormatter (I think the only benefit is automatic capturing when text/plain is requested?), you just need a helper method:

    /// <summary>
    /// Generate raw content from the given string output.
    /// <para>See https://stackoverflow./a/13028027/1037948 and https://stackoverflow./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;
    }

Then for any GetSomething method(s), you write:

    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)))
            ));
    }

Which results in a request to /myapicontroller/getmysomething1/ (assuming your route is set up to allow actions) returning:

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

本文标签: aspnet web apiDynamic JavaScript returned by webapiStack Overflow