Ошибка в службе WCF, размещенной в службе приложений Azure: ошибка HTTP 405.0 - метод не разрешен - PullRequest
0 голосов
/ 18 апреля 2019

Хорошо, здесь совсем новичок в WCF, поэтому наберитесь терпения, пожалуйста.

У меня есть веб-служба WCF, опубликованная в службе приложений Azure, и приложение Xamarin.forms, которое должно подключаться к службе.

Я создал службу WCF, сначала я попытался выполнить ее самостоятельно и создал клиент в своем приложении xamarin с помощью Visual Studio 2017 «Добавить службу».Поэтому он добавил файл Reference.cs, и я создал прокси-класс и интерфейс для подключения к службе, а что нет.

У меня были проблемы с подключением к службе с мобильного телефона, поэтому я опубликовал службув службе приложений Azure (в конце концов, она бесплатна), включила журналы Azure, изменила файл NLog.config для записи в трассировку, изменила только URL в моем мобильном приложении, и теперь служба выдает его каждый раз, когда я пытаюсь подключиться к немусо своего мобильного телефона:

Ошибка HTTP 405.0 - метод не разрешен. Не удается отобразить страницу, которую вы ищете, поскольку используется недопустимый метод (глагол HTTP).

Я читаю ошибку в облачном обозревателе Visual Studio в папке LogFiles\DetailedErrors.

Честно говоря, я почти ничего не знаю о HTTP, но я знаю, что не написал HTTP в службе.Я предполагаю, что WCF использует это и использует неправильный глагол в некоторый момент, в некотором месте, но как я должен знать, где изменить это или даже как проверить это?Я только что создал интерфейс, класс и вызвал методы этого класса ... не знаю, где искать POST или GET.

В любом случае, я даже не уверен, какой код я должен публиковать здесь,но я прочитал множество вопросов по этому поводу, поэтому вот некоторые из них:

Класс обслуживания

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

Интерфейс

[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>

То есть.

По сути, я потратил больше недели на изучение и попытки сделать это, сейчас я очень расстроен и понятия не имею, что происходит, поэтому ЛЮБАЯ помощь будет принята с благодарностьювключая простое «эй, ты ничего не знаешь! ты должен прочитать это <include here link I shoud read>!».


Редактировать: Хорошо, из-за указаний Махлатсе я пробовал парувещи.

До того, как я пытался получить доступ к сервису через https://mjrffacturascomunidadeswebservice.azurewebsites.net/, появляется сообщение с надписью Your App Service app is up and running, поэтому я подумал, что все в порядке, но когда я попытался добавить к этому файл SVCURL, он выдал исключение при запросе сеанса, но с использованием basicHTTPbinding, который не поддерживает сеансы.

Я удалил оба параметра режима сеанса из атрибута интерфейса [ServiceContract(SessionMode = SessionMode.Required)] и FirstMethod иLastMethod методов, и исключение исчезло.Теперь, если посмотреть на https://mjrffacturascomunidadeswebservice.azurewebsites.net/MJRFFrasCdadesService.svc, там написано You have created a service., а что нет, поэтому я полагаю, что СЕЙЧАС оно действительно работает и работает ... поэтому я попытался проверить его в своем приложении, и оно выдает следующее:

            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 ;

Это другая ошибка (я думаю, по крайней мере, это прогресс).Как вы можете видеть, метод GoogleLoginAsync генерирует это исключение, но теперь это метод моего приложения, который его генерирует, а не сервис: ServiceReference1.MJRFFrasCdadesServiceClient - это класс, сгенерированный Visual Studio, когда я добавил ссылку на сервис, когда я был все еще самостоятельнохостинг службы.

Я думаю, что собираюсь удалить эту ссылку, добавить новую в службу, размещенную в Azure, и снова протестировать все это.


Edit2:

И да, это решило эту проблему, но теперь у меня есть такая:

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 Один за другим.Хорошо, я не уверен, стоит ли мне продолжать задавать этот вопрос в том же вопросе, поскольку первоначальная проблема решена, поэтому я принимаю ответ и продолжаю пытаться или открывать новый вопрос.

1 Ответ

1 голос
/ 18 апреля 2019

Вот несколько вещей, которые вы можете попробовать

  1. Проверьте, запущена ли служба (достаточно просмотра файла .svc)
  2. Проверьте, являются ли контракты на обслуживанието же самое, это будут файлы WSDL (проверьте, все ли методы одинаковы (что более важно, если ваш метод существует)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...