由Azure应用服务托管的WCF服务中的错误:HTTP错误405.0-不允许的方法 [英] Error in WCF service hosted with Azure app service: HTTP Error 405.0 - Method Not Allowed

查看:120
本文介绍了由Azure应用服务托管的WCF服务中的错误:HTTP错误405.0-不允许的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,这里完全是WCF的新手,请耐心等待。



我在Azure应用服务上发布了WCF Web服务,还拥有Xamarin。表单应用程序必须连接到该服务。



我提供了WCF服务,起初我尝试对其进行自我托管,并通过使用visual studio 2017添加服务。因此,它添加了 Reference.cs 文件,然后我创建了代理类和接口以连接到服务,而没有连接到该服务。



我无法从移动设备连接到服务,因此我在Azure应用服务上发布了该服务(毕竟它是免费的),启用了Azure日志,修改了 NLog.config 文件记录到跟踪中,仅修改了我的移动应用程序中的URL,现在每次我尝试从移动设备连接到该服务时,该服务都会抛出该错误:



HTTP错误405.0-不允许使用方法。由于使用了无效的方法(HTTP动词),因此无法显示正在查找的页面。



我正在Visual Studio的Cloud Explorer中的 LogFiles\DetailedErrors 文件夹中读取错误。



老实说,我对HTTP几乎一无所知,但是我知道我没有在服务中编写HTTP。我想WCF使用它,并且在某个地方的某个时刻使用了错误的动词,但是我应该如何知道在哪里更改它,甚至如何检查它呢?我只是做了一个接口,一个类,然后在该类上调用方法……不知道在哪里寻找POST或GET。



无论如何,我不是即使可以确定应该在此处发布什么代码,但是我已经阅读了很多有关此问题,所以这里是其中的一些内容:



服务类 >

 公共类MJRFFrasCdadesService:IMJRFFrasCdadesService,IDisposable 
{
private Users.UsersClass _Users =新用户。 UsersClass();
私有静态NLog.Logger _Logger = NLog.LogManager.GetCurrentClassLogger();
私人布尔_已处置;

公共静态事件EventHandler< ConnectionEventArgs> ConnectionEvent;
公共静态事件EventHandler< ConnectionEventArgs> DisconnectionEvent;

公共字符串Ping()
{
返回确定;
}

公共异步任务< string> GoogleLoginAsync(字符串电子邮件)
{
NLog.LogManager.Configuration.Variables [ email] =;
_Logger.Info( {1} {2} {1} Comienza google login con电子邮件:{0} {1} {2},
电子邮件,
Environment.NewLine,
----------------------------------- *********** ************************************);

var driveHandler =等待_Users.NewUserAsync(email);

试试
{
var init = await driveHandler.InitDriveAsync(email);
_Logger.Info( InitDriveAsync finalizado con resultado:{0},init);
if(!init ||!driveHandler.LoginOK)
{
_Logger.Info( Devolviendo mensaje de error:{0},driveHandler.MsgError);
return driveHandler.MsgError;
}
_Logger.Info(登录成功,devolviendo \确定);
返回确定;
}
捕获(异常e)
{
_Logger.Error(e);
return e.ExceptionErrorMessage();
}
}

公共异步任务< string> UploadFileAsync(byte [] fileBytes,字符串fileName,字符串电子邮件)
{
_Logger.Info( Comienza subida de fichero con nombre {0},fileName);

var driveHandler =等待_Users.GetUserDriveHandler(email);
if(driveHandler == null)
{
_Logger.Info(无日志。Devolviendo do用户未登录);
返回用户未登录;
}

尝试
{
if(!driveHandler.LoginOK)
{
_Logger.Info(无日志。Devolviendo \ 未记录\);
返回未记录;
}

var result = await driveHandler.UploadImageAsync(fileBytes,fileName);
_Logger.Info( Proceso de subida terminado。Resultado:{0},结果);
if(!result)
{
_Logger.Info( Devolviendo mensaje de error:{0},driveHandler.MsgError);
return driveHandler.MsgError;
}
_Logger.Info( Subida ok,devolviendo \ Ok\);
返回确定;
}
捕获(异常e)
{
_Logger.Error(e);
return e.ExceptionErrorMessage();
}
}

public void Dispose()
{
if(!_Disposed)
{
_Users.Dispose( );
}
_Disposed = true;
}

public void FirstMethod()
{
if(ConnectionEvent!= null)
{
string m = Alguien se ha conectado;
ConnectionEvent(null,new ConnectionEventArgs()
{
Message = m
});
_Logger.Info(m);
}
}

public void LastMethod()
{
if(DisconnectionEvent!= null)
{
字符串m = Alguien se ha desconectado;
DisconnectionEvent(null,new ConnectionEventArgs()
{
Message = m
});
_Logger.Info(m);
}
}
}






