簡體   English   中英

將數據發送到ServiceStack RESTful服務,獲得“訪問被拒絕”

[英]Sending Data to ServiceStack RESTful service, getting 'Access is denied'

我使用ServiceStack構建了RESTful服務,該服務將數據發送到數據庫。 我已經在本地測試過,效果很好。 當我將其部署到服務器並運行相同的代碼(即jQuery $ .ajax調用)時,出現“拒絕訪問”錯誤。 我已經使用插件在ServiceStack配置中設置了CORS,如此處所述 我還在ajax調用中將crossDomain設置為true。 我想不出要怎么做才能使它正常工作,老實說,我不確定在哪里拋出該錯誤。 我已經遍歷了Javascript,它甚至沒有到達ajax調用的“ failure”塊,在此之前引發了錯誤……我正在使用IE9進行測試,是否相關……?

知道會發生什么嗎?

這是我的ServiceStack POST方法:

    public CitationResponse Post(Citation citation)
    {
        var response = new CitationResponse { Accepted = false };

        if (string.IsNullOrEmpty(citation.ReportNumber))
        {
            response.Accepted = false;
            response.Message = "No data sent to service.  Please enter data in first.";
            return response;
        }

        try
        {
            response.ActivityId = Repository.CreateCitation(citation.ReportNumber, citation.ReportNumber_Prefix, citation.ViolationDateTime, citation.AgencyId, citation.Status);
            response.Accepted = true;
        }
        catch (Exception ex)
        {
            response.Accepted = false;
            response.Message = ex.Message;
            response.RmsException = ex;
        }

        return response;
    }

這是調用Web服務的Javascript函數:

   SendCitationToDb: function(citation, callback) {
        $.ajax({
            type: "POST",
            url: Citations.ServiceUrl + "/citations",
            data: JSON.stringify(citation),
            crossDomain: true,
            contentType: "application/json",
            dataType: "json",
            success: function (data) {
                if (!data.Accepted) {
                    Citations.ShowMessage('Citation not added', 'Citation not added to database.  Error was: ' + data.Message, 'error');
                } else {
                    citation.ActivityId = data.ActivityId;
                    callback(data);
                }
            },
            failure: function(errMsg) {
                Citations.ShowMessage('Citation not added', 'Citation not added to database.  Error was: ' + errMsg.Message, 'error');
            }
        });
    }

謝謝你的幫助!

更新:我只是在Chrome 29中運行了同一個應用程序,但遇到了以下錯誤(為安全起見,替換了真實URL):

OPTIONS http://servicedomain.com/citations Origin http://callingdomain.com is not allowed by Access-Control-Allow-Origin.

XMLHttpRequest cannot load http://servicedomain.com//citations. Origin http://callingdomain.com is not allowed by Access-Control-Allow-Origin.

但我顯然允許標題中包含所有域:

            Plugins.Add(new CorsFeature()); //Enable CORS

            SetConfig(new EndpointHostConfig {
                DebugMode = true, 
                AllowJsonpRequests = true,
                WriteErrorsToResponse = true,
                GlobalResponseHeaders =
                {
                    { "Access-Control-Allow-Origin", "*" },
                    { "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS" }
                }
            });

現在,如果我通過Chrome中的REST控制台應用程序運行相同的服務調用,我將收到ServiceStack的有效回復。 這是響應頭:

Status Code: 200
Date: Fri, 20 Sep 2013 19:54:26 GMT
Server: Microsoft-IIS/6.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET, ServiceStack/3.948 Win32NT/.NET
Access-Control-Allow-Methods: POST,GET,OPTIONS, GET, POST, PUT, DELETE, OPTIONS
Content-Type: application/json; charset=utf-8
Access-Control-Allow-Origin: *, *
Cache-Control: private
Content-Length: 58

所以我完全迷失了為什么它可以在純REST請求中工作,而不是在應用程序中工作?

更新:

