Winforms 500错误-无法选择并执行post操作

Winforms 500错误-无法选择并执行post操作,winforms,asp.net-web-api,Winforms,Asp.net Web Api,我不擅长使用Web API。这是我的问题。我从Windows窗体应用程序发送Json序列化对象。对象是一个实体表。当我执行get响应时,它返回一个500服务器错误。基本上,我计划在一个控制器中使用多个post方法,但我可能做得不对。所以我需要你们来指导我到底做错了什么 这是我的控制器: [ResponseType(typeof(HttpWebResponse)), HttpPost, ActionName("MerchandiseApi")] public HttpRespons

我不擅长使用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); 
}
这里是构建Uri的地方:我还有两个表要发送,但我将从这个开始。这是我向服务器发送的第一个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;
        }
问题

主要的问题是你的路线。Routes将按顺序进行检查,因此当您向http://localhost:50826/api/Merchandise/PostMain 这些路线是按顺序排列的:

api/{controller}/{id} api/{controller}/{action} 因此,第一条路线将匹配:

如果PostMain方法是[HttpPost]的唯一操作,则mainFromConsolidator在foreach循环中将为null,您将收到一个NullReferenceException,该异常将导致500错误。 如果您有多个用[HttpPost]修饰的方法,那么这些操作之间的调用是不明确的,并且您将收到InvalidOperationException,其中发现多个操作与请求消息匹配,从而导致500错误。 另一个问题是您正在使用ActionNameMerchandiseApi,但没有发布到该操作

解决方案

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

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中使用该名称来调用该操作。

我计划为其他2个实体添加更多Post方法,这些实体将被发送到同一控制器,但我不确定如何告诉我的客户将对象发送到哪个Post操作。嗨@Reza,很抱歉回复太晚,谢谢您的回答。我现在了解了路由,但是我是否需要更改URI或winform应用程序中的任何内容以使用操作3?是的,我将向该控制器发送更多URI,我需要告诉他们使用Action2或Action2Action1Hi@JoshuaMasangcay,不客气:要从winforms应用程序调用多个操作,只需在web api中创建多个操作,并使用合适的url调用它们。例如,要调用SomeController的Action3,请将请求发布到和。同时请记住,最好使用http://localhost:50826 作为一种设置,如果需要,您可以简单地更改url。再次感谢@Reza。我学到了很多。祝你今天愉快!不客气,你也祝你今天愉快。顺便说一句,如果你觉得答案有帮助,你可以欣然接受并投票:
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)
}