接口

  [ServiceContract(SessionMode = SessionMode.Required)] 
公共接口IMJRFFrasCdadesService
{
[OperationContract]
字符串Ping();

[OperationContract]
Task< string> GoogleLoginAsync(字符串电子邮件);

[OperationContract]
Task< string> UploadFileAsync(byte [] fileBytes,字符串fileName,字符串email);

[OperationContract(IsInitiating = true)]
void FirstMethod();

[OperationContract(IsTerminate = true)]
void LastMethod();
}






Web。 config

 <?xml version = 1.0 encoding = utf-8?> 
< configuration>

< appSettings>
< add key = aspnet:UseTaskFriendlySynchronizationContext value = true />
< / appSettings>
< system.web>
< compilation debug = true targetFramework = 4.7.1 />
< httpRuntime targetFramework = 4.7.1 />
< /system.web>
< system.serviceModel>
<行为>
< serviceBehaviors>
<行为>
<!-错误的履历表-实施条件的虚假信息->
< serviceMetadata httpGetEnabled = true httpsGetEnabled = true />
< ;!-准个人身份证明书,正确的事实证明,真实的事实证明。在任何情况下均不得透露任何证据,实施工具的伪造->
< serviceDebug includeExceptionDetailInFaults = true />
< / behavior>
< / serviceBehaviors>
< / behaviors>
< protocolMapping>
< add binding = basicHttpsBinding scheme = https />
< / protocolMapping>
< serviceHostingEnvironment aspNetCompatibilityEnabled = true multipleSiteBindingsEnabled = true />
< /system.serviceModel>
< system.webServer>
< modules runAllManagedModulesForAllRequests = true />
< ;!-
真实性,您可以在dablee ladepuración网站上查看自己的导演。
在网络上发布虚假的实施行为信息。
->
< directoryBrowse enabled = true />
< /system.webServer>

< / configuration>






就是这样。



基本上,我花了一个多星期的时间学习并尝试执行此操作,现在我非常沮丧,不知道发生了什么,所以 ANY 的帮助将不胜感激,其中包括一个简单的嘿,您一无所知!您必须阅读此<在此处包含我应该阅读的链接> !。 / p>




编辑:
好​​的,由于Mahlatse的指示,我尝试了一对



在我尝试通过 https://mjrffacturascomunidadeswebservice.azurewebsites.net/ ,出现消息说您的App Service应用已启动并正在运行,所以我认为一切正常,但是当我尝试将svc文件附加到该URL时,它引发了关于询问会话的异常,但使用了不支持会话的 basicHTTPbinding



我删除了b在接口属性 [ServiceContract(SessionMode = SessionMode.Required)] FirstMethod 中,以及 LastMethod 方法,该异常消失了。现在,如果浏览到 https://mjrffacturascomunidadeswebservice.azurewebsites.net/MJRFFrasCdadesService.svca>说您已经创建了一个服务。,但还没有,所以我想现在它已经真正启动并运行了……所以我尝试在我的应用程序中对其进行测试,并抛出以下错误:

 错误:
