如何使用MVC4和Razor设置javascript变量

如何使用MVC4和Razor设置javascript变量,javascript,c#,asp.net-mvc,asp.net-core,.net-core,Javascript,C#,Asp.net Mvc,Asp.net Core,.net Core,有人可以格式化下面的代码,以便我可以使用razor用c#代码设置srcript变量吗 下面的内容不起作用,我用这种方式让别人很容易帮上忙 @{int proID = 123; int nonProID = 456;} <script type="text/javascript"> @{ <text> var nonID =@nonProID; var proID= @proID; window.nonID = @nonP

有人可以格式化下面的代码,以便我可以使用razor用c#代码设置srcript变量吗

下面的内容不起作用,我用这种方式让别人很容易帮上忙

@{int proID = 123; int nonProID = 456;}

<script type="text/javascript">
    @{

     <text>  

    var nonID =@nonProID;
    var proID= @proID;
    window.nonID = @nonProID;
    window.proID=@proID;

    </text>
}
</script>
@{int proID=123;int nonProID=456;}
@{
var nonID=@nonProID;
var proID=@proID;
window.nonID=@nonProID;
window.proID=@proID;
}
我得到了一个设计时间错误


您应该查看razor页面产生的输出。实际上,您需要知道服务器端和客户端执行的是什么。试试这个:

@{
    int proID = 123; 
    int nonProID = 456;
}

<script>

    var nonID = @nonProID;
    var proID = @proID;
    window.nonID = @nonProID;
    window.proID = @proID;

</script>
@{
int proID=123;
int-nonProID=456;
}
var nonID=@nonProID;
var proID=@proID;
window.nonID=@nonProID;
window.proID=@proID;
输出应如下所示:

var proID = @proID + 0;


根据您使用的Visual Studio版本,它会在使用razor的视图设计时指出一些亮点。

由于在处理视图时razor语法错误可能会出现问题,我完全理解您希望避免这些错误的原因。这里有几个其他的选择

<script type="text/javascript">
    // @Model.Count is an int
    var count = '@Model.Count';
    var countInt = parseInt('@Model.ActiveLocsCount');
</script>

//@Model.Count是一个int
var count='@Model.count';
var countInt=parseInt('@Model.activelocscont');
引号充当分隔符,因此razor解析器很高兴。当然,在第一条语句中,您的C#int会变成一个JS字符串。对于纯粹主义者来说,第二种选择可能更好


如果有人有一个更好的方法来避免razor语法错误,特别是维护var的类型,我很乐意看到它

与其说是一个答案,不如说是一个警示故事:这也让我感到困扰——我想我有一个解决方案,先挂起一个零,然后使用
@(…)
语法。i、 e您的代码应该是:

var nonID = 0@(nonProID);
var proID = 0@(proID);
获得如下输出:

var nonId = 0123;
我没有意识到的是,这就是JavaScript(版本3)如何表示八进制/base-8数字,并实际改变了值。此外,如果您使用的是
“使用严格”命令,然后它将完全中断您的代码,因为八进制数已被删除


我仍在寻找一个合适的解决方案。

我就是这样解决这个问题的:

@{int proID = 123; int nonProID = 456;}

<script type="text/javascript">
var nonID = Number(@nonProID);
var proID = Number(@proID);
</script>

如果您执行以下操作,它会起作用:

var proID = @proID + 0;
它生成的代码类似于:

var proID = 4 + 0;
当然有点奇怪,但至少没有更多的假语法错误。
遗憾的是,VS2013中仍然报告了这些错误,因此这一问题尚未得到妥善解决。

我一直在研究这种方法:

function getServerObject(serverObject) {
  if (typeof serverObject === "undefined") {
    return null;
  }
  return serverObject;
}

var itCameFromDotNet = getServerObject(@dotNetObject);

对我来说,这似乎让JS方面更安全。。。最糟糕的情况是,您最终会得到一个空变量。

我已经看到了几种解决该错误的方法,并且我运行了一些计时测试,以了解什么对速度有效()

