Select to view content in your preferred language

MVC4 Web API and Dojo Config

5109
6
01-17-2013 01:58 PM
ReneRubalcava
Esri Frequent Contributor
Ok, this is killing me.
I recently started usiing MVC4 and the new Web API to build an app. Everything works great when running in Visual Studio and even works fine when running from my deployment server if I access the url as localhost/application, but once I change to the site name //<servername>/application it looks like the regex for loading modules with Dojo CDN break.

Here is my main.js
(function () {
    'use strict';

    var root = this;

    require({
        async: true,
        parseOnLoad: true,
        aliases: [["text", "dojo/text"]],
        packages: [
          {
              name: "views",
              location: location.pathname.replace(/\/[^/]+$/, "") + "Scripts/app/views"
          }, {
              name: "models",
              location: location.pathname.replace(/\/[^/]+$/, "") + "Scripts/app/models"
          }, {
              name: "helpers",
              location: location.pathname.replace(/\/[^/]+$/, "") + "Scripts/app/helpers"
          }, {
              name: "widgets",
              location: location.pathname.replace(/\/[^/]+$/, "") + "Scripts/app/widgets"
          }, {
              name: "app",
              location: location.pathname.replace(/\/[^/]+$/, "") + "Scripts/app"
          }
        ]
    }, ['app/run']);


}).call(this);


I am not using the bundler for my modules

Here is my Script Render function on my cshtml file
        @Scripts.Render("~/bundles/jquery",
        "~/bundles/jqueryui",
        "~/Scripts/toastr.js",
        "//serverapi.arcgisonline.com/jsapi/arcgis/?v=3.3compact",
        "~/Scripts/app/main.js");


The error I get is
http://serverapi.arcgisonline.com/jsapi/arcgis/3.2compact/js/dojo/dojo/Scripts/app/run.js 404 (Not Found) 


So for some reason, it looks like location.pathname.replace() regex isn't working when using the servername, but is fine when using localhost.

If anyone has deployed successfully a MVC4 app in this manner, I'd appreciate any help. As it is, I'll need to work on reworking this as a non-MVC4 app in the meantime.
0 Kudos
6 Replies
ReneRubalcava
Esri Frequent Contributor
Well this is weird.
If my site url is
http://<servername>/appname

My loader is broken, but if my site url is
http://<servername>/appname/

It works perfect because the regex is looking for the last "/" to start the replace.

For some reason a vanilla html/js app will automatically append the "/" at the end of the URL, but MVC4 is not, probably because there is no index.html in the root of the app. So I think there is some sort of setting I need to adjust for this to happen, which I just find odd. I'll have to dig in further on this one.

Just a heads up if anyone else comes across this problem. If I can figuer out a solution, I'll post it up.
0 Kudos
ViktorLozhkin
Deactivated User
This is a common ASP.NET MVC issue, not only dojo.
You must use Url.Content method helper with tilda-symbol for references in cshtml-file, cause in production environment your files may be placed in the virtual folders like myapp in http://www.example.com/myapp/

In the version ASP.NET MVC4 (Razor 2.0) Url.Content may be ommited but not for javascript block.

require({
        async: true,
        parseOnLoad: true,
        aliases: [["text", "dojo/text"]],
        packages: [
          {
              name: "views",
              location: '@Url.Content("~/Scripts/app/views")'
          }, {
              name: "models",
              location: '@Url.Content("~/Scripts/app/models")'
          }, {
              name: "helpers",
              location: '@Url.Content("~/Scripts/app/helpers")'
          }, {
              name: "widgets",
              location: '@Url.Content("~/Scripts/app/widgets")'
          }, {
              name: "app",
              location: '@Url.Content("~/Scripts/app")'
          }
        ]
    }, ['app/run']);
0 Kudos
ReneRubalcava
Esri Frequent Contributor
Ha, thanks!
I'll give that a shot when I get home. It's much simpler than the method I used to do a custom router to add the slash.
Will that work if I load the js file with the ScriptBundle then? I didn't think it would work in a standalone js file, but admittedly I didn't try.
0 Kudos
ViktorLozhkin
Deactivated User
Will that work if I load the js file with the ScriptBundle then?


Method helpers acts as instruction to ViewEngine (Razor in your case) for page rendering, so if you put Url.Content to js-file it will do nothing and you will get an error from dojo loader again.

The solution - configure all objects which requires Url.Content or another ViewEngine activity in cshtml-file.

<script type="text/javascript">
var dojoConfig = {
        async: true,
        parseOnLoad: true,
 packages: [ /* package definitions here*/ ]
};
</script>
<script type="text/javascript" src="//serverapi.arcgisonline.com/jsapi/arcgis/?v=3.3"></script>
0 Kudos
ReneRubalcava
Esri Frequent Contributor
I know, but I was hoping if I loaded it with ScriptBundle the helpers would get processed.
This method is a quick fix, but not ideal for my situation. This will come in handy on prototyping though, thanks.
The solution I found was to create a custom Router that added a trailing slash to the Url.
http://stackoverflow.com/questions/1385265/add-a-trailing-slash-at-the-end-of-each-url
This won't break my bundles like URL Rewrite will.

Thanks again.
0 Kudos
deleted-user-Jie3eyjOl9XM
Deactivated User
I realize it's 18 months after your post. But, I did something that solved the bundle vs script issue for me, using MVC. I check the ASP.Net debugger setting, and load either the script or the bundle. This I can quickly override that setting if an issue needs investigation, too. Here's my dojoConfig using Razor syntax.

var debugMode = Boolean(@HttpContext.Current.IsDebuggingEnabled.ToString().ToLower());
var packageSrc = debugMode ? '@Html.ResolveServerUrl("~Scripts")' : '@Html.ResolveServerUrl("~bundles")';
var dojoConfig = {
    isDebug: debugMode,
    packages: [{
        name: "app",
        location: packageSrc + '/app'
    },
    {
        name: "widget",
        location: packageSrc + '/widget'
    }]
};
0 Kudos