ASP.NET Google 登录:传入消息具有意外的消息格式 'Raw'
ASP.NET Google Signin: The incoming message has an unexpected message format 'Raw'
我正在尝试使用此页面实现 Google 登录:https://developers.google.com/identity/sign-in/web/backend-auth
我的令牌验证调用是:
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://www.example.com/api/gtokensignin');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function () {
console.log('Signed in as: ' + xhr.responseText);
};
xhr.send('idtoken=' + id_token);
我通过 Chrome 开发人员控制台中的 [常规] 选项卡检查了请求:
一般
Request URL: https://www.example.com/api/gtokensignin
Request Method: POST
Status Code: 400
Remote Address: 192.168.178.219:443
Referrer Policy: strict-origin-when-cross-origin
回复headers
cache-control: private
content-length: 2903
content-type: text/html
date: Thu, 01 Jul 2021 13:23:35 GMT
server: Microsoft-IIS/10.0
x-aspnet-version: 4.0.30319
x-powered-by: ASP.NET
请求headers
:authority: www.example.com
:method: POST
:path: /api/gtokensignin
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
content-length: 1220
content-type: application/x-www-form-urlencoded
cookie: ASP.NET_SessionId=ptesmo1fxwfcgv2cple6xdzi; G_ENABLED_IDPS=google; G_AUTHUSER_H=0; _ga=GA1.1.1295181445.1624434076; __gads=ID=a5e2262ee1a99a43-23e99f1715c900bb:T=1624434076:RT=1624434076:S=ALNI_MZMMJEkUKSKcUUh9w9uH8_Z84lLAQ; _ga_MLNSQWJ4J5=GS1.1.1625123053.36.0.1625123053.0
dnt: 1
origin: https://www.example.com
referer: https://www.example.com/test2.aspx
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
sec-ch-ua-mobile: ?0
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-origin
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36
表单数据
idtoken: eyJhbGciOiJSUzI2NiIsImtpZCI6IjExMmU0YjUyYWI4MzMwMTdkMzg1Y2UwZDBiNGM2MDU4N2VkMjU4NDIiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXpwIjoiOTU1MjU1MDgxOTEwLWpkcWticDQzNWo1azBnampvZGYzNmZuODEzODZ2ZnFzLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiOTU1MjU1MDgxOTEwLWpkcWticDQzNWo1azBnampvZGYzNmZuODEzODZ2ZnFzLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwic3ViIjoiMTE3NzYzNjQ1MjYxMDUxNjAzODgxIiwiZW1haWwiOiJmbG9yYW5mZWxlbkBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXRfaGFzaCI6ImdEM0pQc3EyVnJLZlZNenAzbkpJYWciLCJuYW1lIjoiRmxvcmFuIEZlbGVuIiwicGljdHVyZSI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hL0FBVFhBSnhFMzdPMlJFRjJfLVozeVVZV1A2c1Z1Ylcta2I2TGgzSGNZWEpINnc9czk2LWMiLCJnaXZlbl9uYW1lIjoiRmxvcmFuIiwiZmFtaWx5X25hbWUiOiJGZWxlbiIsImxvY2FsZSI6ImVuIiwiaWF0IjoxNjI1MTY3MjM4LCJleHAiOjE2MjUxNzA4MzgsImp0aSI6ImMwMjgxYWE0YTE1NTBiZWY1ZDJlOTZhOWQwY2Y5ZTU1NTY1MjA1NGEifQ.S_ubEh_4IYhQTPVSye0-tma7pfhAu9xLOoKG5SoO08ZXhqpRxcvJu5C1E6luL9I-LYVLhUNHmplmtR0JJmg47x2lqFH_vwEEGmbhfdEBrEoCXShktxbfLu1p9WcK6MUFMZFT0q93Zp2PgPIfXp_caqqxMeAGEZfzWMK9ZmZhMfmTX_Ny2KlO4KJHR-FvY9Rv1XrcTrTiWfTclKFqpIvyWaUR-wk4srWpu1-riH5J9lz-VC-nmQAbWZw0kxD2DK0RjqsbeXJvPrrtjiCURM-s2b4tfvtyADRkgF2Nh9oOlsMJZRxKXoGNYsLoR0iYYcGbQm4NZGzVwmPj3pxtf1htEA
但是,服务器returns出现如下错误:
The incoming message has an unexpected message format 'Raw'. The expected message formats for the operation are 'Xml'; 'Json'. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details.
完整错误:
The server encountered an error processing the request. Please see the service help page for constructing valid requests to the service. The exception message is 'The incoming message has an unexpected message format 'Raw'. The expected message formats for the operation are 'Xml'; 'Json'. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details.'. See server logs for more details. The exception stack trace is:
at System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
Iapi.vb
<OperationContract()>
<Web.WebInvoke(Method:="POST", ResponseFormat:=Web.WebMessageFormat.Json, BodyStyle:=Web.WebMessageBodyStyle.Bare,
UriTemplate:="gtokensignin")>
Function gtokensignin(ByVal str As String) As Stream
我最初在上面的代码中有 BodyStyle:=Web.WebMessageBodyStyle.WrappedRequest
。
我还尝试在 OperationContract()
中将 BodyStyle=
更改为 BodyStyle=WebMessageBodyStyle.Wrapped
,但会引发相同的错误。
我还尝试将签名更改为:
<Web.WebInvoke(Method:="POST", RequestFormat = WebMessageFormat.Json, ResponseFormat:=Web.WebMessageFormat.Json, BodyStyle:=Web.WebMessageBodyStyle.Bare,
但后来我得到了错误
'RequestFormat' is not declared. It may be inaccessible due to its protection level.
web.config
<services>
<service behaviorConfiguration="ServiceBehaviour" name="Mysite.api">
<endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="Binding" contract="Mysite.Iapi" />
<endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="httpbind" contract="Mysite.Iapi" />
</service>
</services>
当我通过 https://www.example.com/api.svc/help/operations/gtokensignin 检查资源可用性时,我看到了这个页面:
我已经检查过:
- WCF service error - Incoming message has an unexpected message format 'Raw'. Expected message formats are 'Xml', 'Json'
- WCF request: "The incoming message has an unexpected message format 'Raw'. The expected message formats for the operation are 'Xml'; 'Json'"
更新 1
我尝试 post 通过 JSON 而不是表单 post,但我得到了错误:
The server encountered an error processing the request. Please see the <a rel="help-page" href="https://www.example.com/api.svc/help">service help page</a> for constructing valid requests to the service. The exception message is 'There was an error deserializing the object of type System.String. End element 'root' from namespace '' expected. Found element 'idtoken' from namespace ''.'. See server logs for more details. The exception stack trace is:
at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName)
at System.ServiceModel.Dispatcher.SingleBodyParameterDataContractMessageFormatter.ReadObject(Message message)
at System.ServiceModel.Dispatcher.SingleBodyParameterMessageFormatter.DeserializeRequest(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</p>
基于服务器错误。它只接受 JSON 或 XML。
所以尝试像这样将 id_token 作为 JSON 发送。
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://www.example.com/api/gtokensignin');
xhr.setRequestHeader('Content-Type', 'application/json'); // because we are sending json
const data = {
"idtoken": id_token,
};
xhr.send(JSON.stringify(data));
如果您坚持以表单形式发送数据 post 请查看此答案。
更新 1
根据您的更新,您的服务器接受了 JSON 请求,但无法将其反序列化为 System.String,因为您正在 posting 一个对象。要将字符串作为 JSON 发送,试试这个
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://www.example.com/api/gtokensignin');
xhr.setRequestHeader('Content-Type', 'application/json'); // because we are sending json
xhr.send(JSON.stringify(id_token));
我正在尝试使用此页面实现 Google 登录:https://developers.google.com/identity/sign-in/web/backend-auth 我的令牌验证调用是:
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://www.example.com/api/gtokensignin');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function () {
console.log('Signed in as: ' + xhr.responseText);
};
xhr.send('idtoken=' + id_token);
我通过 Chrome 开发人员控制台中的 [常规] 选项卡检查了请求:
一般
Request URL: https://www.example.com/api/gtokensignin
Request Method: POST
Status Code: 400
Remote Address: 192.168.178.219:443
Referrer Policy: strict-origin-when-cross-origin
回复headers
cache-control: private
content-length: 2903
content-type: text/html
date: Thu, 01 Jul 2021 13:23:35 GMT
server: Microsoft-IIS/10.0
x-aspnet-version: 4.0.30319
x-powered-by: ASP.NET
请求headers
:authority: www.example.com
:method: POST
:path: /api/gtokensignin
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
content-length: 1220
content-type: application/x-www-form-urlencoded
cookie: ASP.NET_SessionId=ptesmo1fxwfcgv2cple6xdzi; G_ENABLED_IDPS=google; G_AUTHUSER_H=0; _ga=GA1.1.1295181445.1624434076; __gads=ID=a5e2262ee1a99a43-23e99f1715c900bb:T=1624434076:RT=1624434076:S=ALNI_MZMMJEkUKSKcUUh9w9uH8_Z84lLAQ; _ga_MLNSQWJ4J5=GS1.1.1625123053.36.0.1625123053.0
dnt: 1
origin: https://www.example.com
referer: https://www.example.com/test2.aspx
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"
sec-ch-ua-mobile: ?0
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-origin
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36
表单数据
idtoken: eyJhbGciOiJSUzI2NiIsImtpZCI6IjExMmU0YjUyYWI4MzMwMTdkMzg1Y2UwZDBiNGM2MDU4N2VkMjU4NDIiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXpwIjoiOTU1MjU1MDgxOTEwLWpkcWticDQzNWo1azBnampvZGYzNmZuODEzODZ2ZnFzLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiOTU1MjU1MDgxOTEwLWpkcWticDQzNWo1azBnampvZGYzNmZuODEzODZ2ZnFzLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwic3ViIjoiMTE3NzYzNjQ1MjYxMDUxNjAzODgxIiwiZW1haWwiOiJmbG9yYW5mZWxlbkBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXRfaGFzaCI6ImdEM0pQc3EyVnJLZlZNenAzbkpJYWciLCJuYW1lIjoiRmxvcmFuIEZlbGVuIiwicGljdHVyZSI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hL0FBVFhBSnhFMzdPMlJFRjJfLVozeVVZV1A2c1Z1Ylcta2I2TGgzSGNZWEpINnc9czk2LWMiLCJnaXZlbl9uYW1lIjoiRmxvcmFuIiwiZmFtaWx5X25hbWUiOiJGZWxlbiIsImxvY2FsZSI6ImVuIiwiaWF0IjoxNjI1MTY3MjM4LCJleHAiOjE2MjUxNzA4MzgsImp0aSI6ImMwMjgxYWE0YTE1NTBiZWY1ZDJlOTZhOWQwY2Y5ZTU1NTY1MjA1NGEifQ.S_ubEh_4IYhQTPVSye0-tma7pfhAu9xLOoKG5SoO08ZXhqpRxcvJu5C1E6luL9I-LYVLhUNHmplmtR0JJmg47x2lqFH_vwEEGmbhfdEBrEoCXShktxbfLu1p9WcK6MUFMZFT0q93Zp2PgPIfXp_caqqxMeAGEZfzWMK9ZmZhMfmTX_Ny2KlO4KJHR-FvY9Rv1XrcTrTiWfTclKFqpIvyWaUR-wk4srWpu1-riH5J9lz-VC-nmQAbWZw0kxD2DK0RjqsbeXJvPrrtjiCURM-s2b4tfvtyADRkgF2Nh9oOlsMJZRxKXoGNYsLoR0iYYcGbQm4NZGzVwmPj3pxtf1htEA
但是,服务器returns出现如下错误:
The incoming message has an unexpected message format 'Raw'. The expected message formats for the operation are 'Xml'; 'Json'. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details.
完整错误:
The server encountered an error processing the request. Please see the service help page for constructing valid requests to the service. The exception message is 'The incoming message has an unexpected message format 'Raw'. The expected message formats for the operation are 'Xml'; 'Json'. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details.'. See server logs for more details. The exception stack trace is:
at System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object[] parameters) at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
Iapi.vb
<OperationContract()>
<Web.WebInvoke(Method:="POST", ResponseFormat:=Web.WebMessageFormat.Json, BodyStyle:=Web.WebMessageBodyStyle.Bare,
UriTemplate:="gtokensignin")>
Function gtokensignin(ByVal str As String) As Stream
我最初在上面的代码中有 BodyStyle:=Web.WebMessageBodyStyle.WrappedRequest
。
我还尝试在 OperationContract()
中将 BodyStyle=
更改为 BodyStyle=WebMessageBodyStyle.Wrapped
,但会引发相同的错误。
我还尝试将签名更改为:
<Web.WebInvoke(Method:="POST", RequestFormat = WebMessageFormat.Json, ResponseFormat:=Web.WebMessageFormat.Json, BodyStyle:=Web.WebMessageBodyStyle.Bare,
但后来我得到了错误
'RequestFormat' is not declared. It may be inaccessible due to its protection level.
web.config
<services>
<service behaviorConfiguration="ServiceBehaviour" name="Mysite.api">
<endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="Binding" contract="Mysite.Iapi" />
<endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" bindingConfiguration="httpbind" contract="Mysite.Iapi" />
</service>
</services>
当我通过 https://www.example.com/api.svc/help/operations/gtokensignin 检查资源可用性时,我看到了这个页面:
我已经检查过:
- WCF service error - Incoming message has an unexpected message format 'Raw'. Expected message formats are 'Xml', 'Json'
- WCF request: "The incoming message has an unexpected message format 'Raw'. The expected message formats for the operation are 'Xml'; 'Json'"
更新 1
我尝试 post 通过 JSON 而不是表单 post,但我得到了错误:
The server encountered an error processing the request. Please see the <a rel="help-page" href="https://www.example.com/api.svc/help">service help page</a> for constructing valid requests to the service. The exception message is 'There was an error deserializing the object of type System.String. End element 'root' from namespace '' expected. Found element 'idtoken' from namespace ''.'. See server logs for more details. The exception stack trace is:
at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.Json.DataContractJsonSerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName)
at System.ServiceModel.Dispatcher.SingleBodyParameterDataContractMessageFormatter.ReadObject(Message message)
at System.ServiceModel.Dispatcher.SingleBodyParameterMessageFormatter.DeserializeRequest(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</p>
基于服务器错误。它只接受 JSON 或 XML。 所以尝试像这样将 id_token 作为 JSON 发送。
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://www.example.com/api/gtokensignin');
xhr.setRequestHeader('Content-Type', 'application/json'); // because we are sending json
const data = {
"idtoken": id_token,
};
xhr.send(JSON.stringify(data));
如果您坚持以表单形式发送数据 post 请查看此答案。
更新 1 根据您的更新,您的服务器接受了 JSON 请求,但无法将其反序列化为 System.String,因为您正在 posting 一个对象。要将字符串作为 JSON 发送,试试这个
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://www.example.com/api/gtokensignin');
xhr.setRequestHeader('Content-Type', 'application/json'); // because we are sending json
xhr.send(JSON.stringify(id_token));