【问题标题】:MVC and Web Api: The requested resource does not support http method 'POST'MVC 和 Web Api:请求的资源不支持 http 方法“POST”
【发布时间】:2019-09-12 11:19:43
【问题描述】:

因此,我查看了与此问题相关的所有问题,并尝试了所有建议,但均无济于事。我在 Visual Studio 2019 中有一个由多个 MVC 项目组成的解决方案。我想添加一个我已经完成的 Web 服务。到目前为止一切都很好。因此,我使用 ajax 对该 Web 服务进行了调用,因此:

            var apiLocation = getHostname(window.location.href, 0) + "/OLBWebService/api/";
            var obj = { "id": $('#salonDDL').val() };

            // populate the services drop down list based on the salon ID
            $.ajax({
                type: "POST",
                headers: {
                            'Content-Type': 'application/json', /*or whatever type is relevant */
                            'Accept': 'application/json' /* ditto */
                        },
                datatype: "json",  
                url: apiLocation + "Service/GetServicesForSalon",
                data: JSON.stringify(obj),  
                success: function (response) {
                    if (response.length > 0) {
                        $('#serviceDDL').empty();
                        var options = '';
                        options += "<option value='0' selected>Please select a service</option>";
                        for (var i = 0; i < response.length; i++) {
                            options += '<option value="' + response[i].Id + '">' + response[i].Name + '</option>';
                        }
                        $('#serviceDDL').append(options);
                    }
                },
                fail: function (error) {
                    alert(error.StatusText);
                }
            });

因此,我目前在 WebApiConfig.cs 中有我的路由:

            config.MapHttpAttributeRoutes();

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

我使用以下方法设置了一个控制器: (HttpPost 被定义为来自 System.Web.Http 命名空间)

        [HttpPost]
        public IHttpActionResult GetServicesForSalon([FromBody]DefaultParams passedParams)
        {
            List<Service> service = new List<Service>();
            service = _ServiceService.GetServicesBySalonID(passedParams.id);

            try
            {
                return Json(service.Select(s => new { Id = s.ID, Name = s.Description }).OrderBy(s => s.Name));
            }
            catch (Exception ex)
            {
                _loggingService.LogError(ex, "Error in GetServicesForSalon with id of:" + passedParams.id.ToString());
                return null;
            }
        }

传入的 DefaultParams 是这样定义的:

    public class DefaultParams
    {
        public int id { get; set; }
    }

当我在调试模式下通过 Visual Studio 2019 或使用 Fiddler 运行它时,我收到消息“请求的资源不支持 http 方法 'POST'”。

奇怪的是,在这个有效的之前我有一个 ajax 调用。 (语法是我一直使用的原始语法,我在问题调用中尝试过这种语法)

            $.ajax({  
                type: "POST",  
                url: apiLocation + "Salon/GetSalonsByOrg",  
                data: JSON.stringify(obj),  
                contentType: "application/json",  
                datatype: "json",  
                success: function (response) {
                    if (response.length > 0) {
                        $('#salonDDL').empty();
                        var options = '';
                        options += "<option value='0' selected>Please select a salon</option>";
                        for (var i = 0; i < response.length; i++) {
                            options += '<option value="' + response[i].Id +'">' + response[i].Name + '</option>';
                        }

                        $('#salonDDL').append(options);
                    } 
                },
                fail: function (error) {
                    alert(error.StatusText);
                }
            });

控制器是不同的控制器,方法是这样定义的: (HttpPost 被定义为来自 System.Web.Http 命名空间)

        [HttpPost]
        public IHttpActionResult GetSalonsByOrg([FromBody]GetSalonsByOrgParams passedParams)
        {
            List<Salon> salons = new List<Salon>();
            salons = _SalonService.GetSalonsByOrg(passedParams.id);

            try
            {
                if (passedParams.filter != null)
                {
                    return Json(salons.AsEnumerable().Where(s => s.City.ToLower().Contains(passedParams.filter.ToLower())).Select(s => new { Id = s.ID, Name = s.Name }).OrderBy(s => s.Name).ToList());
                }
                else
                {
                    return Json(salons.Select(s => new { Id = s.ID, Name = s.Name }).OrderBy(s => s.Name));
                }
            }
            catch (Exception ex)
            {
                _loggingService.LogError(ex, "Error in GetSalonsByOrg with filter of:" + passedParams.filter);
                return null;
            }
        }

