【发布时间】:2019-12-05 23:41:50
【问题描述】:
我有一个以这种方式初始化的非常简单的自托管 WCF 应用程序:
Host = new WebServiceHost(this, new Uri(serviceAddress));
var binding = new WebHttpBinding();
binding.ReceiveTimeout = TimeSpan.MaxValue;
binding.MaxReceivedMessageSize = int.MaxValue;
binding.CrossDomainScriptAccessEnabled = true; // TODO: Remove this?
var endpoint = Host.AddServiceEndpoint(typeof(HttpService), binding, "");
Host.Open();
我的 HttpService 类有这个方法:
[OperationContract, WebInvoke(Method = "*")]
public string Evaluate(string query)
{
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
if (WebOperationContext.Current.IncomingRequest.Method == "OPTIONS")
{
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "POST, PUT, DELETE");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Max-Age", "1728000");
return "";
}
else
{
try
{
return "12345";
}
catch (ProcessNotFoundException ex)
{
throw new WebFaultException<string>(ex.Message, System.Net.HttpStatusCode.NotFound);
}
catch (Exception ex)
{
throw new WebFaultException<string>(ex.Message, System.Net.HttpStatusCode.InternalServerError);
}
}
}
我在上面添加了 CORS 内容,以便任何人都可以使用 JavaScript 从任何网站使用此 API。我正在尝试使用fetch 运行一些 POST 请求,因为一旦它起作用,我将传递大量数据,因此 GET 方法将不起作用。从 JavaScript 执行以下操作可以正常工作:
fetch('http://localhost:8001/HeliumScraperService/Evaluate', { method: 'POST', headers: { "Content-Type": 'application/json' }, body: '1232'});
当我这样做时,我的 Evaluate 方法首先使用 OPTIONS 调用,然后使用 POST 调用,并返回一个没有错误的 XML 字符串。以下也有效(注意正文中的引号):
fetch('http://localhost:8001/HeliumScraperService/Evaluate', { method: 'POST', headers: { "Content-Type": 'application/json' }, body: '"hello world"'});
由于两者都是有效的 JSON,我认为任何 JSON 字符串都可以,所以我这样做了,但我收到了 400 Bad Request 错误:
fetch('http://localhost:8001/HeliumScraperService/Evaluate', { method: 'POST', headers: { "Content-Type": 'application/json' }, body: '[10]'});
我认为它可能需要一个可以转换为我的方法参数的 JSON,但这也不起作用(给我一个 400 错误):
fetch('http://localhost:8001/HeliumScraperService/Evaluate', { method: 'POST', headers: { "Content-Type": 'application/json' }, body: JSON.stringify({ query: "hey" })})
所以它可以接受数字和字符串,但没有别的,我不知道为什么。我尝试使用所有这些其他属性组合并得到完全相同的结果:
[OperationContract, WebInvoke(Method = "*", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json)]
[OperationContract, WebInvoke(Method = "*", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json)]
[OperationContract, WebInvoke(Method = "*", BodyStyle = WebMessageBodyStyle.Bare)]
[OperationContract, WebInvoke(Method = "*", BodyStyle = WebMessageBodyStyle.Wrapped)]
我只是希望能够发送任何字符串,而不需要对其进行调查并决定它是好是坏,同时还能够执行上面的 CORS 操作。有没有办法做到这一点?
【问题讨论】:
-
试试
[OperationContract, WebInvoke(Method = "*", RequestFormat = WebMessageFormat.Json)]` ... 虽然我不确定Method = "*"是否有效 -
@JaromandaX 以完全相同的结果进行了尝试。我想我应该得到一个 Stream 而不是一个字符串(见下面我的答案)
标签: javascript c# wcf post