Пользовательский контроллер Azure / API .Net backend
У меня запущен MobileService в Azure, и я решил создать новый сервис и перенести код самостоятельно. Новый сервис нового типа называется: служба мобильных приложений Azure.
В настоящее время у меня работает Аутентификация, и я могу выполнять миграцию / обновление базы данных. Я следую примеру TodoItem. Теперь я хочу создать свой собственный пользовательский API, который легко работает на MobileService, но я не могу заставить его работать в мобильном приложении Azure:/
Я перешел по этим двум ссылкам web-Api-routing и app-service-mobile-backend. И теперь у меня есть следующее:
Я создал новый контроллер:
[MobileAppController]
public class TestController : ApiController
{
// GET api/Test
[Route("api/Test/completeAll")]
[HttpPost]
public async Task<ihttpactionresult> completeAll(string info)
{
return Ok(info + info + info);
}
}
В mobileApp.cs я добавил следующий код в соответствии с бэкэндом:
HttpConfiguration config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
Дополнительно я установил следующий пакет в соответствии с web-api-routing:
Microsoft.AspNet.WebApi.WebHost
и звонок от клиента:
string t = await App.MobileService.InvokeApiAsync<string,string>("Test/completeAll", "hej");
Отладка показывает, что это правильный URL:
{Метод: POST, RequestUri: ' https://xxxxxxx.azurewebsites.net/api/Test/completeAll', версия: 1.1, содержимое: System.Net.Http.StringContent, заголовки:{ X-ZUMO-FEATURES: AT X-ZUMO-INSTALLATION-ID: e9b359df-d15e-4119-a4ad-afe3031d8cd5 X-ZUMO-AUTH: xxxxxxxxxxx Принять: application/json Пользовательский агент: ZUMO/2.0 Пользовательский агент: (lang= Управляемый; os= Магазин Windows; os_version=-; arch= Нейтральный; версия =2.0.31125.0) X-ZUMO-ВЕРСИЯ: ZUMO/2.0 (lang= Управляемый; os= Магазин Windows; os_version=-; arch= Нейтральный; версия =2.0.31125.0) ZUMO-API-версия: 2.0.0 Content-Type: application/json; charset=utf-8 Content-Length: 3}}
Но продолжайте получать: 404 (Не найдено) Сообщение об отладке "Запрос не может быть выполнен. (Не найден)"
Что мне не хватает:/?
Обновить
Я попытался расширить код в The mobileApp.cs, с помощью:
HttpConfiguration config = new HttpConfiguration();
new MobileAppConfiguration()
.UseDefaultConfiguration().MapApiControllers()
.ApplyTo(config);
config.MapHttpAttributeRoutes();
app.UseWebApi(config);
основанный на app-service-backend, но по-прежнему нет доступа:/
Обновить
Я использовал fiddler2 для доступа к конечной точке через браузер и получил следующие результаты:
Обновить снова
Я пытался создать другое минимальное решение, но все равно получаю ту же ошибку. Есть ли какие-нибудь замечательные учебники, которым я могу следовать, чтобы достичь этой функциональности?
Позитивное чувство медленно испаряется.,,
Вопрос также работает сейчас на MSDN, я буду обновлять здесь, если там отображается какая-либо информация.
Обновить
Протестированный комментарий Линды, и я могу получить доступ к конвертеру значений:
// Use the MobileAppController attribute for each ApiController you want to use
// from your mobile clients
[MobileAppController]
public class ValuesController : ApiController
{
// GET api/values
public string Get()
{
MobileAppSettingsDictionary settings = this.Configuration.GetMobileAppSettingsProvider().GetMobileAppSettings();
ITraceWriter traceWriter = this.Configuration.Services.GetTraceWriter();
string host = settings.HostName ?? "localhost";
string greeting = "Hello from " + host;
traceWriter.Info(greeting);
return greeting;
}
// POST api/values
public string Post()
{
return "Hello World!";
}
}
Это я получаю с помощью функции post и get:
string t = await App.MobileService.InvokeApiAsync<string, string>("values", null, HttpMethod.Post, null);
или же
string t = await App.MobileService.InvokeApiAsync<string, string>("values", null, HttpMethod.Get, null);
Но код, который я вставил, не имеет маршрута, так почему я могу получить к нему доступ, используя значения? Каким был бы путь к исходному контроллеру, если бы не использовался параметр маршрута?
Дополнительная информация
Теперь я создал заявку в службу поддержки Microsoft и обновлю ее дополнительной информацией.,, С надеждой.
Обновить информацию с форума MSDN: попробуйте MS_SkipVersionCheck Читая об атрибуте здесь, он не представляется применимым. Но я попробовал это. Еще Not Found
для моего API, но оригинальный все еще работает. Так что это не повлияло на эту проблему.
5 ответов
Да!!!
Итак, я наконец-то начал работать, я скопировал данные из lidydonna - msft git и прочитал о .net backend для мобильного сервиса.
Это закончилось следующим:
using System.Web.Http;
using Microsoft.Azure.Mobile.Server.Config;
using System.Threading.Tasks;
using System.Web.Http.Tracing;
using Microsoft.Azure.Mobile.Server;
namespace BCMobileAppService.Controllers
{
[MobileAppController]
public class TestController : ApiController
{
// GET api/Test
[HttpGet, Route("api/Test/completeAll")]
public string Get()
{
MobileAppSettingsDictionary settings = this.Configuration.GetMobileAppSettingsProvider().GetMobileAppSettings();
ITraceWriter traceWriter = this.Configuration.Services.GetTraceWriter();
string host = settings.HostName ?? "localhost";
string greeting = "Hello from " + host;
traceWriter.Info(greeting);
return greeting;
}
// POST api/values
[HttpPost, Route("api/Test/completeAll")]
public string Post(string hej)
{
string retVal = "Hello World!" + hej;
return retVal;
}
}
}
Это новый контроллер, а не тот, который поставляется с ним, как используется lidydonna. Казалось, что он хочет обе функции get
а также post
, Это привело к тому, что API был зарегистрирован и может быть доступен. Это означает, что клиентский вызов на сервер, который я использовал, был:
t = await App.MobileService.InvokeApiAsync<string, string>("Test/completeAll", null, HttpMethod.Post, new Dictionary<string, string>() { { "hej", " AWESOME !" }});
dialog = new MessageDialog(t);
dialog.Commands.Add(new UICommand("OK"));
await dialog.ShowAsync();
И я получил ответ YAY!
Дополнительная информация
Контроллеры, которые вы создаете, т.е. класс должен заканчиваться Controller
Вы можете иметь текст до, но не после. Эта информация была предоставлена на форуме MSDN.
Если post
и get
имеет тот же вход, который возвращает сервер Not found
, Наличие разных входов решает проблему.
В случае странного Internal Server Error
то есть странно, что вы можете пройти весь код сервера, все переменные, которые вы хотите вернуть, инициализированы, но клиент получает ошибку. Затем обратитесь к разделу "Внутренняя ошибка сервера" - пользовательский контроллер службы приложений Azure, где можно решить проблему с помощью простого исправления конфигурации.
У вас должно быть что-то не так в конфигурации вашего проекта. У меня есть рабочий образец здесь: https://gist.github.com/lindydonna/6fca7f689ee72ac9cd20
После создания HttpConfiguration
объект, вызов config.MapHttpAttributeRoutes()
, Я добавил атрибут маршрута [Route("api/Test/completeAll")]
и я могу подтвердить, что маршрут зарегистрирован правильно.
Попробуйте добавить этот атрибут в ValuesController и проверьте маршрут.
Я нашел другую причину для 404 ошибок, когда дело дошло до использования атрибутной маршрутизации.
Код выше изначально имел это в mobileApp.cs:
HttpConfiguration config = new HttpConfiguration();
new MobileAppConfiguration()
.UseDefaultConfiguration().MapApiControllers()
.ApplyTo(config);
config.MapHttpAttributeRoutes();
app.UseWebApi(config);
Config.MapHttpAttributeRoutes() должен быть перемещен над.ApplyTo:
HttpConfiguration config = new HttpConfiguration();
config.MapHttpAttributeRoutes();
new MobileAppConfiguration()
.UseDefaultConfiguration().MapApiControllers()
.ApplyTo(config);
Попробуйте переключить наследование с ApiController на TableController.
Это действительно странно, но простой запрос API не работает в службе приложений Azure. Поэтому я нашел решение, которое сработало для меня. Я протестировал http-запросы с помощью C# http post / get, android post / get и цели C post / get. Прежде всего, вам необходимо обновить класс Startup.MobileApp.cs:
new MobileAppConfiguration()
.UseDefaultConfiguration()
.MapApiControllers() /* /api endpoints **missing part***/
.ApplyTo(config);
Затем создайте пользовательский контроллер мобильного приложения Azure. После этого немного измените ваш контроллер, чтобы получить правильный ответ JSON
public class Mes
{
public string message { get; set; }
}
// GET api/My
public Mes Get()
{
return new Mes { message = "thanks" };
// return "Hello from custom controller!";
}
// POST api/My
public Mes Post(Mes chal)
{
return new Mes { message = chal.message + "asnwer" };
// return "Hello from custom controller!";
}
}
Вы можете просто оставить первый вариант и получить ответ, но OBjective C скажет вам, что текст JSON не начинался с массива или объекта и опции для разрешения фрагментов... и т. Д. Это происходит потому, что вы получаете простую строку, а не объект. Вот почему я изменил свой ответ с классом Mes, но это также зависит от того, как вы делаете запрос и какой тип объекта вы ожидаете. Поэтому.MapApiControllers() - это основной ключ для API, а контроллер WEB API теперь заменен на пользовательский Azure. Надеюсь это поможет.