如果我传递序列化的 json 数据,它会出现在 http 请求中的啥位置?
Posted
技术标签:
【中文标题】如果我传递序列化的 json 数据,它会出现在 http 请求中的啥位置?【英文标题】:If i pass serialized json data, where does that appear in the http request?如果我传递序列化的 json 数据,它会出现在 http 请求中的什么位置? 【发布时间】:2021-08-12 06:18:14 【问题描述】:我正在尝试这样做:将 http 验证令牌插入到序列化的 JSON 数据中。我已经有能力在 JSON 中正常传递它,也可以使用自定义授权扩展在标头中传递它。我想做的是,在验证器中,如果请求不在标头数据或表单数据中,则反序列化传递的数据并在那里查看。我实际上无法在请求中找到数据。当我读取传递的数据(84 字节)时,我得到了一堆数字。
这是防伪验证器:
namespace DispatchCrude.Extensions
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,
AllowMultiple = false, Inherited = true)]
public sealed class ValidateHeaderAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
public void OnAuthorization(AuthorizationContext filterContext)
if (filterContext == null)
throw new ArgumentNullException("filterContext");
var httpContext = filterContext.HttpContext;
var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName];
//try header first
var token = httpContext.Request.Headers["__RequestVerificationToken"];
//try normal method
if (token == null)
for(int cl = 0; cl < httpContext.Request.Form.Keys.Count; cl++)
if (httpContext.Request.Form.Keys[cl] == "__RequestVerificationToken")
token = httpContext.Request.Form[httpContext.Request.Form.Keys[cl]];
if (token == null)
//this section isn't finding the passed data
//get here if form stringified
System.IO.Stream str; String strmContents;
Int32 counter, strLen, strRead;
// Create a Stream object.
str = httpContext.Request.InputStream;
// Find number of bytes in stream.
strLen = Convert.ToInt32(str.Length);
// Create a byte array.
byte[] strArr = new byte[strLen];
// Read stream into byte array.
strRead = str.Read(strArr, 0, strLen);
// Convert byte array to a text string.
strmContents = "";
for (counter = 0; counter < strLen; counter++)
strmContents = strmContents + strArr[counter].ToString();
token = strmContents; //just so i can debug the returned token
//if both fail, attempt to check stringified data for matching token.
AntiForgery.Validate(cookie != null ? cookie.Value : null, token);
下面是我们序列化表单数据的一些示例代码:
$.ajax(
type: "POST",
headers: appendVerificationToken(),
url: "/OrderSettlement/SessionApplyRatesCancel",
data: JSON.stringify( key: data.key ),
contentType: "application/json",
success: function ()
/* decided to NOT close the window (just cancel and show the [CANCELLED] description)
// on success, close the owning popup
runFuncByNameSingleParameter(_owningPopup.Close);
*/
);
正如我所说,在标头中传递它是可行的,但我希望能够将它添加到数据中,但我在解析它的请求中找不到它。
【问题讨论】:
由于您提交请求的方式,JSON 构成了请求的整个正文。它不是表单编码的数据。您可以通过多种方式获得该身体。一种方法(虽然不一定是最好的)是string requestBody = await httpRequest.Content.ReadAsStringAsync();
。
我会尝试这样阅读,看看我是否能得到一个好的结果,谢谢。
虽然我无法像您发布的那样阅读它(这是一个注释,所以我认为我不能使其异步)并且它内置在 filtercontext 中,您关于它成为整个请求的信息很好足以让我找到正确的解决方案。这有效:使用 (var reader = new StreamReader(httpContext.Request.InputStream)) json = reader.ReadToEnd();
如果您发布某种答案,我会接受。与此同时,我要留下一个“占位符”的答案。
【参考方案1】:
感谢Ouroborus,我能够想出一个解决方案。 这有效:
string json;
var position = httpContext.Request.InputStream.Position;
using (var reader = new StreamReader(httpContext.Request.InputStream, Encoding.UTF8, false, 8192, true))
json = reader.ReadToEnd();
//you MUST reset the input stream to start or you will break post.
httpContext.Request.InputStream.Seek(position, SeekOrigin.Begin);
try
var jsonObj = Json.Decode(json); //attempt to parse into json object.
token = jsonObj["__RequestVerificationToken"];
catch
//eat the parse errors. That simply means it's not json.
我希望它可以帮助别人。请注意,您必须将流重置为零,这正是我正在做的,否则控制器函数将不会接收任何传递的数据。
【讨论】:
以上是关于如果我传递序列化的 json 数据,它会出现在 http 请求中的啥位置?的主要内容,如果未能解决你的问题,请参考以下文章
JSON.net 直接从 oledbconnection 序列化