Programming

JavaScript 내에서 Razor 사용

procodes 2020. 2. 20. 23:38
반응형

JavaScript 내에서 Razor 사용


뷰 ( cshtml) 에있는 JavaScript 내에서 Razor 구문을 사용하는 것이 가능합니까, 아니면 해결 방법이 있습니까?

Google지도에 마커를 추가하려고합니다 ... 예를 들어 시도했지만 컴파일 오류가 많이 발생합니다.

<script type="text/javascript">

    // Some JavaScript code here to display map, etc.

    // Now add markers
    @foreach (var item in Model) {

        var markerlatLng = new google.maps.LatLng(@(Model.Latitude), @(Model.Longitude));
        var title = '@(Model.Title)';
        var description = '@(Model.Description)';
        var contentString = '<h3>' + title + '</h3>' + '<p>' + description + '</p>'

        var infowindow = new google.maps.InfoWindow({
            content: contentString
        });

        var marker = new google.maps.Marker({
            position: latLng,
            title: title,
            map: map,
            draggable: false
        });

        google.maps.event.addListener(marker, 'click', function () {
            infowindow.open(map, marker);
        });
    }
</script>

여기<text>설명 된대로 의사 요소를 사용하여 Razor 컴파일러를 컨텐츠 모드로 되 돌리십시오.

<script type="text/javascript">

    // Some JavaScript code here to display map, etc.


    // Now add markers
    @foreach (var item in Model) {
        <text>
            var markerlatLng = new google.maps.LatLng(@(Model.Latitude), @(Model.Longitude));
            var title = '@(Model.Title)';
            var description = '@(Model.Description)';
            var contentString = '<h3>' + title + '</h3>' + '<p>' + description + '</p>'

            var infowindow = new google.maps.InfoWindow({
                content: contentString
            });

            var marker = new google.maps.Marker({
                position: latLng,
                title: title,
                map: map,
                draggable: false
            });

            google.maps.event.addListener(marker, 'click', function () {
                infowindow.open(map, marker);
            });
        </text>
    }
</script>

최신 정보:

Scott Guthrie는 최근@: 에 Razor의 구문에 대해 게시했습니다<text> . JavaScript 코드 한두 줄만 추가 하면 태그 보다 약간 덜 복잡 합니다. 다음 방법은 생성 된 HTML의 크기를 줄이기 때문에 선호 될 것입니다. (addMarker 함수를 정적 캐시 된 JavaScript 파일로 이동하여 크기를 더 줄일 수도 있습니다) :

<script type="text/javascript">

    // Some JavaScript code here to display map, etc.
    ...
    // Declare addMarker function
    function addMarker(latitude, longitude, title, description, map)
    {
        var latLng = new google.maps.LatLng(latitude, longitude);
        var contentString = '<h3>' + title + '</h3>' + '<p>' + description + '</p>';

        var infowindow = new google.maps.InfoWindow({
            content: contentString
        });

        var marker = new google.maps.Marker({
            position: latLng,
            title: title,
            map: map,
            draggable: false
        });

        google.maps.event.addListener(marker, 'click', function () {
            infowindow.open(map, marker);
        });
    }

    // Now add markers
    @foreach (var item in Model) {
        @:addMarker(@item.Latitude, @item.Longitude, '@item.Title', '@item.Description', map);
    }
</script>

addMarker더 정확한 호출을 위해 위의 코드를 업데이트했습니다 .

명확히하기 위해 호출이 C # 코드와 비슷하게 보이지만 @:Razor가 텍스트 모드로 돌아갑니다 addMarker. 그런 다음 Razor는 @item.Property구문을 선택하여 해당 속성의 내용을 직접 출력해야한다고 말합니다.

업데이트 2