在花了很多時間嘗試了許多我在網上找到的不同解決方案之后,我的Configure方法現在看起來像這樣:

        public override void Configure(Container container)
        {
            SetConfig(new EndpointHostConfig
            {
                DefaultContentType = ContentType.Json,
                ReturnsInnerException = true,
                DebugMode = true, //Show StackTraces for easier debugging (default auto inferred by Debug/Release builds)
                AllowJsonpRequests = true,
                ServiceName = "SSD Citations Web Service",
                WsdlServiceNamespace = "http://www.servicestack.net/types",
                WriteErrorsToResponse = true,
                GlobalResponseHeaders = 
                { 
                    { "Access-Control-Allow-Origin", "*" },
                    { "Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS" }
                }
            });

            container.RegisterAutoWired<Citation>();
            container.RegisterAutoWired<Driver>();
            container.RegisterAutoWired<Vehicle>();
            container.RegisterAutoWired<Violations>();

            using (var getAttributes = container.Resolve<AttributesService>())
                getAttributes.Get(new AttributesQuery());

            Plugins.Add(new CorsFeature());
            RequestFilters.Add((httpReq, httpRes, requestDto) =>
            {
                httpRes.AddHeader("Access-Control-Allow-Origin", "*");
                httpRes.AddHeader("Access-Control-Allow-Methods", "POST, GET, DELETE, OPTIONS");
                httpRes.AddHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");

                if (httpReq.HttpMethod == "OPTIONS")
                    httpRes.EndServiceStackRequest(); //   extension method
            });

            Routes
              .Add<Attribute>("/attributes", "GET, OPTIONS")
              .Add<Citation>("/citations", "POST, GET, OPTIONS, DELETE")
              .Add<Driver>("/driver", "POST, OPTIONS")
              .Add<Vehicle>("/vehicle", "POST, OPTIONS")
              .Add<Violations>("/violations", "POST, OPTIONS");

            var config = new AppConfig(new ConfigurationResourceManager());
            container.Register(config);
        }
    }

在這一點上,我不確定該怎么辦。 我已經嘗試了所有方法,但是仍然遇到相同的錯誤。 使用Chrome中的REST控制台,這些方法仍然可以正常工作 ,這有點令人生氣,因為我永遠無法讓他們使用它們來從網頁調用它們。 我幾乎准備好用WCF重寫整個過程,但是我真的很想讓ServiceStack版本開始工作,因為我知道它可以在本地工作! 如果有人有其他建議可以嘗試,非常感謝您的幫助!

更新:有關詳細信息,請參見底部的評論。 我必須從IIS的HTTP標頭選項卡中刪除標頭。 不知道何時將它們放進去,但是對於可能遇到相同問題的其他人,這是IIS中選項卡的屏幕截圖:

自定義Http標頭

我有同樣的問題與你,在我以前的問題

您可以在此處此處閱讀#mythz的非常有用的答案。

我在AppHost中使用的代碼

          using System.Web;
          using ServiceStack.WebHost.Endpoints.Extensions;  // for  httpExtensions methods  
    //  => after  v.3.9.60,  =>using ServiceStack;

          public override void Configure(Container container)
          {   

                SetConfig(new ServiceStack.WebHost.Endpoints.EndpointHostConfig
                {
                 DefaultContentType = ContentType.Json,
                  ReturnsInnerException = true,
                  WsdlServiceNamespace = "http://www.servicestack.net/types"
                });

             Plugins.Add(new CorsFeature()); 
             this.RequestFilters.Add((httpReq, httpRes, requestDto) =>
             {
                //Handles Request and closes Responses after emitting global HTTP Headers
                   if (httpReq.HttpMethod == "OPTIONS")
                           httpRes.EndServiceStackRequest();  //httpExtensions method
               //  =>after  v.3.9.60, => httpRes.EndRequestWithNoContent(); 
              });

            Routes
             .Add<TestRequest>("/TestAPI/Reservation", "POST, OPTIONS");   // OPTIONS is mandatory for CORS
          }

和像你一樣的JavaScript

  jQuery.support.cors = true;

    function TestRequestCall() {
       var  TestRequest = new Object();                
           TestRequest.Id = 11111;
           TestRequest.City = "New York";



      $.ajax({
          type: 'Post',
          contentType: 'application/json',         
          url: serverIP +'/TestAPI/Reservation',
          data: JSON.stringify( TestRequest ),
          dataType: "json",
          success: function (TestResponse, status, xhr) {

                 if(TestResponse.Accepted)  doSomething();

           },
           error: function (xhr, err) {
              alert(err);
           }
      });
   }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM