Это сокращение.
!
"не".
--
уменьшает значение.
Таким образом, !--
проверяет, является ли значение, полученное в результате отрицания результата уменьшения значения, ложным.
Попробуйте это:
var x = 2;
console.log(!--x);
console.log(!--x);
Первое значение false, поскольку значение x равно 1, второе значение true, поскольку значение x равно 0.
Примечание: !x--
сначала проверит, является ли x ложным, а затем уменьшит его.
Итак, похоже, ответ - «нет, вы не можете получить необработанные данные, вам нужно восстановить запрос / ответ из свойств проанализированных объектов». Ну что ж, я сделал реконструкцию.
HttpRequest
и HttpResponse
до MVC раньше имели GetInputStream ()
и GetOutputStream ()
, которые могли быть используется для этой цели. Я не рассматривал эти части в MVC, поэтому я не уверен, что они доступны, но это может быть идеей :)
use a IHttpModule:
namespace Intercepts
{
class Interceptor : IHttpModule
{
private readonly InterceptorEngine engine = new InterceptorEngine();
#region IHttpModule Members
void IHttpModule.Dispose()
{
}
void IHttpModule.Init(HttpApplication application)
{
application.EndRequest += new EventHandler(engine.Application_EndRequest);
}
#endregion
}
}
class InterceptorEngine
{
internal void Application_EndRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpResponse response = application.Context.Response;
ProcessResponse(response.OutputStream);
}
private void ProcessResponse(Stream stream)
{
Log("Hello");
StreamReader sr = new StreamReader(stream);
string content = sr.ReadToEnd();
Log(content);
}
private void Log(string line)
{
Debugger.Log(0, null, String.Format("{0}\n", line));
}
}
Согласитесь с FigmentEngine, IHttpModule
, похоже, правильный путь.
Изучите httpworkerrequest
, readentitybody
и GetPreloadedEntityBody
.
Чтобы получить httpworkerrequest
, вам нужно сделать следующее:
(HttpWorkerRequest)inApp.Context.GetType().GetProperty("WorkerRequest", bindingFlags).GetValue(inApp.Context, null);
где inApp
- объект httpapplication.
Я знаю, что это не управляемый код, но я собираюсь предложить фильтр ISAPI. Прошло несколько лет с тех пор, как я имел «удовольствие» поддерживать свой собственный ISAPI, но насколько я помню, вы можете получить доступ ко всему этому материалу как до, так и после того, как ASP.Net сделал это.
http://msdn.microsoft.com/en-us/library/ms524610.aspx
Если HTTPModule недостаточно хорош для того, что вам нужно, я просто не думаю, что есть какой-либо управляемый способ сделать это с необходимым количеством деталей. Хотя это будет больно.
Я согласен с остальными, используйте IHttpModule. Взгляните на ответ на этот вопрос, который делает почти то же самое, что вы задаете. Он регистрирует запрос и ответ, но без заголовков.
Ну, я работаю над проектом и сделал, может быть, не слишком глубокий, log, используя параметры запроса:
Взгляните:
public class LogAttribute : ActionFilterAttribute
{
private void Log(string stageName, RouteData routeData, HttpContextBase httpContext)
{
//Use the request and route data objects to grab your data
string userIP = httpContext.Request.UserHostAddress;
string userName = httpContext.User.Identity.Name;
string reqType = httpContext.Request.RequestType;
string reqData = GetRequestData(httpContext);
string controller = routeData["controller"];
string action = routeData["action"];
//TODO:Save data somewhere
}
//Aux method to grab request data
private string GetRequestData(HttpContextBase context)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < context.Request.QueryString.Count; i++)
{
sb.AppendFormat("Key={0}, Value={1}<br/>", context.Request.QueryString.Keys[i], context.Request.QueryString[i]);
}
for (int i = 0; i < context.Request.Form.Count; i++)
{
sb.AppendFormat("Key={0}, Value={1}<br/>", context.Request.Form.Keys[i], context.Request.Form[i]);
}
return sb.ToString();
}
Вы можете украсить свой класс контроллеров, чтобы записывать его полностью:
[Log]
public class TermoController : Controller {...}
или регистрировать только некоторые отдельные методы действий
[Log]
public ActionResult LoggedAction(){...}
Определенно используйте IHttpModule
и реализуйте события BeginRequest
и EndRequest
.
Все «сырые» данные присутствует между HttpRequest
и HttpResponse
, его просто нет в едином необработанном формате. Вот части, необходимые для создания дампов в стиле Fiddler (примерно настолько близких к необработанному HTTP, насколько это возможно):
request.HttpMethod + " " + request.RawUrl + " " + request.ServerVariables["SERVER_PROTOCOL"]
request.Headers // loop through these "key: value"
request.InputStream // make sure to reset the Position after reading or later reads may fail
Для ответа:
"HTTP/1.1 " + response.Status
response.Headers // loop through these "key: value"
Обратите внимание, что вы не можете прочитать поток ответа , поэтому у вас есть чтобы добавить фильтр в выходной поток и захватить копию.
В вашем BeginRequest
вам нужно будет добавить фильтр ответа:
HttpResponse response = HttpContext.Current.Response;
OutputFilterStream filter = new OutputFilterStream(response.Filter);
response.Filter = filter;
Сохранить фильтр
, где вы можете получить к нему в обработчике EndRequest
. Я предлагаю в HttpContext.Items
. Затем можно получить полные данные ответа в filter.ReadStream ()
.
Затем реализовать OutputFilterStream
, используя шаблон Decorator в качестве оболочки для потока:
/// <summary>
/// A stream which keeps an in-memory copy as it passes the bytes through
/// </summary>
public class OutputFilterStream : Stream
{
private readonly Stream InnerStream;
private readonly MemoryStream CopyStream;
public OutputFilterStream(Stream inner)
{
this.InnerStream = inner;
this.CopyStream = new MemoryStream();
}
public string ReadStream()
{
lock (this.InnerStream)
{
if (this.CopyStream.Length <= 0L ||
!this.CopyStream.CanRead ||
!this.CopyStream.CanSeek)
{
return String.Empty;
}
long pos = this.CopyStream.Position;
this.CopyStream.Position = 0L;
try
{
return new StreamReader(this.CopyStream).ReadToEnd();
}
finally
{
try
{
this.CopyStream.Position = pos;
}
catch { }
}
}
}
public override bool CanRead
{
get { return this.InnerStream.CanRead; }
}
public override bool CanSeek
{
get { return this.InnerStream.CanSeek; }
}
public override bool CanWrite
{
get { return this.InnerStream.CanWrite; }
}
public override void Flush()
{
this.InnerStream.Flush();
}
public override long Length
{
get { return this.InnerStream.Length; }
}
public override long Position
{
get { return this.InnerStream.Position; }
set { this.CopyStream.Position = this.InnerStream.Position = value; }
}
public override int Read(byte[] buffer, int offset, int count)
{
return this.InnerStream.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
this.CopyStream.Seek(offset, origin);
return this.InnerStream.Seek(offset, origin);
}
public override void SetLength(long value)
{
this.CopyStream.SetLength(value);
this.InnerStream.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
this.CopyStream.Write(buffer, offset, count);
this.InnerStream.Write(buffer, offset, count);
}
}
Вы можете использовать серверную переменную ALL_RAW, чтобы получить исходные заголовки HTTP, отправленные с запросом, а затем вы можете получить InputStream как обычно:
string originalHeader = HttpHandler.Request.ServerVariables["ALL_RAW"];
check out : http://msdn.microsoft.com/en-us/library/ms524602%28VS.90%29.aspx
Возможно, лучше сделать это вне вашего приложения. Вы можете настроить обратный прокси-сервер, чтобы делать такие вещи (и многое другое). Обратный прокси-сервер - это в основном веб-сервер, который находится в вашей серверной комнате и стоит между вашим веб-сервером (-ами) и клиентом. См. http://en.wikipedia.org/wiki/Reverse_proxy