如何在 ASP.NET MVC 中集成 AngularJS(2)

如何在 ASP.NET MVC 中集成 AngularJS(1)中,我们介绍了 ASP.NET MVC 捆绑和压缩、应用程序版本自动刷新和工程构建等内容。

下面介绍如何在 ASP.NET MVC 中集成 AngularJS 的第二部分。

ASP.NET 捆绑和压缩

CSS 和 JavaScript 的捆绑与压缩功能是 ASP.NET MVC 最流行和有效的特性之一。捆绑和压缩降低了 HTTP 请求和有效载荷的大小,结果是可以更快和更好的执行 ASP.NET MVC 的网站。有许多可以减少 CSS 和 JavaScript 合并的大小的方法。

捆绑可以很容易地将多个文件合并或捆绑到一个文件中。您可以创建 CSS,JavaScript 和其他包。压缩可以优化脚本和 CSS 代码,如去除不必要的空格和注释,缩短变量名到一个字符。由于捆绑和压缩降低你的 JavaScript 和 CSS 文件的大小,发送的 HTTP 的字节也会显著降低。

当配置包文件时,你需要考虑一个捆绑策略以及如何组织你的包文件。下面的 BundleConfig 类是内置的 ASP.NET 捆绑功能的配置文件。在 BundleConfig 类,我决定通过功能模块来组织我的文件。我为工程中的每一个文件设置了一个独立的捆绑,包括对脚本的单独捆绑,Angular 的核心文件,共享的 JavaScript 文件和主目录单,客户目录和产品目录。

我创建了客户和产品目录的独立包,带着这种想法,当用户请求应用程序的这些源文件时,应以将会动态的加载这些捆绑。由于 AngularJS 是一个纯客户端框架,可以动态加载 ASP.NET 包和服务器端技术,所以这两项技术相结合,成为了这个要求具有发布调试模块的实例应用的最大开发挑战。

// BundleConfig.cs
using System.Web;
using System.Web.Optimization;

public class BundleConfig
{
    // For more information on bundling, visit http://go.microsft.com/fwlink/?LinkId=301862
    public static void RegisterBundles(BundleCollection bundles)
    {
        bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
            "~/Scripts/jquery-{version}.js"));

        bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
            "~/Scripts/bootstrap.js",
            "~/Scripts/respond.js"
        ));

        bundles.Add(new StyleBundle("~/Content/css").Include(
           "~/Content/bootstrap.css",
           "~/Content/site.css",
           "~/Content/SortableGrid.css",
           "~/Content/angular-block-ui.min.css",
           "~/Content/font-awesome.min.css"
        ));

        bundles.Add(new ScriptBundle("~/bundles/angular").Include(
           "~/Scripts/angular.min.js",
           "~/Scripts/angular-route.min.js",
           "~/Scripts/angular-sanitize.min.js",
           "~/Scripts/angular-ui.min.js",
           "~/Scripts/angular-ui/ui-bootstrap.min.js",
           "~/Scripts/angular-ui/ui-bootstrap-tpls.min.js",
           "~/Scripts/angular-ui.min.js",
           "~/Scripts/angular-block-ui.js"
        ));

        bundles.Add(new ScriptBundle("~/bundles/shared").Include(
           "~/Views/Shared/CodeProjectBootstrap.js",
           "~/Views/Shared/AjaxService.js",
           "~/Views/Shared/AlertService.js",
           "~/Views/Shared/DataGridService.js",
           "~/Views/Shared/MasterController.js"
        ));

        bundles.Add(new ScriptBundle("~/bundles/routing-debug").Include(
           "~/Views/Shared/CodeProjectRouting-debug.js"
        ));

        bundles.Add(new ScriptBundle("~/bundles/routing-production").Include(
           "~/Views/Shared/CodeProjectRouting-production.js"
        ));

        bundles.Add(new ScriptBundle("~/bundles/home").Include(
           "~/Views/Home/IndexController.js",
           "~/Views/Home/AboutController.js",
           "~/Views/Home/ContactController.js",
           "~/Views/Home/InitializeDataController.js"
        ));

 
        bundles.Add(new ScriptBundle("~/bundles/customers").Include(
           "~/Views/Customers/CustomerMaintenanceController.js",
           "~/Views/Customers/CustomerInquiryController.js"
        ));

 
        bundles.Add(new ScriptBundle("~/bundles/products").Include(
           "~/Views/Products/ProductMaintenanceController.js",
           "~/Views/Products/ProductInquiryController.js"
        ));
    }
}

缓存与 ASP.NET 捆绑

使用 ASP.NET 捆绑的优势是它的“cache busting”的辅助方法,一旦你改变了 CSS 和 JavaScript 的缓存方式,这种方法将会使用自动引导的方式使捆绑的文件能够更容易的进行缓存。下面的代码示例是在一个 MVC 的 Razor 视图中执行的(通常情况下,是在 _Layout.cshtml 母版页)。所述的 Scripts.Render 方法将会在客户端渲染,并且当在非调试模式下执行时,它将会产生包的虚拟路径和结束包的序列号。当你更改包的内容并重新发布你的应用程序时,包将会生成一个新的版本号,这有助于客户端上的浏览器缓存,并生成一个新的下载包。

// _Layout.cshtml
@Scripts.Render("~/bundles/customers")
@Scripts.Render("~/bundles/products")

该 Scripts.Render 功能是一个很好的功能,但在此示例应用程序,我想使用在客户端一侧动态加载的客户和产品,所以我不能用渲染功能来渲染我的一些包,这是挑战的开始。这个问题是以如何使用 AngularJS 从客户端 JavaScript 渲染服务器端的 ASP.NET 包开始的?

_Layout.cshtml - 服务器端启动代码

一个使用 ASP.NET MVC 来引导 AngularJS 应用程序的好处是,你可以通过 _Layout.cshtml 主页中服务器端的代码,来加载和执行 AngularJS 的代码。这是第一步,帮助解决我通过客户端代码渲染服务器端捆绑的窘境。当然,你可以简单地嵌入脚本来标记客户端的代码,但我需要一种方法来渲染一个包和引用,并维护被追加到清除了缓存的包的目的自动版本号。

开始的时候,我在 _Layout.cshtml 母版页的顶部编写了一些服务器端代码。我所做的头两件事情就是让从程序集信息类中获取应用的序列号,从应用程序设置中获取检索的基本 URL。这两个都将被之后 HTML 中的 Razor 视图引擎所解析。

下面的代码段,产生了我想根据需求动态加载的一些包,我不想当应用启动时加载所有的前期的包。我需要的信息中的最重要一块是虚拟路径和每一次捆绑的长版本号。幸运的是,访问捆绑信息的方法,本身就是一种捆绑的功能。

下面的代码行的关键行引用了 BundleTable。这行代码执行了 ResolveBundleUrl 返回了该方法的虚拟路径以及每个引用的捆绑和版本号。这些代码基本上生成一个包的列表并且将该列表转换成一个 JSON 集合。后来这个 JSON 集被添加到 AngularJS。有一个 JSON 集合中的包的信息是,允许从客户端 AngularJS 应用程序加载服务器端捆绑的最初的方法。

// _Layout.cshtml
@using CodeProject.Portal.Models
@{
    string version = typeof(CodeProject.Portal.MvcApplication).Assembly.GetName().Version.ToString();
    string baseUrl = System.Configuration.ConfigurationManager.AppSettings["BaseUrl"].ToString();

    List<CustomBundle> bundles = new List<CustomBundle>();
    CodeProject.Portal.Models.CustomBundle customBundle;

    List<string> codeProjectBundles = new List<string>();
    codeProjectBundles.Add("home");
    codeProjectBundles.Add("customers");
    codeProjectBundles.Add("products");

    foreach (string controller in codeProjectBundles)
    {
        customBundle = new CodeProject.Portal.Models.CustomBundle();
        customBundle.BundleName = controller;
        customBundle.Path = BundleTable.Bundles.ResolveBundleUrl("~/bundles/" + controller);
        customBundle.IsLoaded = false;
        bundles.Add(customBundle);
    }

    BundleInformation bundleInformation = new BundleInformation();
    bundleInformation.Bundles = bundles;
    string bundleInformationJSON = Newtonsoft.Json.JsonConvert.SerializeObject(
    bundleInformation, Newtonsoft.Json.Formatting.None);

}

ASP.NET 的捆绑类有很多的功能。例如,如果你想通过捆绑所有文件进行迭代,你可以执行 EnumerateFiles 方法,返回一个特定的包内的每个文件的虚拟路径。

