如何在ASP.NET MVC中通过AJAX正确调用POST操作方法
问题描述:
我试图通过Ajax调用MVC操作失败。当我这样做,就会出现以下错误:如何在ASP.NET MVC中通过AJAX正确调用POST操作方法
HttpException: A public action method 'Find' was not found on controller 'MyProject.Controllers.LoanController'.
的操作方法我试图调用具有以下特征:
[Route("Loan/Find/{loanNumber:int}")]
[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
[ActionName("Find")]
[AllowAnonymous]
public ActionResult Find(int loanNumber)
{
var model = new LoanStatusModel
{
Record = Repository.GetRecord(loanNumber),
User = this.SecurityPrincipal
};
return this.PartialView("LoanStatusSearchResult", model);
}
试图调用它是如下视图代码:
@using(Ajax.BeginForm("Find", new AjaxOptions
{
HttpMethod = "POST",
AllowCache = false,
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "ajaxTarget",
LoadingElementId="loader"
}))
{
<fieldset>
<div class="col-sm-3">
<input type="text"
id="loanNumber"
name="loanNumber"
value="@Model.LoanNumber"
class="form-control"
minlength="8"
maxlength="10"/>
</div>
<div class="col-sm-7">
<input type="submit"
value="Search"
class="btn btn-primary"/>
</div>
</div>
</fieldset>
}
<div id="loader" style="display:none">
Working, please wait...
</div>
<div id="ajaxTarget">
</div>
这是我RouteConfig.cs的内容:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new
{
controller = "Home",
action = "Index",
id = UrlParameter.Optional
}
);
}
Fidler报告,对路由的请求导致HTTP 401未授权,这种情况有意义,因为这是最初配置为禁用匿名访问的Intranet站点。但是,匿名访问已启用,并且错误仍然存在。
要解决这个问题,我已经尝试了所有通过互联网(StackOverflow的特别)搜索后执行以下操作:
- 我改变了IIS接受匿名请求,并重新启动服务器。这对结果没有影响。
- 最初,行动方法是用
HttpPostAttribute
装饰的。将其改为使用AcceptVerbs
对结果没有影响。 - 我在该方法中加入了
AllowAnonymous
,它对结果没有影响。
如何解决此问题?它可以解决吗?我还需要提供哪些其他信息?
答
你有一个属性路线定义
[Route("Loan/Find/{loanNumber:int}")]
所以,当你尝试用yourSite/Loan/Find/123123313
访问您的操作方法将到操作方法,但如果你尝试正常yourSite/Loan/Find?loanNumber=123123123
,这是行不通的!
您的Ajax.BeginForm
html帮助程序生成表单标签的操作值为“/ Home/Find”,当您提交表单时,loanNumber的值将在邮件正文中提交,它不在您定义的路由模式中属性路由定义
如果你删除了属性路由路由定义,你的代码将会工作。属性路由主要用于创建漂亮的seo友好类url。所以它最好用于GET操作,而不是表单发布场景。
如果你仍然想保留属性路由路由模式,我建议你不要使用帮助者方法Ajax.BeginForm
并处理aja x打电话给你的自己,你可以按照你想要的方式构建url。
因此,建立一个正常的形式,给一个身份证的形式。
@using (Html.BeginForm("Find","Home", FormMethod.Post,new {id="mySearchForm"}))
{
<div class="col-sm-3">
<input type="text" id="loanNumber" name="loanNumber"value="@Model.LoanNumber" />
</div>
<div class="col-sm-7">
<input type="submit" value="Search" />
</div>
}
,并有JavaScript来听这个表单的提交事件,阻止默认行为,并与我们想要的网址Ajax调用!
$(function() {
$("#mySearchForm").submit(function(e) {
e.preventDefault();
var url = "@Url.Action("Find","Home")"; //change to your controller name
url = url + "/" + $("#loanNumber").val();
$.post(url, function(res) {
$("#ajaxTarget").html(res);
});
});
});
OH。 MY。神。我不能相信我错过了这一点。 (/ epicfacepalm)你不会相信我忽略了多少次。救命恩人,老兄。 –
我用自定义ajax解决方案更新了答案。干杯:) – Shyju
我实际上修好了路线。我们希望它成为/贷款/状态并在表格中传递数据。老派的网址在这里是个不错的选择。 –