Как исправить ошибку «ERR_ABORTED 400 (Bad Request)» с помощью вызова Jquery к службе C # WCF? - PullRequest
0 голосов
/ 03 июля 2019

Я создал простой сервис C # WCF, который возвращает строку с HTML-кодом.Когда я использую этот сервис с простым проектом MVC внутри решения WCF, все работает нормально.

  • Сервисный код
    public class ConnectorService : IConnectorService
    {
        public string GetData()
        {
            return "<a href='www.test.com.br'>test</a>";
        }
    }
  • Код интерфейса
    [ServiceContract]
    public interface IConnectorService
    {
        [OperationContract]
        string GetData();
    }

После этого теста я опубликовал эту службу в своем локальном IIS и попытался использовать эту службу с помощью html-страницы, которая не находится в решении WCF, но находится в том же каталоге IIS службы.

  • HTML-код
    <html>
        <head>
        <title>test</title>
        <script src='Scripts/jquery-3.3.1.min.js'></script>
        </head>
    <body>
        <div id='divContent'></div>
    </body>
    </html>

    <script type='text/javascript'>
        $(document).ready(function () {

            $.ajax({
                url: 'http://localhost/ConnectorService.svc/GetData',
                contentType: 'application/json; charset=utf-8',
                type: "GET",
                dataType: 'jsonp',
            success: function (data) {
                $('#divContent').html(data); 
            },
            error: function (error) {
                alert("error:  status - " + error.status + " | text: " + error.statusText);
            }
        });

    });
    </script>

Когда я открываю этот HTML-файл в браузере, я получаю 2 ошибки:

1) Политика CORS - iисправлено это с файлом global.asax, подобным этому

protected void Application_BeginRequest(object sender, EventArgs e)
    {
        if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
        {
            HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
            HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
            HttpContext.Current.Response.End();
        }
    }

2) Ошибка 400 - неправильный запрос Я попробовал несколько решений переполнения стека, как правило, с изменениями в моем вызове ajax, файлах global.asax и web.config,но я всегда получаю неверную ошибку запроса внутри консоли Chrome.

  • код web.config
        <?xml version="1.0"?>
    <configuration>

      <appSettings>
        <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
      </appSettings>
      <system.web>
        <compilation debug="true" targetFramework="4.7.2" />
        <httpRuntime targetFramework="4.7.2"/>
      </system.web>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
              <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
              <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
              <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <protocolMapping>
          <add binding="basicHttpsBinding" scheme="https" />
        </protocolMapping>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
      </system.serviceModel>
      <system.webServer>

        <httpProtocol>
          <customHeaders>
            <add name="Access-Control-Allow-Origin" value="*" />
            <add name="Access-Control-Allow-Credentials" value="true" />
            <add name="Access-Control-Allow-Headers" value="Content-Type,Accept" />
            <add name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS" />
          </customHeaders>
        </httpProtocol>

        <modules runAllManagedModulesForAllRequests="true"/>
        <!--
            To browse web app root directory during debugging, set the value below to true.
            Set to false before deployment to avoid disclosing web app folder information.
          -->
        <directoryBrowse enabled="true"/>
      </system.webServer>

    </configuration>

Я считаю, что это простая проблема с простым решением, нопосле нескольких дней испытаний я чувствую, что яв погоне за собственным хвостомКто-нибудь может подсказать мне решение для этого?

Заранее спасибо.

1 Ответ

1 голос
/ 04 июля 2019

Что-то не так с вызовом.Обычно мы вызываем типичную службу WCF, используя прокси-класс клиента, вместо прямой отправки http-запроса.

$.ajax({
            url: 'http://localhost/ConnectorService.svc/GetData',
            contentType: 'application/json; charset=utf-8',
            type: "GET",
            dataType: 'jsonp',
        success: function (data) {
            $('#divContent').html(data); 
        },
        error: function (error) {
            alert("error:  status - " + error.status + " | text: " + error.statusText);
        }

Этот стиль вызова службы путем прямой отправки http-запроса обычно применяется к службе Restful Style.пожалуйста, обратитесь к ссылке ниже.
https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design
И Asp.net WebAPI, и WCF могут создать службу стиля Restful.
https://docs.microsoft.com/en-us/aspnet/web-api/
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/wcf-web-http-programming-model-overview
На основе вашего примерамы могли бы изменить службу WCF на стиль Restful, а затем вызвать ее, отправив запрос http напрямую.
Interface.

        [ServiceContract]
        public interface IService1
        {
            [OperationContract]
            [WebGet(RequestFormat =WebMessageFormat.Json,ResponseFormat =WebMessageFormat.Json)]                    
            string GetData(int value);

    }

Служба.

public class Service1 : IService1
{

    public string GetData(int value)
    {
        return "<a href='www.test.com.br'>test</a>";
    }
}

Web.config

  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpsGetEnabled="true" httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior>
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
    <protocolMapping>
      <add scheme="http" binding="webHttpBinding"/>
    </protocolMapping>
  </system.serviceModel>

Результат (доступ к URL с вводом адреса в браузереHttp Получить запрос).
enter image description here
В качестве альтернативы, мы вызываем его, отправляя запрос Ajax.

$.ajax({
    method:"Get",
    url: "http://10.157.13.69:11000/Service1.svc/GetData?value=34",
    contentType:"application/json"
}).done(function(data){
    console.log(data);
})

Не стесняйтесь сообщить мне, если естьЯ могу помочь с чем угодно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...