WebAPI возвращает «Недостаточно стека для продолжения безопасного выполнения программы». - PullRequest
0 голосов
/ 23 февраля 2019

У меня относительно простой REST API, реализованный в приложении WebApi2 с различными контроллерами, передающими объекты JSON туда и обратно.Это работает довольно хорошо, или я так думал.HTTP-вызовы на сервер поступают из приложения Android с помощью Volley.

Один запрос не удался, по-видимому, на стороне клиента, поэтому я смоделировал его с помощью HTTP-клиента Intellij

Вот как выглядит этот запрос (в формате Intellij).Для чего это стоит, я не думаю, что это имеет значение.Я помещаю это здесь, чтобы показать, что объект не монстр.Я опубликую код объекта, если кто-то думает, что это поможет.

POST http://localhost:1430/api/Bids/
Accept: */*
Cache-Control: no-cache

{"BidText":"1C","Board":2,"Counter":0,"Direction":"E","Erased":false,"Id":0,"RoundNumber":1,"SectionId":1,"TableNumber":1}

При этом я получил сюрприз.Похоже, это какой-то бесконечный цикл, происходящий на стороне сервера, но указанный цикл, по-видимому, отсутствует ни в одном из моего кода.На самом деле, я бы не знал, что сервер вообще получил какой-либо запрос, если бы я не смотрел на него таким образом.Он с радостью вернул HTTP 500 в мое приложение, не удосужившись сообщить мне об этом (кроме того, я хотел бы хотя бы иметь возможность регистрировать это!)

Добавлено пробел для удобства чтения:

{"Сообщение": "Произошла ошибка.",

"ExceptionMessage": "Недостаточно стека для продолжения безопасного выполнения программы. Это может произойти из-за слишком большого количества функций в стеке вызовов или функциив стеке, используя слишком много стека\ r \ n в System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren (метаданные ModelMetadata, BodyModelValidatorContext validationContext, контейнер объектов, IEnumerable 1 validators)\r\n at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, BodyModelValidatorContext validationContext)\r\n at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, BodyModelValidatorContext validationContext, Object container, IEnumerable 1 валидаторы) \ r \ n.Метаданные ModelMetadata, BodyModelValidatorContext validationContext) \ r \ n в System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren (метаданные ModelMetadata, BodyModelValidatorContext validateContext, контейнер объектов, IEnumerable 1 validators)\r\n at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, BodyModelValidatorContext validationContext)\r\n at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, BodyModelValidatorContext validationContext, Object container, IEnumerable 1 валидаторы) \ r \ n в System.Web.H

* * 10 * * 22 ** Я даже не уверен, с чего начать, чтобы выяснить, почему это происходит.

Вот где мои маршруты объявлены

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


    config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = 
Newtonsoft.Json.ReferenceLoopHandling.Ignore;
    config.Formatters.Remove(config.Formatters.XmlFormatter);

    appBuilder.UseWebApi(config);

Метод контроллера, который не делает это:объявлено так:

[HttpPost]
[ResponseType(typeof(Bid))]
public IHttpActionResult PostBid([FromBody] Bid bid)
{

Вероятно, стоит отметить, что объект Bid объявлен в EntityFramework, и это новый объект, который я пытаюсь поместить в базу данных.Этот объект еще не прикреплен к объекту DBContext.

Класс Bid следует.Мне интересно, должен ли я [JSONIgnore] ассоциированные объекты (они уже существуют в базе данных, но не были переданы через соединение http)

    [Table("BiddingData")]
    public class Bid : ObservableObject
    {

        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Key, Column(Order = 0)]
        public int Id { get; set; }

        [Column("Section", Order = 1)]
        public int SectionId { get; set; }

        [Column("Table", Order = 2)]
        public int TableNumber { get; set; }

        [Column("RoundNumber", Order = 3)]
        public int RoundNumber { get; set; }

        [Column("Board", Order = 4)]
        public int Board { get; set; }

        [Column("Counter", Order = 5)]
        [Index("IX_Counter", IsUnique = false)]
        public int Counter { get; set; }

        [Column(Order = 6)]
        public string Direction { get; set; }

        [Column("Bid", Order = 7)]
        public string BidText { get; set; }

        [Column(Order = 8)]
        public DateTime DateLog { get; set; }

        [Column(Order = 9)]
        public DateTime TimeLog { get; set; }

        [Column(Order = 10)]
        public bool Erased { get; set; }

        [NotMapped]
        [JsonIgnore]
        public String ElapsedTime { get; set; }


        [Column(Order = 11)]
        [JsonIgnore]
        public String IpAddress { get; set; }

        public virtual Round Round { get; set; }

        [NotMapped]
        [JsonIgnore]
        public String BidValue
        {
            get
            {
                switch (BidText)
                {
                    case "X":
                    case "XX":
                        return BidText;
                    case "P":
                        return "PASS";
                    default:
                        switch (BidText.Substring(1))
                        {
                            case "N":
                                return BidText.Substring(0, 1) + "N";
                            case "C":
                                return BidText.Substring(0, 1) + "♣";
                            case "D":
                                return BidText.Substring(0, 1) + "♦";
                            case "H":
                                return BidText.Substring(0, 1) + "♥";
                            case "S":
                                return BidText.Substring(0, 1) + "♠";
                            default: return "";
                        }

                }
            }
        }

        [NotMapped]
        [JsonIgnore]
        public Brush ForegroundColor
        {
            get
            {
                Color color;

                switch (BidText)
                {
                    case "X":
                    case "XX":
                    case "P":
                        color = Colors.White;
                        break;
                    default:
                        switch (BidText.Substring(1))
                        {
                            case "C":
                                color = Colors.DarkGreen;
                                break;
                            case "D":
                                color = Colors.Yellow;
                                break;
                            case "H":
                                color = Colors.Red;
                                break;
                            case "S":
                                color = Colors.Blue;
                                break;
                            case "N":
                            default:
                                color = Colors.Black;
                                break;
                        }

                        break;

                }

                return new SolidColorBrush(color);
            }
        }

        [NotMapped]
        [JsonIgnore]
        public Brush BackgroundColor
        {
            get
            {
                switch (BidText)
                {
                    case "X":
                        return new SolidColorBrush(Colors.Blue);
                    case "XX":
                        return new SolidColorBrush(Colors.Red);
                    case "P":
                        return new SolidColorBrush(Colors.Green);
                    default:
                        return new SolidColorBrush(Colors.White);

                }
            }
        }

        [NotMapped]
        [JsonIgnore]
        public String TableString
        {
            get
            {
                if (Round?.Section != null)
                {
                    return Round.Section.Letter.Trim() + "-" + TableNumber;
                }

                return TableNumber.ToString();                
            }

        }

        //TODO i18N
        [NotMapped]
        [JsonIgnore]
        public String BoardString
        {
            get
            {
                if (this.Round != null)
                {
                    return "Round #" + this.RoundNumber + " - Board #" + this.Board + " - " + this.Round.NSPair + " VS " + this.Round.EWPair;
                }                
                else
                {
                    return "Board #" + this.Board;
                }
            }
        } 
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...