处理Web请求时出错:状态码405(MethodNotAllowed):不允许使用方法;

跟踪:
在(包装器托管到本机)System.Object。__icall_wrapper_mono_remoting_wrapper(intptr,intptr)
在(包装器远程调用)ServiceReference1.IMJRFFrasCdadesService.GoogleLoginAsync(字符串)
在ServiceReference1.MJRFFrasCdadesServiceClient.GoogleLoginAsync(System.String电子邮件)[0x00006]在< 61e2d5b4688b450c9b2865fbef0c9da1>:0
在MJRFFacturasComunidades.Model.WebService.WebServiced& [0x00023]在< 61e2d5b4688b450c9b2865fbef0c9da1>:0中;

这是一个不同的错误(我想至少是一个进步)。如您所见,方法 GoogleLoginAsync 引发了该异常,但现在是我的应用程序方法引发了该异常,而不是服务: ServiceReference1.MJRFFrasCdadesServiceClient 是我仍在自托管服务时添加服务引用时Visual Studio生成的类。



我想我要删除该引用,向azure托管的服务中添加一个新引用,然后再次测试所有这些。






Edit2 :



是的,它解决了这个问题,但是现在我有了这个:

 反序列化 GoogleLogin操作的请求消息正文时出错。 OperationFormatter遇到无效的消息正文。预期会找到名称为 GoogleLogin且名称空间为 http://tempuri.org/的节点类型元素。找到名称为 GoogleLoginAsync和名称空间为 http://tempuri.org/的节点类型元素; 

跟踪:
在(包装器托管到本机)System.Object。__icall_wrapper_mono_remoting_wrapper(intptr,intptr)
在(包装器远程调用)ServiceReference2.IMJRFFrasCdadesService.GoogleLoginAsync(字符串)
在ServiceReference2.MJRFFrasCdadesServiceClient.GoogleLoginAsync(System.String电子邮件)[0x00006]在< e1f3df4dfbf340f09d2768d7fbc33427>:0
在MJRFFacturasComunidades.Model.gt.WebService.WebService [0x00023]在< e1f3df4dfbf340f09d2768d7fbc33427>:0中;

xD一个接一个。好的,我不确定是否应该在同一问题中继续提出此问题,因为原来的问题已解决,因此我接受了答案并继续尝试或提出新的问题。

解决方案

以下是您可以尝试的一些方法


  1. 检查服务是否正在运行(浏览到.svc文件就足够了)

  2. 检查服务合同是否相同,这就是WSDL文件(检查所有方法是否相同(更多)重要的是,如果您的方法存在)


Ok, totally newbie with WCF here, so be patient with me, please.

I have a WCF web service published on Azure app service, and a Xamarin.forms application that must connect to the service.

I made the WCF service, at first I tried to self host it and I made the client on my xamarin app by using the visual studio 2017 "Add service". So it added the Reference.cs file, and I made the proxy class and interface to connect to the service and what not.

