Dynamic JavaScript returned by webapi

匿名 (未验证) 提交于 2019-12-03 00:59:01

问题:

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 complete.

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!

回答1:

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

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",...} 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!