【发布时间】:2018-02-12 17:13:27
【问题描述】:
我有 VisualStudio 2017。我正在开发一个简单的应用程序。我查找用户名并返回有关该人的一些信息。这次奇怪的是,由于此应用程序将在公司结构中的位置,URL 将类似于:
https://specialAps.my.company.com/MyUserLookup
我可以做一个 WebDeply 并基于该配置,索引页面会按我预期的方式显示在上面的 URL 中(注意:没有尾随的“/”)。
索引页面是一个非常简单的表单,其中包含一个用于用户名的文本输入框和一个提交按钮。 jQuery on click 事件处理程序捕获提交事件并调用“主页”控制器中的“搜索”操作。
$.ajax({
url: "/Home/UserSearchResult",
dataType: "json",
traditional: true,
data: {
username: $("#UserSearchForm input#username").val().trim()
}
}).done(...
).fail(...);
这会构建一个请求:
https://specialAps.my.company.com/Home/UserSearchResult?username=auser
这是无效的,因为应用程序名称不再在 URL 中。
我把ajax调用改成:
$.ajax({
url: "/MyUserLookup/Home/UserSearchResult",
dataType: "json",
traditional: true,
data: {
username: $("#UserSearchForm input#username").val().trim()
}
}).done(...
).fail(...);
这似乎应该是正确的地址,但 Chrome DeveloperTools 报告请求被取消,没有请求预览或结果。如果我在不同的浏览器窗口中手动运行请求,我会得到 400 级别的“错误请求”结果。
这是RouteConfig 的问题吗?我目前有默认路由:
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 }
);
}
我已尝试将应用名称添加到路由 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 }
);
}
然后我在尝试访问索引页面时得到 403 Forbidden 结果。
我所有其他项目都有以下形式的 URL:“https://AppName.host.name”或“https://AppName.host.name/Home/...”,我在这里缺少什么?
编辑
管理员发誓服务器配置正确。
上面的 jQuery ajax 代码在它自己的文件中,并通过bundle 包含在index.cshtml 文件中。我尝试将 ajax 调用中的 url: 值设置为:
url: "@Url.Action('UserSearchResult', 'Home')"
但这只是 urlencods 并将 @Url.Action('NetidSearchResult', 'Home') 嵌入到生成的网址中。
现在我在简单表单中添加了一个隐藏文本字段,并将其值设置为@Url.Action(...) 的值。然后我在 ajax 调用中将该值用作:
url: $("#UserSearchForm input#url").val().trim()
在我的桌面(本地主机)上,这会生成正确的 url:
http://localhost:5784/home/usersearchresult?username=auser
但该请求因某种未知原因而被取消。网络标签下的 Chrome DeveloperTools 报告:
usersearchresult?netid=auser (canceled) xhr jquery-3.3.1.js:9600 0 B 27 ms
如果我在UserSearchResult 方法中放置断点,我可以看到该方法运行完成。响应对象声明 200 级状态。如果我将完整的 url 粘贴到浏览器中,那么我会得到我期望的 JSON 对象。
搜索方法的概要如下。我可以检查personSearchResult 字典并知道里面有东西。
[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);
}
我还用一个简单的 Json 字符串替换了可能复杂的 personSearchResult 对象的返回,这一切仍然发生。
编辑 2
我发现,由于我要从 onsubmit 处理程序激活 ajax 调用,因此我必须到 return false;。这不是完整的答案,而是它的进步。
编辑 3
嗯,那肯定被深深地埋没了。事实证明,Web 服务器用于运行此应用程序实例的“服务帐户”没有访问数据库和其他资源的权限。没有以任何有用的方式报告这一点。上面,我正在捕获异常消息并将其放入一个 Dict 中,该 Dict 将成为响应中的 Json 对象......但它没有。我刚刚设置了
Response.StatusDescription = e.Message;
在catch 中看到了错误。
【问题讨论】:
-
你说
https://specialAps.my.company.com/Home/UserSearchResult?username=auser无效,但http://localhost:5784/home/usersearchresult?username=auser(同一路由)有效。因此,您的问题不清楚 - 什么是有效网址而不是无效网址?你说appName在查询字符串中,但我在那里看到了一个用户名。请说明您要达到的目标。 -
请注意默认路由类完全忽略主机名和查询字符串。他们唯一考虑的是路径,除非您customize routing 考虑其他部分。
-
@NightOwl888:关于我的问题在网址上不清楚,您是完全正确的。在 localhost 上,查询路径只是“控制器/操作”。在开发服务器上,管理员将此应用程序配置为将其 appName 作为查询路径的第一个元素:.../myApp/controller/action'。当我写这些行时,我的代码的某些方面没有将 appName 添加到目标 url 中,因为它应该有。