65.9K
CodeProject 正在变化。 阅读更多。
Home

在 Microsoft MVC 应用程序中使用 AJAX(带 Entity Framework)

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.84/5 (10投票s)

2008年5月23日

CPOL

4分钟阅读

viewsIcon

104483

downloadIcon

1606

本文介绍如何在基于 Microsoft MVC 框架的应用程序中使用 AJAX。

MvcAjax

引言

在本文中,我将解释如何在 MVC 应用程序中使用 AJAX。我将使用 Entity Framework 从数据库获取数据。为了实现局部网页更新,我使用了迷人的 JS 框架 prototype。

开始之前需要准备什么

  1. Visual Studio 2008 (beta)
  2. MVC 框架
  3. ADO.NET Entity Framework
  4. VS 2008 和 Microsoft .NET 3.5 SP1
  5. Framework Prototype

任务

我的页面上有两个下拉列表:一个国家列表和一个城市列表。当我从第一个下拉列表中选择一个国家时,第二个下拉列表中的城市列表应该被更新,当然,无需重新加载整个页面。

计划

虽然这个任务很简单,但我认为最好有一个开发计划。

  1. 数据库 — 国家和城市表
  2. Entity Framework — 访问数据的接口
  3. Model — 获取国家和城市列表
  4. Controller — 用于查看主页并将对象传递给视图的 Action 方法
  5. 视图
  6. AJAX (prototype) — 用于将数据加载到下拉列表中的 JavaScript 代码

解决方案

  1. 数据库 — 我创建了两个表,CountryCityCity 通过 CountryCodeCountry 连接。

    Tables.gif

  2. Entity Framework — 我们应该为访问 CountryCity 等数据库对象生成代码。为此,右键单击“Models”文件夹,然后单击“Add ...”,并选择“ADO.NET Entity Data Model”。然后,我们从列表中选择表:Country、City。单击“Finish”按钮后,Studio 会生成模型和类。要更新此模型(创建后),您应该转到 Model Browser(双击“.edmx”文件),单击根对象,然后从数据库中选择“Update Model”。
  3. Model — 让我们创建两个类 — 分别用于国家和城市。第一个类 StaticData 包含一个用于获取城市列表的私有方法和一个公共属性。
    public class StaticData
    {
        public List<Country> CountryList
        {
            get
            {
                return GetAllCountries();
            }
        }
        private static List<Country> GetAllCountries()
        {
            List<Country> countries = null;
            using (DataCoreConnection context = new DataCoreConnection())
            {
                countries = (from c in context.Country
                             select c).ToList();
            }
            return countries;
        }
    }

    第二个城市类几乎相同,但构造函数接受一个参数,即城市所属国家的代码。

    public class Cities
    {
        private string countryCode;
        public Cities(string CountryCode)
        {
            countryCode = CountryCode;
        }
        public List<City> CitiesForCountry
        {
            get
            {
                return GetCitiesForCountry(countryCode);
            }
        }
        private List<City> GetCitiesForCountry(string CountryCode)
        {
            List<City> list = null;
            using (DataCoreConnection context = new DataCoreConnection())
            {
                list = (from c in context.City
                        where c.Country.Code == CountryCode
                        select c).ToList();
            }
            return list;
        }
    }
  4. Controller — 我们使用现有的 HomeController,因为我们的下拉列表在主页上。我们只添加一个 Action 方法来显示为城市下拉列表提供内容的视图。
    public void UpdateCities(string code)
    {
        Cities cities = new Cities(code);
        RenderView("SelectCity", cities);
    }

    在这里,我们获取一个城市列表(对象 Cities)并将其传递给 SelectCity 视图。别忘了在 Global.asax 中添加路由规则。

    routes.Add(new Route("Home/UpdateCities/{code}", 
    new RouteValueDictionary(new { controller = "Home", action = "UpdateCities" }),
        new MvcRouteHandler()));
  5. Views — 我们使用两个视图,一个用于包含静态数据的主页,另一个用于包含城市数据的下拉列表。从现有视图开始 — Index.aspx。由于我们应该将 StaticData 对象传递给它,因此我们的视图必须继承自 ViewPage,并且还必须继承自 ViewPage<StaticData>
    public partial class Index : ViewPage<StaticData>
    {
    }

    让我们在页面上显示国家列表。

    <select id="selCountry" onchange="UpdateCitiesList();">
        <option value="0" selected="selected"><Select a country></option>
    
        <% foreach (var country in ViewData.CountryList)
           { %>
            <option value='<%= country.Code %>'>
            <%= country.Name %>
            </option>
        <% } %>
    
        </select>

    这段代码非常简单,所以似乎没有必要解释。我注意到 ViewData 对象具有 StaticData 类型,因此我们可以调用其成员而无需任何强制类型转换。稍后将讨论获取城市列表的处理程序 UpdateCitiesList()。现在,让我们创建另一个视图来显示城市。

    public partial class SelectCity : ViewPage<Cities>
    
    {
    }

    然后,添加生成下拉列表内容的的代码。

    <option value="0"><Select a city></option>
    <% foreach (var city in ViewData.CitiesForCountry)
       { %>
    
    <option value='<%=city.Id %>'><%= city.Name %></option>
    
    <%} %>

    首先,我们应该添加一个指向 prototype 文件的链接(我在母版页上做了)。

    <script type="text/javascript" 
      src="<%= Page.ResolveClientUrl("~/Views/Scripts/prototype_p.js") %>"></script>

    现在,我们添加一些代码,它将在不重新加载整个页面的情况下从数据库获取数据。

    <script type="text/javascript" language="javascript">
        function UpdateCitiesList()
        {
            if ($('selCountry').value == "0")
                return;
                var url = '/Home/UpdateCities/' + $('selCountry').value;
            new Ajax.Updater('selCities', url,
            {
                method: 'get'
            }
                    );
        }
    </script>

    这段代码也很简单。首先,我们定义了下拉列表中哪个元素被选中。如果它是“0”元素(只包含文本“Select ...”),我们就退出函数。否则,我们创建一个 URL 来调用 Controller Home 和 Action 方法 UpdateCities(带有选定国家的代码),并调用 prototype 库对象 Ajax.Updater。此对象允许我们以异步方式获取数据,即,无需重新加载整个页面。

    一旦我们选择了一个国家,城市下拉列表就会更新。

加载并打开本文附带的解决方案。您可能会看到一个空白页 Default.aspx(SP1 中的 bug),或者可能看不到。无论如何,您需要使用此地址:localhost:NNN/Home/ 来查看结果。

最新更新

Microsoft 推出了 MVC Prerelease 的第 3 个版本,您可以在 此处加载。别忘了加载 Readme 文件(在下载页面的底部),您可以在其中找到更改的完整列表。我曾尝试按照 Readme 的建议重写我的项目,结果代码完全编译但完全无法运行(路由至今不起作用)。所以我创建了一个新项目(因为路由出于某种原因在这里起作用)并将所有文件迁移到那里。因此,您可以在文章的顶部找到 ASP.NET Prerelease 3 的新项目版本。

您可以在 我的博客 中找到此文章的俄语版本。

欢迎提出评论和建议!

© . All rights reserved.