Я новичок в ASP.NET MVC4, и у меня есть проблема, которую я не могу решить.
У меня есть простая конечная точка GET, которую я хочу вернуть всем prestations.
Когда я пытаюсь достичь этой конечной точки, я не получаю ответа и даже тайм-аута. Мой API хорошо работает в других конечных точках.
Вот код внутри метода, относящегося к этой конечной точке:
[Route("api/Prestations")]
// GET: api/Prestations
/// <summary>
/// Liste de toutes les prestations
/// </summary>
/// <returns></returns>
[ResponseType(typeof(List<Prestation>))]
public List<Prestation> GetPrestations()
{
return db.Prestations.ToList();
}
Я просто не понимаю, почему это не работает.
Некоторая помощь будет оценена по достоинству.
Спасибо !
Вы установили точку останова внутри метода? Возможно, получение данных из базы данных занимает ОЧЕНЬ много времени. Сколько строк возвращается?
Удалите строку кода, чтобы получить Prestations, и замените ее на throw new Exception();. Выбрасывается ли исключение?
@Amy Выброшено исключение. Я отредактировал свой пост, чтобы добавить определение маршрута.
Хорошо, это подтверждает, что проблема в EF или в размере данных, которые вы пытаетесь сериализовать. Поэтому отмените изменение исключения, присвойте результат db.Prestations.ToList() переменной, верните эту переменную. Установите точку останова. Вернется ли db.Prestations.ToList() вообще, или это то, где он застопорился?
@Эми Хорошо. Если я назначаю результат переменной и выбрасываю исключение перед точкой возврата, выбрасывается исключение.
Тогда это количество данных, которые вы возвращаете. Это слишком много. Возвращать меньше данных.
Как я могу это сделать, пожалуйста? Должен ли я вернуть только половину моего списка в этом методе и создать второй метод, который возвращает этот список предварительных станций из середины?
У вас есть разные варианты. Есть ли у Prestation подобъекты, свисающие с него? Один из вариантов — удалить несущественные данные или дочерние объекты. Другой вариант — использовать пейджинг.
Да, у Prestation есть подобъекты. Подскажите, пожалуйста, как удалить их из списка?
Я имею в виду из db.Prestations.ToList() ?





Согласно этой статье Обработка больших строковых значений JSON в .NET и предотвращение исключений вы можете попытаться увеличить размер строки JSON, которую вы возвращаете, изменив файл web.config:
<configuration>
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization maxJsonLength = "86753090" />
</webServices>
</scripting>
</system.web.extensions>
</configuration>
Также вы можете попытаться сериализовать результат с помощью Newtonsoft.Json и вернуть как контент, чтобы увидеть, работает ли он.
[ResponseType(typeof(List<Prestation>))]
public ActionResult GetPrestations()
{
var presentations = db.Prestations.ToList();
return Content(JsonConvert.Seriazlize(presentations), "application/json");
}
Но в общем случае вы бы не хотели возвращать клиенту данные из всей таблицы, потому что она может быть огромной и содержать миллионы записей. Таким образом, вы бы предпочли реализовать разбиение на страницы:
[ResponseType(typeof(List<Prestation>))]
public List<Prestation> GetPrestations(int skip = 0, int take = 100)
{
return db.Prestations.OrderBy(p => p.IdPrestation).Skip(skip).Take(take).ToList();
}
Спасибо за этот полный ответ :)
Однако, если я реализую разбиение на страницы, должен ли я запрашивать свою конечную точку с добавлением параметров пропуска и взятия в URL?
@PierrickMartellière, да, вы запрашиваете первую партию, скажем, из 100 элементов, затем запрашиваете следующие 100, пропуская 100 и беря следующие 100 и так далее. Также не забудьте отсортировать элементы по идентификатору, чтобы обеспечить последовательный порядок. AFAIR в EF 6.x требуется определить порядок сортировки для таких запросов.
Наконец-то я рассмотрел решение, мне пришлось создать ViewModel, чтобы вернуть список, и указать только имя предварительной станции и идентификатор.
Вот мой недавно созданный класс:
public class PrestationResultNormal
{
public List<ItemPrestation> prestations;
public PrestationResultNormal(List<Prestation> prestations)
{
this.prestations = prestations.Select(x => new ItemPrestation()
{
IdPrestation = x.IdPrestation,
NomPrestation = x.NomPrestation
}).ToList();
}
}
Спасибо за помощь ! :)
и теперь в моем методе я делаю:
var prestations = db.Prestations.ToList();
return new PrestationResultNormal(prestations);
Я думаю, что это всего лишь сложный обходной путь, который решает вашу проблему. Было бы неплохо, если бы вы могли прикрепить скриншот, показывающий содержимое сети при выполнении запроса, чтобы увидеть детали запроса к API. Если вы используете Chrome, вы можете просто нажать F12, чтобы открыть инструменты разработчика, а затем открыть вкладку «Сеть», затем отправить запрос на свой API и сделать снимок экрана.
Я думаю, что это должно работать:
[System.Web.Http.HttpGet]
[System.Web.Http.ActionName(nameof(GetPrestations))]
public HttpResponseMessage GetPrestations()
{
// var result db.Prestations.ToList();
var result = new List<Prestations>()
{
new Prestations(){
IdPrestation = 3,
NomPrestation = "blah1"
},
new Prestations(){
IdPrestation = 4,
NomPrestation = "blah2"
}
};
return Request.CreateResponse(HttpStatusCode.OK, result);
}
public class Prestations
{
public int IdPrestation { get; set; }
public string NomPrestation { get; set; }
}
Если приведенный выше код работает для вас, попробуйте раскомментировать var result db.Prestations.ToList(); и использовать вместо него. Обе вещи должны работать.
Если данные огромны и загрузка не работает, удалите .ToList() из возврата db.Prestations.ToList(); в качестве возврата db.Prestations;, это позволит избежать выполнения загрузки данных как отсрочки во время цикла в представлении (если вы используете эту модель в представлении).
Вы настроили маршрут для этого действия? Пожалуйста, покажите полный класс контроллера