我在这里遗漏了什么? 我已经接近这个问题一天了,我确信这是一件简单的事情,所以新鲜的眼睛会受到赞赏,因为我是办公室的唯一开发人员! 非常感谢您的任何建议。

【问题讨论】:

  • 如果你在你的控制器中设置了一个断点,它会到达那个断点吗?
  • 没有遇到断点。然而localhost/OLBWebService/api/Salon/GetSalonsByOrg 有效,但localhost/OLBWebService/api/Service/GetServicesForSalon 无效。区别在于都继承了 ApiController 的控制器。
  • header请求方式是什么?获取还是发布?只是为了好玩,尝试只传递 Id,例如: var obj = $('#salonDDL').val();然后在您的数据值中: data: { "id": obj } 并在您的控制器方法中: public IHttpActionResult GetServicesForSalon([FromBody]string id)
  • 这是来自 MVC 剃须刀页面 (.cshtml) 的 ajax 调用。该调用是一个 POST,如我原始帖子的第一个代码块所示。我也曾在 Fiddler 中将其作为 POST 进行尝试,结果相同。
  • 最初我确实按照您的建议传递了参数。结果相同。当前代码是在另一个 SO 帖子上建议的,该帖子似乎对其他人有用,所以就用它了。

标签: c# api model-view-controller


【解决方案1】:

其实这不是 POST 方法。这个控制器有更多的方法吗?

【讨论】:

  • Controller 定义为: public class ServiceController : ApiController 除了构造函数没有其他方法。 public ServiceController(IServiceService serviceService, ILoggerService loggingService)
【解决方案2】:

好的。这并不完全是一个答案,但希望我让它工作的程序可能对某人有所帮助。 所以我删除了Web Service项目并重新开始。 添加了一个新项目 Asp.Net Web 应用程序 API。 这会自动在您的 App_Start 文件夹中设置一个 WebApiConfig.cs 文件。 该路线无法正常工作,因为它设置为 routeTemplate: "api/{controller}/{id}", 所以我把它设置为 routeTemplate: "api/{controller}/{action}/{id}",

您还设置了 ValuesController。 一旦更改了路由,就可以使用默认的 GET 和 POST 方法。

接下来我添加了我的 GetServicesForSalon 方法。它仍然在 [FromBody] 中传递了 DefaultParams,但没有声明 int id {get;set;} 我将其更改为字符串,例如字符串 ID {get;set;}

嘿,很快,它奏效了。

我刚刚设置了另一个控制器(ServiceController)并将代码复制到其中看看会发生什么。除了名称(显然)相同。 它不起作用。 所以https://localhost/OLBWebService/api/Values/GetServicesForSalon 有效。 但。 https://localhost/OLBWebService/api/Service/GetServicesForSalon 不起作用?

因此,您似乎仅限于 1 个继承 ApiController 的控制器。 不知道为什么会这样,但我现在有多个 GET 和 POST 方法在我添加项目时由 VS 设置的 ValuesController 中工作。

不理想,因为我喜欢根据对象拆分我的方法,例如沙龙、员工、服务等 但是在这上面浪费了一天之后,我只想继续前进,弥补失去的时间。

【讨论】:

    猜你喜欢
    • 2019-10-07
    • 1970-01-01
    • 1970-01-01
    • 2013-03-05
    • 2018-06-24
    • 1970-01-01
    • 2020-09-19
    • 2012-06-15
    • 2014-06-23
    相关资源
    最近更新 更多