View 코드는 실제로 JavaScript 코드를 넣기에 좋은 장소가 아니라는 점에 주목할 가치가 있습니다. JavaScript 코드는 정적 .js파일에 저장 한 다음 Ajax 호출에서 또는 data-HTML에서 속성을 스캔하여 필요한 데이터를 가져와야 합니다. Razor는 JavaScript가 아닌 HTML 용으로 인코딩되도록 설계되었으므로 JavaScript 코드를 캐시 할 수있게하는 것 외에도 인코딩 문제를 피할 수 있습니다.

코드보기

@foreach(var item in Model)
{
    <div data-marker="@Json.Encode(item)"></div>
}

자바 스크립트 코드

$('[data-marker]').each(function() {
    var markerData = $(this).data('marker');
    addMarker(markerData.Latitude, markerData.Longitude,
              markerData.Description, markerData.Title);
});

방금이 도우미 함수를 작성했습니다. 그것을 넣어 App_Code/JS.cshtml:

@using System.Web.Script.Serialization
@helper Encode(object obj)
{
    @(new HtmlString(new JavaScriptSerializer().Serialize(obj)));
}

그런 다음 예제에서 다음과 같이 할 수 있습니다.

var title = @JS.Encode(Model.Title);

인용 부호를 넣지 않은 방법에 주목하십시오. 제목에 이미 따옴표가 포함되어 있으면 폭발하지 않습니다. 사전과 익명 객체도 훌륭하게 처리하는 것 같습니다!


둥근 구멍에 사각형 못을 끼 우려 고합니다.

Razor는 HTML 생성 템플릿 언어로 고안되었습니다. JavaScript 코드를 생성하는 것이 좋을 수도 있지만 그렇게 설계되지 않았습니다.

예를 들어 : Model.Title아포스트로피 포함되어 있으면 어떻게 됩니까? 그러면 JavaScript 코드가 손상되고 Razor는 기본적으로 올바르게 이스케이프하지 않습니다.

도우미 함수에서 문자열 생성기를 사용하는 것이 더 적절할 것입니다. 해당 접근 방식의 의도하지 않은 결과는 줄어들 것입니다.


어떤 특정 오류가 표시됩니까?

이와 같은 것이 더 잘 작동 할 수 있습니다.

<script type="text/javascript">

//now add markers
 @foreach (var item in Model) {
    <text>
      var markerlatLng = new google.maps.LatLng(@Model.Latitude, @Model.Longitude);
      var title = '@(Model.Title)';
      var description = '@(Model.Description)';
      var contentString = '<h3>' + title + '</h3>' + '<p>' + description + '</p>'
    </text>
}
</script>

Razor가 마크 업 모드로 전환해야 함을 나타 내기 위해 <text>뒤에 매직 태그 가 필요 foreach합니다.


외부 JavaScript 파일이 아닌 CSHTML 페이지에있는 한 정상적으로 작동합니다.

Razor 템플릿 엔진은 출력되는 내용에 신경 쓰지 않으며 <script>다른 태그 나 다른 태그를 구별하지 않습니다 .

그러나 XSS 공격 을 방지하려면 문자열을 인코딩해야합니다 .


"text!"처럼 "<!-" "->"를 선호합니다.

<script type="text/javascript">
//some javascript here     

