MVC 컨트롤러에서 페이지 수명주기를 가로 채서 페이지 또는 DOM 어딘가에 코드를 삽입 할 수 있습니까? 페이지 머리글과 바닥 글에 HTML, CSS 및 JavaScript를 추가하고 싶지만 어딘가에 어셈블리에 포함 된 _Layout보기에 추가하지 마십시오. 그래서 Global.asax/Application_Start의 컨트롤러에서이 작업을 수행하고 싶습니다. 이것이 가능한가?HTML 또는 스크립트를 MVC 페이지 수명주기에 삽입 하시겠습니까?
2
A
답변
1
나는 비슷한 것을했습니다.
첫째, 당신은
두 번째를 (당신이 코드를 삽입 할) 레이아웃 파일 내부에 자리를 추가해야합니다, 당신은 당신의 Global.asax에 글로벌 ActionFilterAttribute를 추가해야합니다. FilterAttribute에서 OnActionExecuted 만 필터링하고 ViewResults 만 필터링하십시오.
셋째, html 코드 내의 자리 표시자를 검색 할 새 필터를 사용하여 Response.Filter를 변경하고 자신의 필터로 바꾸어야합니다.
정확하게 썼습니다. 코드의 어느 곳에서나 스타일 & 스크립트를 선언하는 방법을 추가했습니다. 결과가 완료되면 리소스가 head 태그에 삽입됩니다.
public class DynamicHeaderHandler : ActionFilterAttribute
{
private static readonly byte[] _headClosingTagBuffer = Encoding.UTF8.GetBytes("</head>");
private static readonly byte[] _placeholderBuffer = Encoding.UTF8.GetBytes(DynamicHeader.SectionPlaceholder);
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Result is ViewResult)
{
filterContext.HttpContext.Response.Filter = new ResponseFilter(filterContext.HttpContext.Response.Filter);
}
base.OnActionExecuted(filterContext);
}
private class ResponseFilter : MemoryStream
{
private readonly Stream _outputStream;
public ResponseFilter(Stream aOutputStream)
{
_outputStream = aOutputStream;
}
public override void Close()
{
_outputStream.Flush();
_outputStream.Close();
}
public override void Write(byte[] buffer, int offset, int count)
{
var maxIndex = IndexOfSubArray(buffer, _headClosingTagBuffer);
var index = IndexOfSubArray(buffer, _placeholderBuffer, maxIndex);
if (index == -1)
{
_outputStream.Write(buffer, offset, count);
}
else
{
var html = DynamicHeader.GetHtml();
var injectBytes = Encoding.UTF8.GetBytes(html);
var newBuffer = buffer.Take(index).Concat(injectBytes).Concat(buffer.Skip(index + _placeholderBuffer.Length)).ToArray();
_outputStream.Write(newBuffer, 0, newBuffer.Length);
}
}
private static int IndexOfSubArray(byte[] aBuffer, byte[] aSubBuffer, int aMaxIndex = int.MaxValue)
{
if (aBuffer.Length < aSubBuffer.Length)
{
return -1;
}
for (var outerIndex = 0; outerIndex < aBuffer.Length && outerIndex < aMaxIndex; ++outerIndex)
{
var isEqual = true;
for (int subInnerIndex = 0, innerIndex = outerIndex; subInnerIndex < aSubBuffer.Length && innerIndex < aBuffer.Length; ++subInnerIndex, ++innerIndex)
{
if (aBuffer[innerIndex] != aSubBuffer[subInnerIndex])
{
isEqual = false;
break;
}
}
if (isEqual)
{
return outerIndex;
}
}
return -1;
}
}
}
나는 당신과 관련된 아마 ActionFilterAttribute를 첨부했습니다. 당신은 전체 코드를 보려면
, 당신은 여기 방문 할 수 있습니다 : 쓰기 여러 번 호출, 첫 쓰기까지가 어떤 경우 Add Styles & Scripts Dynamically
에' he' 및 광고'로 다음 시작> '? 이 경우 코드가 머리 끝을 감지하지 못합니다. 일반적으로 Write로 전달되는 청크는 일반적인 HTML 헤더보다 커야하지만 여전히 그렇습니다. 아마도 모든 입력을 버퍼링하고 버퍼링 된 입력을 닫는 태그 버퍼와 비교해야합니다. 머리가 끝나면 래핑 된 출력 스트림에 직접 모든 것을 쓸 수 있습니다. –
그 사건을 생각하지 않았습니까! 어쨌든 나는 결코 문제가 없었기 때문에 나는 운이 좋았고이 경우에 빠지지 않았다. 나는 그것을 내 편에서 고칠 것이다. 하지만 도움이 되었습니까? –