Azure自定义控制器/ API .Net后端

时间:2016-03-01 08:31:46

标签: c# asp.net azure azure-api-apps azure-mobile-services

我在Azure上运行了一个MobileService,并决定创建一个新服务并自己迁移代码。新服务属于新类型:Azure Mobile App Service。

目前我正在使用身份验证,并且可以执行迁移/更新数据库。我正在关注TodoItem示例。我现在想要创建自己的Custom API,它可以轻松地在MobileService上运行,但我无法在Azure Mobile App上运行它:/

我已经关注了这两个链接web-Api-routingapp-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中,我根据backend添加了以下代码:

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:   在X-ZUMO-INSTALLATION-ID:e9b359df-d15e-4119-a4ad-afe3031d8cd5 X-ZUMO-AUTH:   xxxxxxxxxxx接受:application / json User-Agent:   ZUMO / 2.0 User-Agent:(lang = Managed; os = Windows Store; os_version = - ; arch = Neutral; version = 2.0.31125.0)     X-ZUMO-VERSION:ZUMO / 2.0(lang = Managed; os = Windows Store; os_version = - ; arch = Neutral; version = 2.0.31125.0)     ZUMO-API-VERSION:2.0.0 Content-Type:application / json; charset = utf-8 Content-Length:3}}

但继续得到:404(未找到) 调试消息“请求无法完成。(未找到)”

我缺少什么:/?

更新

我尝试使用:

扩展mobileApp.cs中的代码
HttpConfiguration config = new HttpConfiguration();
        new MobileAppConfiguration()
            .UseDefaultConfiguration().MapApiControllers()
            .ApplyTo(config);
        config.MapHttpAttributeRoutes();
        app.UseWebApi(config);

基于app-service-backend,但仍无法访问:/

更新

我使用fiddler2通过浏览器访问端点并得到以下结果:

Fiddler output

再次更新

我试图创建另一个最小解决方案,但仍然得到相同的错误。我可以遵循哪些很棒的教程来实现这个功能吗?

积极的感觉正在慢慢蒸发。 。 。

问题现在也在msdn上运行,如果有任何信息,我会在这里更新。

更新

测试过Lindas评论,我实际上可以访问值转换器:

// 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);

但我粘贴的代码没有路由,为什么我可以使用值访问它?如果没有使用route参数,那么原始控制器的路径是什么?

额外信息

我现在已经与Microsoft创建了一个支持服务单,并将更新其他信息。 。 。希望。

更新 来自MSDN论坛的信息:尝试MS_SkipVersionCheck 阅读属性here,它似乎不适用。但我试过了。我的API仍然是Not Found,但原始的仍在使用。所以它对这个问题没有影响。

5 个答案:

答案 0 :(得分:15)

是的!!!

所以我终于搞定了,我复制了lidydonna的使用 - msft git并阅读了.net backend for mobileservice

以下结尾:

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一样随附的控制器。似乎它需要函数getpost。这导致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();

我得到了一个回应!

额外信息

您创建的控制器,即类需要以Controller结尾,您可以在之前但不在之后拥有文本。此信息在MSDN forum discussion上提供。

如果postget具有相同的输入,则服务器返回Not found。有不同的输入解决了这个问题。

如果是奇怪的Internal Server Error,即很奇怪,您可以单步执行整个服务器代码,所有要返回的变量都会被初始化,但客户端会收到错误。然后参考Internal Server Error - Azure App Service Custom Controller,其中对配置的简单修复可以解决问题。

答案 1 :(得分:5)

您的项目配置中必定有问题。我在这里有一个工作样本:https://gist.github.com/lindydonna/6fca7f689ee72ac9cd20

创建HttpConfiguration对象后,请致电config.MapHttpAttributeRoutes()。我添加了路由属性[Route("api/Test/completeAll")],我可以确认路由已正确注册。

尝试将此属性添加到ValuesController并检查路由。

答案 2 :(得分:2)

在使用属性路由时,我发现了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);

答案 3 :(得分:1)

尝试从ApiController切换到TableController。

答案 4 :(得分:1)

这真的很奇怪,但简单的API请求在azure app服务中无效 所以我找出了对我有用的解决方案。我用c#http post / get,android post / get和Objective C post / get测试了http请求 首先,您需要更新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自定义控制器。 希望这可以帮助。