Javascript(Jquery)调用MVC3 Controller/Action/ID的URL路由问题,返回404,
URL Routing issue with Javascript (Jquery) call to MVC3 Controller/Action/ID, returning 404, should get JSon
问题:如何对传递给javascript的URL进行编码,以便在构建/部署的版本中,代码将转到带有id的控制器/操作并返回JSon数据,就像在Visual Studio环境中一样?
目标:将日期返回到日期选择器,因为这些日期将被禁用。我期望返回JSon字符串数组,这些字符串是日期,然后输入到日期选择器中。
与他人的相关性:从对Controller/Action/ID的调用中返回JSon数据似乎是一件常见的事情。我看到了其他关于路由问题的问题,以及JSon,jQuery似乎是增强web开发的一种流行方式。
背景:我有一个jQueryUI日期选择器,它调用Controller/Action/ID并向日期选择器返回json数据。它在VisualStudio中运行时运行良好,但在构建和部署到Dev环境时失败。代码将生成并传递给jQuery的URL传递为:/安全/验证/getDisabledDates/999
我们正在使用Umbraco,在Umbraco区域中有一个名为/Secure的目录来保存我们的MVC代码。代码尝试然后在开发环境中生成的URL是:/安全/验证/getDisabledDates/999如果我观察Firebug中的调用和错误,我会看到以下错误:岗位http://dev.ourcompanyname.com/Secure/Validation/getDisabledDates/999302找到了(如果我进一步调查,我发现它真的是一个404,被发送到错误页面,这就是找到的。)
我在视图中使用@Url.Action来获得操作的正确Url(希望如此),但当在Dev环境中发出javascript请求时,返回的是404。代码进入javascript代码,并在警报中显示URL,这在我看来是正确的。代码似乎没有MVC控制器那么远(我试着在那里放了一个消息框)。
这似乎是因为控制器实际上不是目录中一个不同的、真实的页面,因为MVC代码被编译到DLL中。我听说过,这很有道理,但世界上其他人似乎在呼叫控制器,所以我不确定我的问题是什么。
最初只有一组日期,所以一些代码调用只说GetDates,但后来它被Widget分解了,所以调用会反映ByWidget,所以会传递一个ID。所有调用都能正确跟踪,代码在Dev.中运行
在javascript函数中成功调用的SetDates是另一个javascript函数,但我在SetDates中设置了警报,在Dev环境中,代码没有走那么远,可能是因为它在ValidationController中找不到代码。
如果有任何有用的建议,我们将不胜感激!
规格:MVC3,Javascript 1.6.4,Jquery Jquery-ui-1.8.17,IIS 7.5,Umbraco 4.7.1,Visual Studio 2010
单独.js文件中的Javascript代码:
function getDisabledDatesByWidget(urlGetDisabledDatesByWidget) {
alert('urlGetDisabledDatesByWidget = ' + urlGetDisabledDatesByWidget);
$.ajax({
//data: {id: id},
type: "POST",
async: false,
url: urlGetDisabledDatesByWidget,
dataType: 'json',
success: setDates,
constrainInput: true,
defaultDate: new Date(defaultCutoff + " 00:00")
});
}
视图中的MVC代码,在文档准备功能中:
widgetId = '@ViewBag.WidgetId';
var urlGetDisabledDatesByWidget = '@Url.Action("getDisabledDates", "Validation", new{id = @ViewBag.WidgetId})';
getDisabledDatesByWidget(urlGetDisabledDatesByWidget);
ValidationController中的MVC代码:
[HttpPost]
public JsonResult getDisabledDates(int id)
{
List<String> disabledDateStrings = new List<String>();
List<DateTime> _DisabledDateDates = DisabledDateSetup.GetDisabledDateDatesByWidget(id).Value.ToList();
////Convert disabled dates to string array
foreach (DateTime disabledDate in _DisabledDateDates)
{
disabledDateStrings.Add(disabledDate.ToString("M-d-yyyy"));
}
ChangeType _changeType = ChangeType.NoChangeType;
ChangeDateRangeSetupResponse _dates = DisabledDateSetup.GetValidChangeDateRange(_changeType);
return Json(new
{
disabledDates = disabledDateStrings,
startDate = UnixTicks(_dates.Value.BeginDate),
endDate = UnixTicks(_dates.Value.EndDate)
});
}
视图中的MVC代码,在div中:
@Html.TextBoxFor(model => model.SetupDate, new { id = "DisabledDateCalendar"})
全局asax路由:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Account", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
在发布之前,我尝试解决了这个问题:
- 在我的办公室咨询了其他开发商
- 使用Firefox/Firebug和Chrome/Chrome的F12功能在Dev中跟踪调用
- 在代码中放置警报/消息框,部署它,并查看显示的内容和未显示的内容
- 在谷歌上搜索答案
- 审查了许多堆栈溢出问题,包括:
- asp.net MVC路由-javascript url 404错误
- 在外部JavaScript中处理ASP.NET MVC路由
- 使用default.aspx/controller/action样式url时ASP.NET MVC路由失败
我从不让Razor将数据注入我的JavaScript,只在语义上注入HTML。此外,与其使用Url.Action
和那些奇怪的助手,不如手动呈现URL和标记?MVC似乎添加了很多不必要的方法,而且更容易理解事情的实际进展:
代替:
@Html.TextBoxFor(model => model.SetupDate, new { id = "DisabledDateCalendar"})
怎么样:
<input type="text" id="DisabledDateCalendar" value="@Model.SetupDate" />
使您的其他代码从JavaScript:语义上可访问
<input type="hidden" id="widgetId" value="@ViewBag.WidgetId" />
<input type="hidden" id="urlGetDisabledDatesByWidget" value="/secure/validation/getdisableddates/@ViewBag.WidgetId" />
另外,您的AJAX是同步的原因是什么?让我们实现异步,现在您不需要将Razor与JS:混合在一起
function getDisabledDatesByWidget(urlGetDisabledDatesByWidget) {
var urlGetDisabledDatesByWidget = $('#urlGetDisabledDatesByWidget').val(),
widgetId = $('#widgetId').val();
alert('urlGetDisabledDatesByWidget = ' + urlGetDisabledDatesByWidget);
$.ajax({
//data: {id: id},
type: "post",
url: urlGetDisabledDatesByWidget,
dataType: 'json',
constrainInput: true,
defaultDate: new Date(defaultCutoff + " 00:00")
})
.done(setDates);
}
虽然我同意Eli的很多回答,但我不同意他驳回Url.Action和其他生成Url的MVC助手。对他们来说,关键是他们被MVC的路由引擎钩住了,所以如果路由发生了变化,而你正在使用URL助手,你就必须对视图中的URL进行零更新。但是,如果你已经对所有Url进行了硬编码,而不是使用Url.Action,你将不得不返回并手动更改每个Url。
以下是Phil Haack的一篇优秀文章,其中举例说明了Url.Action在解决MVC中的一个错误时如何避免了很多麻烦:http://haacked.com/archive/2011/02/20/routing-regression-with-two-consecutive-optional-url-parameters.aspx
- 使用ui路由器实现动态URL路由的最佳方式是什么
- Ui路由器未按url路由
- 使用ui路由器在URL路由中创建一个必需的参数
- Javascript 无法解析正确的图像路径,当使用 URL 路由在 ASP.Net 中请求页面时
- AngularJS ui-router 中的 URL 路由参数
- 有没有一种方法可以在express.js中的url路由中执行动态键/值参数
- 使用正则表达式的Url路由子字符串
- Javascript(Jquery)调用MVC3 Controller/Action/ID的URL路由问题,返回404,
- Backbone.js:url路由末尾的尾部斜杠
- 在本地基于文件的应用程序中(使用file://),是否可以使用AngularJS进行HTML5模式URL路由
- Angular的url路由不能直接访问
- AngularJS为同一个URL路由多个ui-view
- 从Express服务的客户端React应用上的一致url路由
- 创建一个模板url路由脚本
- Url路由不工作在我的PHP代码
- Javascript MVC Url路由组件,路由在两边
- URL路由到子视图
- react-router-component将所有url路由到同一个组件
- Javascript将/url路由到函数
- AngularJS相对url路由问题