I was having problems to connect to the service from the mobile, so I published the service at Azure app service (it's free after all), enabled Azure logs, modified the NLog.config file to log to the trace, modified only the URL in my mobile app, and now the service throws this every time I try to connect to it from my mobile:

HTTP Error 405.0 - Method Not Allowed.The page you are looking for cannot be displayed because an invalid method (HTTP verb) is being used.

I'm reading the error in Visual Studio's Cloud Explorer at LogFiles\DetailedErrors folder.

Honestly, I know almost nothing about HTTP, but I know that I haven't written HTTP in the service. I suppose WCF use it and is using a bad verb at some moment, in some place, but how am I supposed to know where to change it or even how to check it? I just made an interface, a class, and call the methods on that class... no idea where to look for POST or GET.

Anyway, I'm not even sure what code should I post here, but I've read tons of questions about this, so here is some of it:

Service class

public class MJRFFrasCdadesService : IMJRFFrasCdadesService, IDisposable
{
    private Users.UsersClass _Users = new Users.UsersClass();
    private static NLog.Logger _Logger = NLog.LogManager.GetCurrentClassLogger();
    private bool _Disposed;

    public static event EventHandler<ConnectionEventArgs> ConnectionEvent;
    public static event EventHandler<ConnectionEventArgs> DisconnectionEvent;

    public string Ping()
    {
        return "Ok";
    }

    public async Task<string> GoogleLoginAsync(string email)
    {
        NLog.LogManager.Configuration.Variables["email"] = "";
        _Logger.Info("{1}{2}{1}           Comienza google login con email: {0}{1}{2}",
            email,
            Environment.NewLine,
            "-----------------------------------*******************************************");

        var driveHandler = await _Users.NewUserAsync(email);

        try
        {
            var init = await driveHandler.InitDriveAsync(email);
            _Logger.Info("InitDriveAsync finalizado con resultado: {0}", init);
            if (!init || !driveHandler.LoginOK)
            {
                _Logger.Info("Devolviendo mensaje de error: {0}", driveHandler.MsgError);
                return driveHandler.MsgError;
            }
            _Logger.Info("Login ok, devolviendo \"Ok\"");
            return "Ok";
        }
        catch (Exception e)
        {
            _Logger.Error(e);
            return e.ExceptionErrorMessage();
        }
    }

    public async Task<string> UploadFileAsync(byte[] fileBytes, string fileName, string email)
    {
        _Logger.Info("Comienza subida de fichero con nombre {0}", fileName);

        var driveHandler = await _Users.GetUserDriveHandler(email);
        if (driveHandler == null)
        {
            _Logger.Info("No logueado. Devolviendo \"User not logged\"");
            return "User not logged";
        }

        try
        {
            if (!driveHandler.LoginOK)
            {
                _Logger.Info("No logueado. Devolviendo \"Not logged\"");
                return "Not logged";
            }

            var result = await driveHandler.UploadImageAsync(fileBytes, fileName);
            _Logger.Info("Proceso de subida terminado. Resultado: {0}", result);
            if (!result)
            {
                _Logger.Info("Devolviendo mensaje de error: {0}", driveHandler.MsgError);
                return driveHandler.MsgError;
            }
            _Logger.Info("Subida ok, devolviendo \"Ok\"");
            return "OK";
        }
        catch (Exception e)
        {
            _Logger.Error(e);
            return e.ExceptionErrorMessage();
        }
    }

    public void Dispose()
    {
        if (!_Disposed)
        {
            _Users.Dispose();
        }
        _Disposed = true;
    }

    public void FirstMethod()
    {
        if (ConnectionEvent != null)
        {
            string m = "Alguien se ha conectado";
            ConnectionEvent(null, new ConnectionEventArgs()
            {
                Message = m
            });
            _Logger.Info(m);
        }
    }

    public void LastMethod()
    {
        if (DisconnectionEvent != null)
        {
            string m = "Alguien se ha desconectado";
            DisconnectionEvent(null, new ConnectionEventArgs()
            {
                Message = m
            });
            _Logger.Info(m);
        }
    }
}


Interface

[ServiceContract(SessionMode = SessionMode.Required)]
public interface IMJRFFrasCdadesService
{
    [OperationContract]
    string Ping();

    [OperationContract]
    Task<string> GoogleLoginAsync(string email);

    [OperationContract]
    Task<string> UploadFileAsync(byte[] fileBytes, string fileName, string email);

    [OperationContract(IsInitiating = true)]
    void FirstMethod();

    [OperationContract(IsTerminating = true)]
    void LastMethod();
}


Web.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.7.1" />
    <httpRuntime targetFramework="4.7.1"/>
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- Para evitar revelar información de los metadatos, establezca los valores siguientes en false antes de la implementación  -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- Para recibir detalles de las excepciones en los fallos, con el fin de poder realizar la depuración, establezca el valor         siguiente en true. Para no revelar información sobre las excepciones, establézcalo en false antes de la implementación -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>    
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        Para examinar el directorio raíz de la aplicación web durante la depuración, establezca el valor siguiente en true.
        Establézcalo en false antes de la implementación para evitar revelar información sobre la carpeta de aplicación web.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>

</configuration>


That is.

Basically, I've spent more than a week learning and trying to do this, right now I'm super frustrated and I have no idea what's happening, so ANY help would be appreciated, including a simple "hey you know nothing! you must read this <include here link I shoud read>!".


Edit: Ok, due to Mahlatse indications I've tried a pair of things.

Before I was trying to access the service through https://mjrffacturascomunidadeswebservice.azurewebsites.net/ , there appears a message saying Your App Service app is up and running, so I thought everything was ok, but when I tried appending the svc file to that URL, it throwed an exception about asking to a session but using basicHTTPbinding which doesn't support sessions.

I removed both, the session mode parameter from the interface's attribute [ServiceContract(SessionMode = SessionMode.Required)] and the FirstMethod and LastMethod methods, and the exception dissappeared. Now if one browse to https://mjrffacturascomunidadeswebservice.azurewebsites.net/MJRFFrasCdadesService.svc , it says You have created a service. and what not, so I suppose NOW it's truly up and running... so I tried to test it at my app and it throws this:

            Error: 
There was an error on processing web request: Status code 405(MethodNotAllowed): Method Not Allowed ;

            Trace: 
at (wrapper managed-to-native) System.Object.__icall_wrapper_mono_remoting_wrapper(intptr,intptr)
at (wrapper remoting-invoke) ServiceReference1.IMJRFFrasCdadesService.GoogleLoginAsync(string)
at ServiceReference1.MJRFFrasCdadesServiceClient.GoogleLoginAsync (System.String email) [0x00006] in <61e2d5b4688b450c9b2865fbef0c9da1>:0 
at MJRFFacturasComunidades.Model.WebService.WebServiceClass+<LogEmail>d__6.MoveNext () [0x00023] in <61e2d5b4688b450c9b2865fbef0c9da1>:0 ;

That's a different error (I suppose at least it's a progress). As you can see the method GoogleLoginAsync is throwing that exception, but now is my app method who is throwing it, not the service: ServiceReference1.MJRFFrasCdadesServiceClient is the class generated by Visual Studio when I added the service reference when I was still self hosting the service.

