ASP.Net MVC 4 WebAPI POST返回404

时间:2013-12-04 06:47:47

标签: asp.net-mvc-4 asp.net-web-api

我已经查看了许多类似的问题,但找不到适用于我的解决方案。所以对Get的调用工作正常,但调用POST返回404.我创建了一个简单的WebAPI项目(MVC 4)。

public class CasesController : ApiController
{
    [Inject]
    public ICaseManager CaseManager { get; set; }

    // GET api/cases
    public IEnumerable<Case> Get()
    {
        return CaseManager.ListCases();
    }

    // POST api/cases
    [HttpPost]
    public void Post([FromBody]Case objCase)
    {

    }
}

因此,当我导航到http://localhost:34645/api/cases时,我得到以下内容:

[{"CaseID":1,"CaseCode":"one","CaseDescription":"case one"},{"CaseID":2,"CaseCode":"two","CaseDescription":"case two"}]

我创建了另一个项目(ASP.Net)并在其中包含一个html文件,其中包含以下代码:

<script src="Scripts/jquery-2.0.3.js"></script>
<script src="Scripts/jquery-2.0.3.intellisense.js"></script>

<script type="text/javascript">
    function postData() {
        $.post('http://localhost:34645/api/cases', { "CaseID": 3, "CaseCode": "three", "CaseDescription": "case three" }).done(function (data) { alert("Success " + data); }).fail(function (xhr, textStatus, errorThrown) { alert("Error " + xhr.status); });
    }
</script>

每次单击调用postData的按钮时,都会收到警告“错误404”。

以下是我的路线:

的Global.asax:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    WebApiConfig.Register(GlobalConfiguration.Configuration);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}

WebAPIConfig.Register:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        //RA: to get JSON
        var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
        config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);

    }
}

RouteConfig:

 public class RouteConfig
 {
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

请告知。

5 个答案:

答案 0 :(得分:5)

注意WebApi注册行的顺序。我发现当我按照这个顺序专门使用Global.asax.cs代码时它起作用了:

        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

否则,它因404错误而失败。

答案 1 :(得分:0)

如果这些是两个独立的解决方案,请检查它们是否都在运行 - 它们可能正在尝试共享服务器实例,因此当您尝试访问其他应用程序时,您尝试访问的WebAPI未运行。如果它们是同一解决方案中的项目,请检查它们是否都设置为在启动时运行,或者再次,当ASP.NET项目尝试访问它时,WebAPI将不会运行。

答案 2 :(得分:0)

请尝试以下操作。这个对我有用。为简洁起见,我删除了一些属性。

public class CasesController : ApiController {
    // GET api/cases
    public IEnumerable<Case> Get() {
        var caseManager = new CaseManager();
        return caseManager.ListCases();
    }

    // POST api/cases
    [HttpPost]
    public string Post([FromBody]Case objCase) {
        return objCase.CaseName;
    }
}

public interface ICaseManager     {
    IEnumerable<Case> ListCases();
}

public class CaseManager     {
    public IEnumerable<Case> ListCases()
    {
        return new List<Case>() { new Case() { CaseID = 1, CaseName = "one" } };
    }
}

public class Case     {
    public int CaseID { get; set; }
    public string CaseName { get; set; }
}

查看

<script type="text/javascript">
    //function postData() {
    //    $.post('http://localhost:58820/api/cases', { "CaseID": 3, "CaseCode": "three", "CaseDescription": "case three" })
    //        .done(function (data) { alert("Success " + data); }).fail(function (xhr, textStatus, errorThrown)
    //        { alert("Error " + xhr.status); });
    //}
$(document).ready(function () {
    $('#save-source').click(function (e) {

        e.preventDefault();
        var source = {
            'ID': 0,
            'CaseID': 3,
            'CaseName': "three",
        };
        $.ajax({
            type: "POST",
            dataType: "json",
            url: "/api/cases",
            data: source,
            success: function (data) {
                alert(data);
            },
            error: function (error) {
                jsonValue = jQuery.parseJSON(error.responseText);                    
            }
        });
    });
});


</script>

 @using (Html.BeginForm(null, null, FormMethod.Post, new { id = "myForm"}))
    {
        <input type="submit" id="save-source" name="save-source" value="Add" />
    }

答案 3 :(得分:0)

经过不同的尝试,这篇文章给了我最多的帮助:

WebAPI and CORS enabled REST services

我还通过NuGet安装了Ninject WebApi DependencyResolver包。

答案 4 :(得分:0)

您写的是发布到$.post('http://localhost:34645/api/cases'...

您可以更改网址以明确包含操作方法名称,例如:$.post('http://localhost:34645/api/cases/post'.. 或者你在config.Routes.MapHttpRoute中添加一个默认动作,当url中没有指定任何动作时将使用该动作

 config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { action="Post", id = RouteParameter.Optional }
        );

或者您可以将路线更改为

  config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",               
            ); 

(没有{action}然后当你使用post http动词时,web api会到达Post方法(它知道自动执行,但是如果设置默认动作,它将覆盖它)