I have VisualStudio 2017. I am working on a simple app. I look up a username and return some information on that person. The oddity this time is that due to where this app will live in the corporate structure the url will be something like:
https://specialAps.my.company.com/MyUserLookup
I can do a WebDeply and based on that configuration the index page appears as I expect at the URL above (note: there is no trailing "/").
The index page is a very simple form with one text input box for the username and a submit button. a jQuery on click
event handler catches the submit event and calls the "Search" action in the "Home" controller.
$.ajax({
url: "/Home/UserSearchResult",
dataType: "json",
traditional: true,
data: {
username: $("#UserSearchForm input#username").val().trim()
}
}).done(...
).fail(...);
This builds a request to:
https://specialAps.my.company.com/Home/UserSearchResult?username=auser
which is invalid because the App Name is no longer in the URL.
I changed the ajax call to:
$.ajax({
url: "/MyUserLookup/Home/UserSearchResult",
dataType: "json",
traditional: true,
data: {
username: $("#UserSearchForm input#username").val().trim()
}
}).done(...
).fail(...);
which seems like it should be the right address but Chrome DeveloperTools reports that the request gets canceled, no request preview or result. If I run the request by hand in a different browser window I get a 400 level "Bad Request" result.
Is this a RouteConfig
issue? I currently have the default route:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.LowercaseUrls = true;
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
I have tried adding the App Name into the route url:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.LowercaseUrls = true;
routes.MapRoute(
name: "Default",
url: "MyUserLookup/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
but then I get 403 Forbidden results on trying to reach the index page.
All of my other projects have had URLs of the form: "https://AppName.host.name" or "https://AppName.host.name/Home/...", what am I missing here?
EDIT
The Admins swear the server is configured correctly.
The jQuery ajax code above is in its own file and is included in the index.cshtml
file via a bundle
. I have tried setting the url:
value in the ajax call to:
url: "@Url.Action('UserSearchResult', 'Home')"
but that just urlencods and embeds @Url.Action('NetidSearchResult', 'Home')
in the generated url.
Now I have added a hidden text field to the simple form and set its value to that of the @Url.Action(...)
. I then use that value in the ajax call as:
url: $("#UserSearchForm input#url").val().trim()
On my desktop (localhost) this generates the correct looking url:
http://localhost:5784/home/usersearchresult?username=auser
but that request gets canceled for some unknown reason. Chrome DeveloperTools reports under the network tab:
usersearchresult?netid=auser (canceled) xhr jquery-3.3.1.js:9600 0 B 27 ms
If I put breakpoints in the UserSearchResult
method I can see that the method runs to completion. The response object claims a 200 level status. If I paste the full url into the browser then I get back the JSON object I expect.
The outline of the search method is below. I can examine the personSearchResult
Dictionary and know it has stuff in it.
[HttpGet]
public ActionResult UserSearchResult(string username) {
var myUser = username.Trim().ToLower();
var personSearchResult = new Dictionary<string, object> {
["errors"] = new List<string>()
};
try {
... put stuff in personSearchResult ...
} catch (Exception e) {
Response.StatusCode = 400;
((List<string>) personSearchResult["errors"]).Add(e.Message);
}
return Json(personSearchResult, JsonRequestBehavior.AllowGet);
}
I have also replaced the return of the possibly complex personSearchResult
object with a trivial Json string and all this still happens.
EDIT 2
I have discoverd that since I am activating the ajax call from an onsubmit
handler that I have to return false;
. That's not the whole answer but its progress.
EDIT 3
Well, that was certainly deeply buried. Turns out that the "service account" that the web server was using to run this app instance did not have permissions to access databases and other resources. That was not being reported in any useful way. Above, I was catching the exception message and putting it in a Dict that would become a Json object in the response... except it didn't. I just set
Response.StatusDescription = e.Message;
in the catch
and saw the error.