500错误 - 无法选择并执行发布操作

时间:2015-11-01 09:23:54

标签: winforms asp.net-web-api

我对Web API不太满意。这是我的问题。我从Windows窗体应用程序发送一个Json序列化对象。该对象是一个实体表。当我做一个get响应时,它返回500服务器错误。基本上我打算在一个控制器中有多个post方法,我可能做得不对。所以我需要你们指导我做错了什么。

这是我的控制器:

[ResponseType(typeof(HttpWebResponse)), HttpPost, ActionName("MerchandiseApi")]        
public HttpResponseMessage PostMain(IList<IMF_Main> mainFromConsolidator)
{
            if (!ModelState.IsValid)
                return Request.CreateResponse(HttpStatusCode.BadRequest, 2);

            using (var anthill = new AnthillConsolidatorEntities())
            {
                var main = new IMF_Main();
                foreach (var item in mainFromConsolidator)
                {
                    main.BrandID = item.BrandID;
                    main.ItemID = item.ItemID;
                    main.CategoryID = item.CategoryID;
                    main.SubCategoryID = item.SubCategoryID;
                    main.ClassID = item.ClassID;
                    main.GenderID = item.GenderID;
                    main.CoaID = item.CoaID;
                    main.SubCoaID = item.SubCoaID;
                    main.First_SRP = item.First_SRP;
                    main.Current_SRP = item.Current_SRP;
                    main.Previous_SRP = item.Previous_SRP;
                    main.isSenior = item.isSenior;
                    main.isActive = item.isActive;
                    main.DateCreated = item.DateCreated;
                    anthill.IMF_Main.Add(main);
                    anthill.SaveChanges();
                }
            }

            return Request.CreateResponse(HttpStatusCode.OK, 1); 
}

这是我的WebApiConfig:

public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

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

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

这是Uri构建的地方:我还有2个表要发送,但我会从这开始。这是我对服务器的第一个Post方法

var jsonMain = JsonConvert.SerializeObject(consolidatorEntities.IMF_Main, Formatting.None);
HttpPost("http://localhost:50826/api/Merchandise/PostMain", jsonMain) == 1.ToString()

    public string HttpPost(string uri, string json)
            {
                string content = "";
                try
                {
                    var request = (HttpWebRequest)WebRequest.Create(uri);
                    request.Method = "POST";
                    request.Accept = "application/json";
                    request.ContentType = "application/json";

                    byte[] bodyBytes = Encoding.UTF8.GetBytes(json);
                    request.GetRequestStream().Write(bodyBytes, 0, bodyBytes.Length);
                    request.GetRequestStream().Close();

                    var response = (HttpWebResponse)request.GetResponse();
                    var sr = new StreamReader(response.GetResponseStream(), Encoding.GetEncod

ing("UTF-8"));
                content = sr.ReadToEnd();
                sr.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error sending data to Anthill \nException: " + ex, "Monytron - Consolidator", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            return content;
        }

1 个答案:

答案 0 :(得分:1)

<强>问题

主要问题在于您的路由。路线将按顺序检查,以便当您向http://localhost:50826/api/Merchandise/PostMain发布请求并按顺序排列这些路线时:

  1. "api/{controller}/{id}"
  2. "api/{controller}/{action}"
  3. 所以第一条路线将匹配:

    • 如果您的PostMain方法是[HttpPost]唯一的操作,那么mainFromConsolidator循环中的foreach将为空,您将收到NullReferenceException该结果500错误。
    • 如果您使用[HttpPost]修饰了多个方法,则这些操作之间的调用不明确,您将收到InvalidOperationExpception&#34;发现多个操作符合请求&#34;消息导致500错误。

    另一个问题是您使用的是ActionName("MerchandiseApi"),但没有发布该行动。

    <强>解决方案

    您可以使用多种解决方案。作为选项,您只能定义一条路线:

    • "api/{controller}/{action}/{id}"

    这样您就可以创建一个包含以下操作的控制器:

    public class SomeController
    {
    
        // matches GET /api/some/action1  
        [HttpGet]
        public HttpResponseMessage Action1()
    
        // matches GET /api/some/action2/5
        [HttpGet]
        public HttpResponseMessage Action2(int id)
    
        // matches POST /api/some/action3
        [HttpPost]
        public HttpResponseMessage Action3(SomeType someParameter)
    
        // matches POST /api/some/action4
        [HttpPost]
        public HttpResponseMessage Action4(SomeType someParameter)
    }
    

    无论如何,如果您决定定义多个路由,请注意路由将按顺序匹配,如果您使用了ActionName属性,则在url中使用该名称来调用该操作。