foreach (var file in bundle.EnumerateFiles(new BundleContext(
         new HttpContextWrapper(HttpContext.Current), BundleTable.Bundles, "~/bundles/shared")))
{
    string filePath = file.IncludedVirtualPath.ToString();
}

_Layout.cshtml - 标题

在 HTML 文档的标题部分,有一个 RequireJS 的参考。该应用程序通过客户端 AngularJS 代码使用了 RequireJS 动态的加载包。RequireJS 是一个加载了 JavaScript API 模块的异步模块定义(AMD)。RequireJS 有许多功能,但是对于实例应用的目的,仅需要来自于 RequireJS 的请求功能以便在后面应用程序的使用。

此外,Scripts.Render 和 Styles.Render 方法将在开始部分被执行。当应用程序以调试模式执行或者 EnableOptimizations 被指为 false 时,渲染的方法将会在每一次捆绑中生成多个脚本。当在发布模式和启用优化时,渲染方法将生成一个脚本标记来代表整个捆绑的版本戳。

这就导致了另外一个挑战,那就是应用需要支持发布模式下生成捆绑脚本标签的能力,和调试模式下生成独特文件的脚本标签的能力。如果你想要在调试模式下为 JavaScript 代码设置断点,这点是很重要的。因为如果在发布模式下,使用 JavaScript 代码的优化捆绑版本是不可能的。

最后,在标题部分,使用 Razor 语法的基本 URL 被早早地设定为服务器侧的基本 URL 变量。

<!-- _Layout.cshtml -->

!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />

<title>AngularJS MVC Code Project</titlev>

<script src="~/Scripts/require.js"></script>

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@Scripts.Render("~/bundles/modernizr")
@Scripts.Render("~/bundles/angular")

@Styles.Render("~/Content/css")

<base href="#baseUrl" />

</head>

调试模式VS发布模式

当 EnableOptimizations 被设置为 false,或者在调试模式运行时,该 @Scripts.Render 方法会在每一次捆绑中产生多种脚本标签。如果你想设置断点并调试 JavaScript 文件,这是必要的。你有另一种选择,就是在调试模式下,使用 RenderFormat 方法来选人客户脚本标签。

下面的代码片段包含在 _layout.cshtml 母版页中,当应用程序在调试模式下,RenderFormat 会被使用。在这种模式下,应用的版本序列号会被追加到捆绑中的所有JavaScript 文件的脚本标签中。对于标准的渲染脚本标签格式不包含追加版本号来说,这也算是个小弥补。

从 Visual Studio 中启动应用程序时,您可能会遇到浏览器缓存的问题。同时也可能会花时间来猜测,你运行的是否是最新版本的 JavaScript 文件。在浏览器中按 F5 可以解决这个问题。为了避免这个问题一起发生,应用程序版本号会被附加到脚本标签中。使用自动版本插件,版本号会在每次构建中自动递增。使用这项技术,我能够知道每一次的编译和运行使用的是 JavaScript 文件的最新版本,这为我省了很多时间。

