微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ASP.NET Google Signin:传入的消息具有意外的消息格式“原始”

如何解决ASP.NET Google Signin:传入的消息具有意外的消息格式“原始”

我正在尝试使用此页面实施 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 开发者控制台中的 [General] 选项卡检查了请求:

一般

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

响应标头

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

请求标头

: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

但是服务器返回如下错误

传入的消息具有意外的消息格式“原始”。操作的预期消息格式是“Xml”; '杰森'。这可能是因为尚未在绑定上配置 WebContentTypeMapper。有关详细信息,请参阅 WebContentTypeMapper 的文档。

完全错误

服务器在处理请求时遇到错误。请参阅服务帮助页面以构建对服务的有效请求。异常消息是“传入的消息具有意外的消息格式“原始”。操作的预期消息格式是“Xml”; '杰森'。这可能是因为尚未在绑定上配置 WebContentTypeMapper。有关更多详细信息,请参阅 WebContentTypeMapper 的文档。'。有关更多详细信息,请参阅服务器日志。异常堆栈跟踪是:

在 System.ServiceModel.dispatcher.Demultiplexingdispatchmessageformatter.DeserializeRequest(Message message,Object[] parameters) 在 System.ServiceModel.dispatcher.UriTemplatedispatchFormatter.DeserializeRequest(Message message,Object[] parameters) 在 System.ServiceModel.dispatcher.dispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc) 在 System.ServiceModel.dispatcher.dispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) 在 System.ServiceModel.dispatcher.ImmutabledispatchRuntime.ProcessMessage5(MessageRpc& rpc) 在 System.ServiceModel.dispatcher.ImmutabledispatchRuntime.ProcessMessage11(MessageRpc& rpc) 在 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, 但后来我得到了错误

'RequestFormat' 未声明。由于其保护级别,它可能无法访问。

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 检查资源可用性时,我看到了这个页面

enter image description here

我已经检查过了:

更新 1

我尝试通过 JSON 而不是表单发布,但随后出现错误

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&amp; rpc)
   at System.ServiceModel.dispatcher.dispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)
   at System.ServiceModel.dispatcher.ImmutabledispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)
   at System.ServiceModel.dispatcher.ImmutabledispatchRuntime.ProcessMessage11(MessageRpc&amp; 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));

如果您坚持将数据作为表单发布,请查看此答案。 https://stackoverflow.com/a/6329148/5964792

更新 1 根据您的更新,您的服务器接受 JSON 请求,但无法将其反序列化为 System.String,因为您正在发布一个对象。要将字符串作为 JSON 发送,试试这个

var xhr = new XMLHttpRequest();
xhr.open('POST','application/json'); // because we are sending json 

xhr.send(JSON.stringify(id_token));

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。