将数据发送到ServiceStack RESTful服务,获取“访问被拒绝”

我使用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以确保安全性):

  Access-Control-Allow-Origin不允许使用选项http://servicedomain.com/citations Origin http://callingdomain.com。

 XMLHttpRequest无法加载http://servicedomain.com//citations。  Access-Control-Allow-Origin不允许使用Origin http://callingdomain.com。 

但我明确允许我的标题中的所有域:

  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获得有效的响应。 这是响应头:

 状态代码:200
日期:2013年9月20日星期五19:54:26 GMT
服务器: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; 字符集= utf-8的
 Access-Control-Allow-Origin:*,*
缓存控制:私有
内容长度:58 

所以我完全迷失了为什么它在纯REST请求中工作,但不是从应用程序?

更新:

在花了很多时间尝试我在网上找到的许多不同的解决方案后,我的配置方法现在看起来像这样:

  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(); container.RegisterAutoWired(); container.RegisterAutoWired(); container.RegisterAutoWired(); using (var getAttributes = container.Resolve()) 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("/attributes", "GET, OPTIONS") .Add("/citations", "POST, GET, OPTIONS, DELETE") .Add("/driver", "POST, OPTIONS") .Add("/vehicle", "POST, OPTIONS") .Add("/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("/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); } }); }