// _Layout.cshtml
@if (HttpContext.Current.IsDebuggingEnabled)
{
    @Scripts.RenderFormat("<script type=\"text/javascript\" src=\"{0}?ver =" + @version + " \">
                           </script>", "~/bundles/shared")
    @Scripts.RenderFormat("<script type=\"text/javascript\" src=\"{0}?ver =" + @version + " \">
                           </script>","~/bundles/routing-debug")
}
else
{
    @Scripts.Render("~/bundles/shared")
    @Scripts.Render("~/bundles/routing-production")
}

服务器端 Razor 数据和 AngularJS 之间的桥梁

现在,我已经创建了服务器端的捆绑数据的收集,接下来的挑战就是注入并创建服务器端和客户端 AngularJS 代码的桥梁。在 _Layout.cshtml 母版页,我创建了能够创造一个 AngularJS 供应商的匿名的 JavaScript 功能。最初我计划创建一个常规的 AngularJS 服务或者一个包含在 _Layout.cshtml 文件中能够使用 Razor 语法注入服务器端的方法集。

不幸的是,直到 AngularJS 配置阶段完成之后,才能提供 AngularJS 服务和方法集,因此我无法在主页中创建一个没有 AngularJS 错误的服务。为了克服这个限制,则需要创建一个 AngularJS 的提供者。提供者的功能是,能够创建提供方法集和服务的实例。提供者允许你在 Angular 配置过程中创建和配置一个服务。

服务提供者名称是以他们所提供工作的提供商为开始的。下面的代码片段中,代码创建一个“applicationConfiguration”提供商,这个提供商正在被 applicationConfigurationProvider 引用。这个提供商将会在构造函数中被配置,来设定用于动态请求的应用所需的程序集版本号和捆绑列表。MVC Razor 代码在构造函数中会注入服务器端的数据。

// _Layout.cshtml
(function () {
        var codeProjectApplication = angular.module(‘codeProject‘);
        codeProjectApplication.provider(‘applicationConfiguration‘, function () {
            var _version;
            var _bundles;
            return {
                setVersion: function (version) {
                _version = version;
            },

            setBundles: function (bundles) {
                _bundles = bundles;
            },

            getVersion: function () {
                return _version;
            },

            getBundles: function () {
                return _bundles;
            },

            $get: function () {
                return {
                    version: _version,
                    bundles: _bundles
                }
            }
       }
    });

    codeProjectApplication.config(function (applicationConfigurationProvider) {
        applicationConfigurationProvider.setVersion(‘@version‘);
        applicationConfigurationProvider.setBundles(‘@Html.Raw(bundleInformationJSON)‘);
    });
})();

路由产生和动态加载 MVC 捆绑

现在你可能已经看到了很多例子实现了每个内容页硬编码路径的 AngularJS 示例。示例应用程序的路由使用基于约定的方法,这种方法允许路由表使用硬编码的路由方法来实现使用基于约定的方法。所有的内容页和相关联的 JavaScript 文件将会遵循命名约定规则,这个规则允许该应用程序来解析路由并动态地确定每个内容页需要哪些 JavaScript 文件。

下面的示例应用程序的路由表只需要分析出三条路线:

  • 一个用于根路径‘/‘
  • 一个标准路由路径,如‘/:section/:tree‘
  • 包含路由参数的路由,如‘/:section/:tree/:id‘

我决定从 ASP.NET 捆绑中加载 JavaScript 文件,下面的路由配置代码需要包含一些 applicationConfigurationProvider 引用的代码,来用于创建保存之前的捆绑信息。捆绑信息将会被解析为 JSON 集。捆绑信息集将会用于返回虚拟的捆绑路径。此外,JSON 集将被用于跟踪被加载的捆绑。一旦捆绑被加载,就不需要第二次捆绑了。

有几件事情需要写入路由代码中。首先,每当用户选择一个页面来加载一定功能模块时,对于模块绑定的所有 JavaScript 文件需要被下载。例如,当用户选择客户模式中的一个内容页面时,以下的代码会查看模块的捆绑是否已经通过 JSON _bundles collection 的 isLoaded 属性被检查了,并且如果 isLoaded 为 false,则捆绑将会被记载, isLoaded 属性会被设置为 true。

当确定需要下载哪些模式的捆绑时,有两件事情需要去加载捆绑:deferred promise 和 RequireJS。deferred promise 可以帮助你异步运行函数,当它完成执行,就会返回。

现在,最后一块本文之谜是确定从客户端代码包中加载的方式。我在以前的文章 CodeProject.com 使用 RequireJS(前面提到的)来动态加载 JavaScript 文件,我使用捆绑来加载 RequireJS。使用 RequireJS“需求”的功能, 我通过捆绑的虚拟路径进入需求功能。事实证明,需求功能将会加载任何能够更好执行捆绑加载的路径。

当我第一次使用 RequireJS 的路径来下载捆绑时,我已经完成了 RequireJS 和它的所有配置。事实证明,我能够去掉这一切,只是简单地加载 RequireJS 库并使用它的需求功能。我甚至没有使用 RequireJS 定义表述来预安装我的动态加载控制器。很多试验和错误之后,我已经达到了本文的目的。我现在可以通过客户端代码加载服务器端的捆绑。

// CodeProjectRouting-production.js
?angular.module("codeProject").config(
[‘$routeProvider‘, ‘$locationProvider‘, ‘applicationConfigurationProvider‘
    function ($routeProvider, $locationProvider, applicationConfigurationProvider) {
        var baseSiteUrlPath = $("base").first().attr("href");
        var _bundles = JSON.parse(applicationConfigurationProvider.getBundles());
        this.getApplicationVersion = function () {
            var applicationVersion = applicationConfigurationProvider.getVersion();
            return applicationVersion;
        }
        this.getBundle = function (bundleName) {

            for (var i = 0; i < _bundles.Bundles.length; i++) {
                if (bundleName.toLowerCase() == _bundles.Bundles[i].BundleName) {
                    return _bundles.Bundles[i].Path;
                }
            }
        }
        this.isLoaded = function (bundleName) {
            for (var i = 0; i < _bundles.Bundles.length; i++) {
                if (bundleName.toLowerCase() == _bundles.Bundles[i].BundleName) {
                    return _bundles.Bundles[i].IsLoaded;
                }
            }
        }
        this.setIsLoaded = function (bundleName) {
            for (var i = 0; i < _bundles.length; i++) {
                if (bundleName.toLowerCase() == _bundles.Bundles[i].BundleName) {
                    _bundles.Bundles[i].IsLoaded = true;
                    break;
                }
            }
        }
        $routeProvider.when(‘/:section/:tree‘,
        {
            templateUrl: function (rp) { return baseSiteUrlPath + ‘views/‘ +
                         rp.section + ‘/‘ + rp.tree + ‘.html?v=‘ + this.getApplicationVersion(); },
            resolve: {
                load: [‘$q‘, ‘$rootScope‘, ‘$location‘, function ($q, $rootScope, $location) {
                    var path = $location.path().split("/");
                    var parentPath = path[1];
                    var bundle = this.getBundle(parentPath);
                    var isBundleLoaded = this.isLoaded(parentPath);
                    if (isBundleLoaded == false) {
                        this.setIsLoaded(parentPath);
                        var deferred = $q.defer();
                        require([bundle], function () {
                            $rootScope.$apply(function () {
                                deferred.resolve();
                            });
                        });
                        return deferred.promise;
                    }
                }]
            }
        });
        $routeProvider.when(‘/:section/:tree/:id‘,
        {
            templateUrl: function (rp) { return baseSiteUrlPath + ‘views/‘ +
                         rp.section + ‘/‘ + rp.tree + ‘.html?v=‘ + this.getApplicationVersion(); },
            resolve: {
                load: [‘$q‘, ‘$rootScope‘, ‘$location‘, function ($q, $rootScope, $location) {
                    var path = $location.path().split("/");
                    var parentPath = path[1];
                    var bundle = this.getBundle(parentPath);
                    var isBundleLoaded = this.isLoaded(parentPath);
                    if (isBundleLoaded == false) {
                        this.setIsLoaded(parentPath);
                        var deferred = $q.defer();
                        require([bundle], function () {
                            $rootScope.$apply(function () {
                                deferred.resolve();
                            });
                        });
                        return deferred.promise;
                    }
                }]
            }
        });
        $routeProvider.when(‘/‘,
        {
            templateUrl: function (rp) {                 return baseSiteUrlPath + ‘views/Home/Index.html?v=‘ + this.getApplicationVersion(); },
                resolve: {
                load: [‘$q‘, ‘$rootScope‘, ‘$location‘, function ($q, $rootScope, $location) {
                    var bundle = this.getBundle("home");
                    var isBundleLoaded = this.isLoaded("home");
                    if (isBundleLoaded == false) {
                        this.setIsLoaded("home");
                        var deferred = $q.defer();
                        require([bundle], function () {
                            $rootScope.$apply(function () {
                                deferred.resolve();
                            });
                        });
                        return deferred.promise;
                    }
                }]
            }
        });
        $locationProvider.html5Mode(true);
     }
]);

以上是如何在 ASP.NET MVC 中集成 AngularJS 的第二部分内容,最后一篇内容会在近期呈现,敬请期待!

文章来源:By Mark J. Caplin

原文链接:http://www.codeproject.com/Articles/1033076/Integrating-AngularJS-with-ASP-NET-MVC

时间: 2024-10-05 03:24:05

如何在 ASP.NET MVC 中集成 AngularJS(2)的相关文章

如何在 ASP.NET MVC 中集成 AngularJS(3)

今天来为大家介绍如何在 ASP.NET MVC 中集成 AngularJS 的最后一部分内容. 调试路由表 - HTML 缓存清除 就在我以为示例应用程序完成之后,我意识到,我必须提供两个版本的路由表:一个运行在调试模式的应用程序下和一个运行在发布模式的应用程序下.在调试模式下,JavaScript 文件在未使用压缩功能的情况下会被下载.如果想要调试并在 JavaScript 控制器中设置断点,这是必须的.事实上,路由表的产生版本也出现了一些挑战,由于产生路由代码使用的是 JavaScript

如何在ASP.NET MVC 中获取当前URL、controller、action

一.URL的获取很简单,ASP.NET通用: [1]获取 完整url (协议名+域名+虚拟目录名+文件名+参数) string url=Request.Url.ToString(); [2]获取 虚拟目录名+页面名+参数: string url=Request.RawUrl;(或 string url=Request.Url.PathAndQuery;) [3]获取 虚拟目录名+页面名:string url=HttpContext.Current.Request.Url.AbsolutePath

如何在asp.net mvc中添加自定义的HTML辅助种方法

很久没在博客园发表文章了,今天来总结一下如何在asp.net mvc中添加自定义的HTML辅助方法.我们现在设计这么一个目前,利用自定义的HTML方法来渲染一个普通的img标记.直接进入主题吧: 首先我们先来看一下一个普通的img标签在HTML中的代码: <img src="Content/images/封面.jpg" alt="图片" id="img01" width="500px" height="250p

angular.js的路由和模板在asp.net mvc 中的使用

我们知道angular.js是基于mvc 的一款优秀js框架,它也有一套自己的路由机制,和asp.net mvc 路由不太一样.asp.net mvc 的路由是通过不同的URL到不同的controller然后交给controller去呈现视图.但是在angular.js则是需要提前指定一个module(ng-app),然后去定义路由规则,通过不同的URL,来告诉ng-app 去加载哪个页面.再渲染到ng-view.通过angular.js路由的使用,可以很容易实现页面的局部刷新.更加高效的去创建

在 ASP.NET MVC 中使用 HTTPS (SSL/TLS)

某些安全性较高的网页,如网上支付或用户登陆页面,可能会使用到https(SSL/TLS)来提高安全性.本文介绍了如何在ASP.NET MVC中强制某action使用https和如何进行向https页面的跳转.我们先实现强制一个action使用https.这里写了一个RequireHttpsAttribute,它的作用是将非https连接转换成https连接,这样所有使用了RequireHttps这个filter的controller都会强制使用https连接. 1 using System.We

《Entity Framework 6 Recipes》中文翻译系列 (20) -----第四章 ASP.NET MVC中使用实体框架之在MVC中构建一个CRUD示例

翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第四章  ASP.NET MVC中使用实体框架 ASP.NET是一个免费的Web框架,它支持3种不同的技术来创建websites(网站)和Web应用:他们分别是,Web Pages,Web Forms,和MVC.虽然MVC是一种非常流行的,有完整的用于软件开发模式理论的技术,但它在ASP.NET中却是一种新的技术. 目前最新的版本是2012年发布的ASP.NET MVC4.自从2008年发布

ASP.NET MVC中jQuery与angularjs混合应用传参并绑定数据

要求是这样子的,在一个列表页中,用户点击详细铵钮,带记录的主键值至另一页.在另一外页中,获取记录数据,然后显示此记录数据在网页上. 先用动图演示: 昨天有分享为ng-click传递参数 <angularjs为ng-click事件传递参数>http://www.cnblogs.com/insus/p/7017737.html 上面仅仅是在ng-click传入一个值,但是在ASP.NET MVC中,还需要把这个值传至另外一个视图中<ASP.NET MVC传递参数(model)>http

如何在ASP.NET Core中实现一个基础的身份认证

注:本文提到的代码示例下载地址> How to achieve a basic authorization in ASP.NET Core 如何在ASP.NET Core中实现一个基础的身份认证 ASP.NET终于可以跨平台了,但是不是我们常用的ASP.NET, 而是叫一个ASP.NET Core的新平台,他可以跨Windows, Linux, OS X等平台来部署你的web应用程序,你可以理解为,这个框架就是ASP.NET的下一个版本,相对于传统ASP.NET程序,它还是有一些不同的地方的,比

如何在asp.net mvc3中使用HttpStatusCode

下载了asp.net mvc 4的源码看了看,没怎么看清楚.不过个人觉得MVC4 beta中Web API这个是比较不错的,虽然说它是往传统回归. web api最好的莫过于它更加适合使用jquery的ajax调用. 我这里主要给大家说明下如何在asp.net mvc 3中借鉴Web API的特性来让AJAX调用更加酷. 首先给大家看个例子,传统的asp.net mvc 3中异步调用的Response: Action如下: 相应的jquery ajax请求代码(只是简单的代码,): 我们来运行看