I think I'm going to remove that reference, add a new one to the service hosted in azure and test again all this.


Edit2:

And yes, it solved that problem, but now I have this one:

Error in deserializing body of request message for operation 'GoogleLogin'. OperationFormatter encountered an invalid Message body. Expected to find node type 'Element' with name 'GoogleLogin' and namespace 'http://tempuri.org/'. Found node type 'Element' with name 'GoogleLoginAsync' and namespace 'http://tempuri.org/' ;

            Trace: 
at (wrapper managed-to-native) System.Object.__icall_wrapper_mono_remoting_wrapper(intptr,intptr)
at (wrapper remoting-invoke) ServiceReference2.IMJRFFrasCdadesService.GoogleLoginAsync(string)
at ServiceReference2.MJRFFrasCdadesServiceClient.GoogleLoginAsync (System.String email) [0x00006] in <e1f3df4dfbf340f09d2768d7fbc33427>:0 
at MJRFFacturasComunidades.Model.WebService.WebServiceClass+<LogEmail>d__6.MoveNext () [0x00023] in <e1f3df4dfbf340f09d2768d7fbc33427>:0  ;

xD One after another. Ok, I'm not sure if I should keep asking this in the same question, since the original problem is solved, therefore I'm accepting the answer and keep trying or opening a new question.

解决方案

Here are a few things you can try

  1. Check if the service is running(browsing to the .svc file should be enough)
  2. Check if the service contracts are the same, this would be the WSDL files( check if all the methods are the same(more importantly if your method exists)

这篇关于由Azure应用服务托管的WCF服务中的错误:HTTP错误405.0-不允许的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