Веб-API 2: передовая практика возврата данных ViewModel из контроллера в результат $http Успех?

Интересно, какой рекомендуемый способ обработки данных (ViewModels) в Web Api 2. Я довольно много гуглил и нашел несколько «рецептов», но мне интересно, какой самый гибкий и простой способ справиться с этим.

Этот вызов возвращает ошибку -->

GET http://localhost:63203/api/Gallery/GetPhotosForPage 404 (Not Found)

наверное из-за какой-то ошибки в подписи..,.

Вот вызов $http (Angular):

var currPage = $location.path() || "Unknown"; 

$http({
    method: 'GET',
    url: '/api/Gallery/GetPhotosForPage',
    accept: 'application/json',
    data: JSON.stringify(currPage)   //currpage = ex. "/leftwing"
    })
        .success(function (result) {
            console.log(result);
            $scope.mystuff= result;
        });

Вот метод GET контроллера: /PriPhotosModel - модель представления...

[HttpGet]
    public object GetPhotosForPage(string currPage)
    {
        PhotoServices photoService = new PhotoServices();
        List<PriPhotosModel> priPhotos = photoService.GetPriPhotosForAllPhotographersOnPage(currPage);
        return Request.CreateResponse(HttpStatusCode.OK, priPhotos);
    }

person Terje Nygård    schedule 29.08.2014    source источник


Ответы (1)


Обратите внимание, что WebApi работает на основе отражения, это означает, что ваши фигурные скобки {vars} должны совпадать с одним и тем же именем в ваших методах.

Поэтому, чтобы сопоставить образец URL-адреса, такой как api/gallery/test, на основе шаблона по умолчанию "api/{controller}/{id}", ваш метод должен быть объявлен следующим образом:

[HttpGet]
public object GetPhotosForPage(string id){
   return id;
}

Где параметр string currPage был заменен на string id.

Причина в том, что маршрутизация по умолчанию объявляет параметр с именем id :

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

Web Api v1 определяет ресурсы глобально в global.asax в событии application_start. Предполагая, что вы используете Visual Studio 2013 и шаблон по умолчанию на основе Microsoft, ваш метод может выглядеть следующим образом:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}

Конфигурация маршрутизации WebApi происходит в WebApiConfig.Register, а конфигурация MVC — в RouteConfig.RegisterRoutes.

Что касается WebApi v2, в котором появилось что-то под названием Атрибуты маршрута, их можно использовать вместе с вашим классом контроллера и упростить настройку маршрутизации.

Например:

 public class BookController : ApiController{
     //where author is a letter(a-Z) with a minimum of 5 character and 10 max.      
    [Route("sample/{id}/{newAuthor:alpha:length(5,10)}")]
    public Book Get(int id, string newAuthor){
        return new Book() { Title = "SQL Server 2012 id= " + id, Author = "Adrian & " + newAuthor };
    }

   [Route("otherUrl/{id}/{newAuthor:alpha:length(5,10)}/{title}")]
   public Book Get(int id, string newAuthor, string title){
       return new Book() { Title = "SQL Server 2012 id= " + id, Author = "Adrian & " + newAuthor };
   }
...
person Dalorzo    schedule 29.08.2014
comment
Вау!.. Большое спасибо за ваш очень подробный и понятный ответ Далорзо :) Это дало мне краткое представление о некоторых вещах, которые мне еще предстоит узнать о маршрутизации и тому подобном... но... мне также интересно, как бы вы отправили параметры от клиента (вызов $http) в метод контроллера, как наилучшая практика, если у вас есть строка или int или что-то еще, что вы хотите отправить в метод GET на сервере. Причина.. общедоступный объект GetPhotosForPage (string currPage) должен называться только так, верно? --› URL: '/api/Gallery/GetPhotosForPage', с данными: currPage (string) ? ' - person Terje Nygård; 29.08.2014
comment
если вы используете свойство из Javascript Ajax, это означает, что это, скорее всего, вызов метода Post, тогда ваш метод в WebApi также должен быть помечен как метод [HttpPost], и один из ваших параметров будет [FromBody] - person Dalorzo; 29.08.2014
comment
Ах! В этом может быть хитрость :) все еще возможно вернуть модель представления, я думаю? :) - person Terje Nygård; 29.08.2014
comment
Из вашего примера выше я не вижу причин, почему бы и нет. - person Dalorzo; 29.08.2014