方法:
  • 直接指派

    在这种方法中,razor语法直接分配给变量。这就是抛出错误的原因。作为基线,JavaScript速度测试只是直接将一个数字赋值给一个变量

  • 通过'Number'构造函数

    在这种方法中,我们将razor语法包装在对`Number`构造函数的调用中,如`Number(@ViewBag.Value)`

  • 帕森特

    在这种方法中,razor语法放在引号中,并传递给'parseInt'函数

  • 值返回函数

    在这种方法中,将创建一个函数,该函数仅将razor语法作为参数并返回它

  • 类型检查功能

    在这种方法中,函数执行一些基本类型检查(基本上是查找null),如果值不是null,则返回值

  • 程序: 使用上述每种方法,for循环的
    重复每个函数调用10M次,得到整个循环的总时间。然后,循环重复30次,以获得每10M动作的平均时间。然后将这些时间相互比较,以确定哪些动作比其他动作快

    请注意,由于它正在运行JavaScript,其他人收到的实际数字会有所不同,但重要的不是实际数字,而是数字与其他数字的比较方式

    结果: 使用直接分配方法,处理10M分配的平均时间为98.033ms。使用
    编号
    构造函数,每10米产生1554.93毫秒。类似地,
    parseInt
    方法花费了1404.27ms。对于简单函数,这两个函数调用花费了97.5ms;对于更复杂的函数,这两个函数调用花费了101.4ms

    结论: 要理解的最干净的代码是直接赋值。但是,由于VisualStudio中的错误,这会报告一个错误,可能会导致Intellisense出现问题,并给人一种模糊的错误感

    最快的代码是简单的函数调用,但只有很小的差距。由于我没有做进一步的分析,我不知道这种差异是否有统计学意义。类型检查函数也非常快,只比直接赋值稍微慢一点,并且包含变量可能为null的可能性。但是,这并不实际,因为如果参数未定义(razor语法中为null),即使是基本函数也将返回未定义

    将razor值解析为int并通过构造函数运行它的速度非常慢,大约比直接赋值慢15倍。最有可能的是
    Number
    构造函数实际上是在内部调用
    parseInt
    ,这可以解释为什么它比简单的
    parseInt
    花费的时间更长。但是,它们的优点是更有意义,不需要外部定义(即文件或应用程序中的其他地方)函数来执行,
    Number
    构造函数实际上最大限度地减少了整数到字符串的可见转换

    归根结底,这些数字是通过10万次迭代生成的。在一个项目上
    @{
    int proID = 123; 
    int nonProID = 456;
    }
    
    <script>
    
    var nonID = '@nonProID';
    var proID = '@proID';
    window.nonID = '@nonProID';
    window.proID = '@proID';
    
    </script>
    
    function n(num){return num;}
    
    var nonID = n(@nonProID);
    var proID= n(@proID);
    
    <input type="hidden" id="SaleDateValue" value="@ViewBag.SaleDate" />
    <input type="hidden" id="VoidItem" value="@Model.SecurityControl["VoidItem"].ToString()" />
    
    var SaleDate = document.getElementById('SaleDateValue').value;
    var Item = document.getElementById('VoidItem').value;
    
    public class ViewBagUtils
    {
        public static string ToJavascriptValue(dynamic val)
        {
            if (val == null) return "null";
            if (val is string) return val;
            if (val is bool) return val.ToString().ToLower();
            if (val is DateTime) return val.ToString();
            if (double.TryParse(val.ToString(), out double dval)) return dval.ToString();
    
            throw new ArgumentException("Could not convert value.");
        }
    }
    
    @using Namespace_Of_ViewBagUtils
    const someValue = @ViewBagUtils.ToJavascriptValue(ViewBag.SomeValue);
    
    const someValue = "@ViewBagUtils.ToJavascriptValue(ViewBag.SomeValue)";
    
    <body id="myId" data-my-variable="myValue">
    
    ...your page code here
    
    </body>
    
    $("#myId").data("my-variable")
    
    var pv = '@System.Web.Configuration.WebConfigurationManager.AppSettings["pv"]';