如何在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); 
      }); 
    }); 

}); 
+0

OH。 MY。神。我不能相信我错过了这一点。 (/ epicfacepalm)你不会相信我忽略了多少次。救命恩人,老兄。 –

+0

我用自定义ajax解决方案更新了答案。干杯:) – Shyju

+0

我实际上修好了路线。我们希望它成为/贷款/状态并在表格中传递数据。老派的网址在这里是个不错的选择。 –