@foreach (var item in itens)
{                 
<!--  
   var title = @(item.name)
    ...
-->

</script>

추가해야 할 사항-Razor 구문 하이 라이터 (및 컴파일러)는 여는 괄호 위치를 다르게 해석한다는 것을 알았습니다.

<script type="text/javascript">
    var somevar = new Array();

    @foreach (var item in items)
    {  // <----  placed on a separate line, NOT WORKING, HILIGHTS SYNTAX ERRORS
        <text>
        </text>
    }

    @foreach (var item in items) {  // <----  placed on the same line, WORKING !!!
        <text>
        </text>
    }
</script>

간단하고 좋은 간단한 예 :

<script>
    // This gets the username from the Razor engine and puts it
    // in JavaScript to create a variable I can access from the
    // client side.
    //
    // It's an odd workaraound, but it works.
    @{
        var outScript = "var razorUserName = " + "\"" + @User.Identity.Name + "\"";
    }
    @MvcHtmlString.Create(outScript);
</script>

그러면 페이지에서 코드를 배치 한 위치에 다음과 같은 스크립트가 생성됩니다.

<script>
    // This gets the username from the Razor engine and puts it
    // in JavaScript to create a variable I can access from
    // client side.
    //
    // It's an odd workaraound, but it works.

    var razorUserName = "daylight";
</script>

이제 razorUserName클라이언트에서 액세스하고 사용할 수 있는 전역 JavaScript 변수 가 있습니다. Razor 엔진은 @User.Identity.Name서버 측 변수 에서 값을 추출 하여 스크립트 태그에 쓰는 코드에 넣었습니다.


다음 솔루션은 JavaScript와 Razor를 결합하는 것보다 더 정확합니다. 이것을 확인하십시오 : https://github.com/brooklynDev/NGon

거의 모든 복잡한 데이터를 ViewBag.Ngon에 추가 하고 JavaScript로 액세스 할 수 있습니다

컨트롤러에서 :

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var person = new Person { FirstName = "John", LastName = "Doe", Age = 30 };
        ViewBag.NGon.Person = person;
        return View();
    }
}

자바 스크립트에서 :

<script type="text/javascript">
    $(function () {
        $("#button").click(function () {
            var person = ngon.Person;
            var div = $("#output");
            div.html('');
            div.append("FirstName: " + person.FirstName);
            div.append(", LastName: " + person.LastName);
            div.append(", Age: " + person.Age);
        });
    });
</script>

default를 사용하여 직렬화 할 수있는 일반 오래된 CLR 객체 (POCO)를 허용합니다 JavascriptSerializer.


@ : 및보다 더 많은 옵션이 <text></text>있습니다.

<script>블록 자체를 사용 합니다.

Razor 코드에 따라 큰 JavaScript 청크를 수행해야하는 경우 다음과 같이 수행 할 수 있습니다.

@if(Utils.FeatureEnabled("Feature")) {
    <script>
        // If this feature is enabled
    </script>
}

<script>
    // Other JavaScript code
</script>

이 방식의 장점은 JavaScript와 Razor를 너무 많이 섞지 않는다는 것입니다. 많이 섞으면 결국 가독성 문제가 발생할 수 있기 때문입니다. 또한 큰 텍스트 블록은 읽기가 쉽지 않습니다.


이전 솔루션 중 어느 것도 올바르게 작동하지 않습니다 ... 모든 방법을 시도했지만 예상 결과를 얻지 못했습니다 ... 마침내 코드에 약간의 오류가 있음을 발견했습니다 ... 그리고 전체 코드가 제공됩니다 이하.

<script type="text/javascript">

    var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 10,
        center: new google.maps.LatLng(23.00, 90.00),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    @foreach (var item in Model)
    {
        <text>
            var markerlatLng = new google.maps.LatLng(@(item.LATITUDE), @(item.LONGITUDE));
            var title = '@(item.EMP_ID)';
            var description = '@(item.TIME)';
            var contentString = '<h3>' + "Employee " +title+ " was here at "+description+ '</h3>' + '<p>'+" "+ '</p>'

            var infowindow = new google.maps.InfoWindow({
                // content: contentString
            });

            var marker = new google.maps.Marker({
                position: markerlatLng,
                title: title,
                map: map,
                draggable: false,
                content: contentString
            });

            google.maps.event.addListener(marker, 'click', (function (marker) {
                return function () {
                    infowindow.setContent(marker.content);
                    infowindow.open(map, marker);
                }
            })(marker));
        </text>
    }
</script>

마침내 해결책 (* .vbhtml)을 찾았습니다.

function razorsyntax() {
    /* Double */
    @(MvcHtmlString.Create("var szam =" & mydoublevariable & ";"))
    alert(szam);

    /* String */
    var str = '@stringvariable';
    alert(str);
}

참고 URL : https://stackoverflow.com/questions/4599169/using-razor-within-javascript



반응형