做法有两种,一种是在StateProvince表里面加个字段,另一种是新建两个表,用来存市、县的数据,表结构完全按照StateProvince走就好了。我这里用的是第二种做法,菜鸟一枚,代码写的比较烂,哪里写的不好欢迎提出来以便我提高自己。

第一步:去数据库,新建两个表,表我就不给了,直接给对应的Model

 using System.Collections.Generic;
using Nop.Core.Domain.Localization; namespace Nop.Core.Domain.Directory
{
/// <summary>
/// Represents a state/province
/// </summary>
public partial class City : BaseEntity, ILocalizedEntity
{
private ICollection<County> _counties;
/// <summary>
/// Gets or sets the country identifier
/// </summary>
public int StateProvinceId { get; set; } /// <summary>
/// Gets or sets the name
/// </summary>
public string Name { get; set; } /// <summary>
/// Gets or sets the abbreviation
/// </summary>
public string Abbreviation { get; set; } /// <summary>
/// Gets or sets a value indicating whether the entity is published
/// </summary>
public bool Published { get; set; } /// <summary>
/// Gets or sets the display order
/// </summary>
public int DisplayOrder { get; set; } /// <summary>
/// Gets or sets the country
/// </summary>
public virtual StateProvince StateProvince { get; set; }
public virtual ICollection<County> Countys
{
get { return _counties ?? (_counties = new List<County>()); }
protected set { _counties = value; }
}
} }

City.cs

 using Nop.Core.Domain.Localization;

 namespace Nop.Core.Domain.Directory
{
/// <summary>
/// Represents a state/province
/// </summary>
public partial class County : BaseEntity, ILocalizedEntity
{
/// <summary>
/// Gets or sets the country identifier
/// </summary>
public int CityId { get; set; } /// <summary>
/// Gets or sets the name
/// </summary>
public string Name { get; set; } /// <summary>
/// Gets or sets the abbreviation
/// </summary>
public string Abbreviation { get; set; } /// <summary>
/// Gets or sets a value indicating whether the entity is published
/// </summary>
public bool Published { get; set; } /// <summary>
/// Gets or sets the display order
/// </summary>
public int DisplayOrder { get; set; } /// <summary>
/// Gets or sets the country
/// </summary>
public virtual City City { get; set; }
} }

County.cs

当然,还需要修改StateProvince的Model

 using System.Collections.Generic;
using Nop.Core.Domain.Localization; namespace Nop.Core.Domain.Directory
{
/// <summary>
/// Represents a state/province
/// </summary>
public partial class StateProvince : BaseEntity, ILocalizedEntity
{
private ICollection<City> _cities;
/// <summary>
/// Gets or sets the country identifier
/// </summary>
public int CountryId { get; set; } /// <summary>
/// Gets or sets the name
/// </summary>
public string Name { get; set; } /// <summary>
/// Gets or sets the abbreviation
/// </summary>
public string Abbreviation { get; set; } /// <summary>
/// Gets or sets a value indicating whether the entity is published
/// </summary>
public bool Published { get; set; } /// <summary>
/// Gets or sets the display order
/// </summary>
public int DisplayOrder { get; set; } /// <summary>
/// Gets or sets the country
/// </summary>
public virtual Country Country { get; set; }
public virtual ICollection<City> Citys
{
get { return _cities ?? (_cities = new List<City>()); }
protected set { _cities = value; }
}
} }

StateProvince.cs

第二步:去Service层去做Crud,县、市的基本是一样的,我就只列出来一个。另外一个照着写就完了。

先定义接口:

 using System.Collections.Generic;
using Nop.Core.Domain.Directory; namespace Nop.Services.Directory
{
public interface ICityService
{
void DeleteCity(City city);
City GetCityById(int cityId);
City GetByAbbreviation(string abbreviation);
IList<City> GetCityByStateProvinceId(int stateProvinceId, bool showHidden = false);
void InsertCity(City city);
void UpdateCity(City city);
}
}

ICityService.cs

去实现接口:

 using System;
using System.Collections.Generic;
using System.Linq;
using Nop.Core.Caching;
using Nop.Core.Data;
using Nop.Core.Domain.Directory;
using Nop.Services.Events; namespace Nop.Services.Directory
{
public partial class CityService:ICityService
{
#region Constants /// <summary>
/// Key for caching
/// </summary>
/// <remarks>
/// {1} : country ID
/// </remarks>
private const string CITYS_ALL_KEY = "Nop.city.all-{0}";
/// <summary>
/// Key pattern to clear cache
/// </summary>
private const string CITYS_PATTERN_KEY = "Nop.city."; #endregion #region Fields private readonly IRepository<City> _cityRepository;
private readonly IEventPublisher _eventPublisher;
private readonly ICacheManager _cacheManager; #endregion #region Ctor /// <summary>
/// Ctor
/// </summary>
/// <param name="cacheManager">Cache manager</param>
/// <param name="stateProvinceRepository">State/province repository</param>
/// <param name="eventPublisher">Event published</param>
public CityService(ICacheManager cacheManager,
IRepository<City> cityRepository,
IEventPublisher eventPublisher)
{
_cacheManager = cacheManager;
_cityRepository = cityRepository;
_eventPublisher = eventPublisher;
} #endregion
public void DeleteCity(City city)
{
if(city==null)
throw new ArgumentNullException("city");
_cityRepository.Delete(city);
_cacheManager.RemoveByPattern(CITYS_PATTERN_KEY);
_eventPublisher.EntityDeleted(city);
} public City GetCityById(int cityId)
{
if (cityId == )
{
return null;
}
return _cityRepository.GetById(cityId);
} public City GetByAbbreviation(string abbreviation)
{
var query = from sp in _cityRepository.Table
where sp.Abbreviation == abbreviation
select sp;
var city = query.FirstOrDefault();
return city;
} public IList<City> GetCityByStateProvinceId(int stateProvinceId, bool showHidden = false)
{
string key = string.Format(CITYS_ALL_KEY, stateProvinceId);
return _cacheManager.Get(key, () =>
{
var query= from sp in _cityRepository.Table
orderby sp.DisplayOrder
where sp.StateProvinceId == stateProvinceId &&
(showHidden || sp.Published)
select sp;
var city = query.ToList();
return city;
});
} public void InsertCity(City city)
{
if (city == null)
throw new ArgumentNullException("city"); _cityRepository.Insert(city); _cacheManager.RemoveByPattern(CITYS_PATTERN_KEY); //event notification
_eventPublisher.EntityInserted(city);
} public void UpdateCity(City city)
{
if (city == null)
throw new ArgumentNullException("city"); _cityRepository.Update(city); _cacheManager.RemoveByPattern(CITYS_PATTERN_KEY); //event notification
_eventPublisher.EntityUpdated(city);
}
}
}

CityService.cs

这是市的,县的照着这个写就完了。注意缓存那块也一定要给把那个Key给改了,不然会重名的。

第三步:去Nop.Web.Framework把刚写的这些Service注入。

  builder.RegisterType<CityService>().As<ICityService>().SingleInstance();
builder.RegisterType<CountyService>().As<ICountyService>().SingleInstance();

DependencyRegistrar.cs

第三步:修改他转换po和vo的方法,我这个做的是国内的电子商务网站,所以,国家那里我直接就写死了,而且在后续的界面中,我也直接把国家给干掉了。

 public static void PrepareModel(this AddressModel model,
Address address, bool excludeProperties,
AddressSettings addressSettings,
ILocalizationService localizationService = null,
IStateProvinceService stateProvinceService = null,
#region yunchen.bai
ICityService cityService=null,
ICountyService countyService=null ,
#endregion
Func<IList<Country>> loadCountries = null,
bool prePopulateWithCustomerFields = false,
Customer customer = null )
{
if (model == null)
throw new ArgumentNullException("model"); if (addressSettings == null)
throw new ArgumentNullException("addressSettings"); if (!excludeProperties && address != null)
{
model.Id = address.Id;
model.FirstName = address.FirstName;
model.LastName = address.LastName;
model.Email = address.Email;
model.Company = address.Company;
model.CountryId = address.CountryId;
model.CountryName = address.Country != null
? address.Country.GetLocalized(x => x.Name)
: null;
model.StateProvinceId = address.StateProvinceId;
model.StateProvinceName = address.StateProvince != null
? address.StateProvince.GetLocalized(x => x.Name)
: null;
model.City = address.City;
model.Address1 = address.Address1;
model.Address2 = address.Address2;
model.ZipPostalCode = address.ZipPostalCode;
model.PhoneNumber = address.PhoneNumber;
model.FaxNumber = address.FaxNumber;
} if (address == null && prePopulateWithCustomerFields)
{
if (customer == null)
throw new Exception("Customer cannot be null when prepopulating an address");
model.Email = customer.Email;
model.FirstName = customer.GetAttribute<string>(SystemCustomerAttributeNames.FirstName);
model.LastName = customer.GetAttribute<string>(SystemCustomerAttributeNames.LastName);
model.Company = customer.GetAttribute<string>(SystemCustomerAttributeNames.Company);
model.Address1 = customer.GetAttribute<string>(SystemCustomerAttributeNames.StreetAddress);
model.Address2 = customer.GetAttribute<string>(SystemCustomerAttributeNames.StreetAddress2);
model.ZipPostalCode = customer.GetAttribute<string>(SystemCustomerAttributeNames.ZipPostalCode);
model.City = customer.GetAttribute<string>(SystemCustomerAttributeNames.City);
//ignore country and state for prepopulation. it can cause some issues when posting pack with errors, etc
//model.CountryId = customer.GetAttribute<int>(SystemCustomerAttributeNames.CountryId);
//model.StateProvinceId = customer.GetAttribute<int>(SystemCustomerAttributeNames.StateProvinceId);
model.PhoneNumber = customer.GetAttribute<string>(SystemCustomerAttributeNames.Phone);
model.FaxNumber = customer.GetAttribute<string>(SystemCustomerAttributeNames.Fax);
} //countries and states
if (addressSettings.CountryEnabled && loadCountries != null)
{
if (localizationService == null)
throw new ArgumentNullException("localizationService"); model.AvailableCountries.Add(new SelectListItem() { Text = localizationService.GetResource("Address.SelectCountry"), Value = "" });
foreach (var c in loadCountries())
{
model.AvailableCountries.Add(new SelectListItem()
{
Text = c.GetLocalized(x => x.Name),
Value = c.Id.ToString(),
Selected = c.Id == model.CountryId
});
}
model.CountryId = ;
if (address != null)
{
model.CountyId = address.CountyId;
model.CityId = address.CityId;
}
if (addressSettings.StateProvinceEnabled)
{
//states
if (stateProvinceService == null)
throw new ArgumentNullException("stateProvinceService"); var states = stateProvinceService
.GetStateProvincesByCountryId()//这块直接给写死成中国
.ToList();
if (states.Count > )
{
foreach (var s in states)
{
model.AvailableStates.Add(new SelectListItem()
{
Text = s.GetLocalized(x => x.Name),
Value = s.Id.ToString(),
Selected = (s.Id == model.StateProvinceId)
});
}
}
else
{
model.AvailableStates.Add(new SelectListItem()
{
Text = localizationService.GetResource("Address.OtherNonUS"),
Value = ""
});
}
#region yunchen.bai 2014.10.27
if (cityService == null)
throw new ArgumentNullException("cityService");
var firstProvince = stateProvinceService.GetStateProvincesByCountryId().FirstOrDefault() ??
new StateProvince();
var citys =
cityService.GetCityByStateProvinceId(model.StateProvinceId != null
? model.StateProvinceId.Value
: firstProvince.Id).ToList();
var firstCity = cityService.GetCityByStateProvinceId(firstProvince.Id).FirstOrDefault() ??
new City();
if (citys.Count > )
{
foreach (var c in citys)
{
model.AvailableCity.Add(new SelectListItem()
{
Text = c.GetLocalized(x=>x.Name),
Value = c.Id.ToString(),
Selected = (c.Id==model.CityId)
});
}
}
else
{
model.AvailableCity.Add(new SelectListItem()
{
Text = localizationService.GetResource("Address.OtherNonUS"),
Value = ""
});
}
if(countyService==null)
throw new ArgumentNullException("countyService");
var counties = countyService.GetCountyByCityId(model.CityId.HasValue?model.CityId.Value:firstCity.Id);
if (counties.Count > )
{
foreach (var county in counties)
{
model.AvailableCounty.Add(new SelectListItem()
{
Text = county.GetLocalized(x=>x.Name),
Value = county.Id.ToString(),
Selected = (county.Id==model.CityId)
});
}
}
else
{
model.AvailableCity.Add(new SelectListItem()
{
Text = localizationService.GetResource("Address.OtherNonUS"),
Value = ""
});
} #endregion }
}

MappingExtensions.cs

未完待续.....

NopCommerce 3.4省市联动的更多相关文章

  1. jquery省市联动,根据公司需求而写

    //author:guan //2015-05-25 //省市联动 //实用说明,页面引用如下js //<script src="../js/jquery-1.6.3.min.js&q ...

  2. Json 基于jQuery+JSON的省市联动效果

    helloweba.com 作者:月光光 时间:2012-09-12 21:57 标签: jQuery  JSON  Ajax  省市联动     省市区联动下拉效果在WEB中应用非常广泛,尤其在一些 ...

  3. AJAX案例四:省市联动

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...

  4. Dynamic CRM 2013学习笔记(八)过滤查找控件 (类似省市联动)

    我们经常要实现类似省市联动一样的功能,常见的就是二个查找控件,一个选择了省后,另一个市的查找控件就自动过滤了,只显示当前省下的市,而不是所有的市.当然这是最简单的,实际工作中还有更复杂的功能要通过过滤 ...

  5. [JS]以下是JS省市联动菜单代码

    以下是JS省市联动菜单代码: 代码一: <html> <head> <title></title> <script language=" ...

  6. 通过Javascript数组设计一个省市联动菜单

    通过Javascript数组设计一个省市联动菜单 使用Option内置类来完成下拉选项的创建 2.使用定时器实现一个时钟程序 3.使用PHP+JSON完成语音验证码 网址:http://yuyin.b ...

  7. Ado.Net小练习03(省市联动)

    前台界面:          后台代码: namespace _04省市联动 {     public partial class Form1 : Form     {         public ...

  8. Ajax省市联动

    以JQuery为JS,写的Ajax省市联动. 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&q ...

  9. html + ashx 实现Ajax省市联动

    基本思路:1.了解数据库中省和市的表结构及关联主键 2.创建html页面及select标签 3.通过ajax向ashx(一般处理程序)发送后台请求完成联动效果 表结构: 这里,开始创建一个命为demo ...

随机推荐

  1. Discuz x3 UCenter实现同步登陆原理

    1.Discuz x3 的登录页面URL是:/member.php?mod=logging&action=login 2.这个登录页面,登录提交的地址是: <form method=&q ...

  2. window.open在Safari中不能打开的问题

    在调移动支付问题的时候遇到过,用window.open打开一个微信支付链接,唤醒移动支付,在IOS下死活唤醒不了,是js代码冲突问题...是click事件IOS下不兼容问题...最后定位到window ...

  3. JS之捕获冒泡和事件委托

    一.事件流(捕获,冒泡)   事件流:指从页面中接收事件的顺序,有冒泡流和捕获流. 当页面中发生某种事件(比如鼠标点击,鼠标滑过等)时,毫无疑问子元素和父元素都会接收到该事件,可具体顺序是怎样的呢?冒 ...

  4. HTML颜色代码

    记录十种个人比较喜欢的颜色: #19CAAD   #8CC7B5  #A0EEE1  #BEE7E9  #BEEDC7 #D6D5B7  #D1BA74  #E6CEAC  #ECAD9E  #F46 ...

  5. vscode自定义代码块

    vscode中设置自定义代码块打开首选项,选择用户代码片段,打开后选择编程语言选中后打开文件,按照格式编辑内容 "Print to console log": { "pr ...

  6. openlayers模仿google地图--地图版权随鹰眼关闭打开而改变位置

    额..题目有点长......今天有个群友问我.想实现google地图地图版权随鹰眼关闭状态改变位置的功能.就是这种<ignore_js_op> 打开鹰眼时  地图版权也随着鹰眼位置改变而改 ...

  7. Android GridView设置行数

    普通的做法是设置一个高度,然后里面能显示出来几行就是几行,如果里面的内容高度变了,就需要重新调整高度来适配. 观察了一下它的onMeasure @Override protected void onM ...

  8. Python爬虫教程-23-数据提取-BeautifulSoup4(一)

    Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据,查看文档 https://www.crummy.com/software/BeautifulSoup/bs4/doc. ...

  9. c# 值类型与引用类型(转)

    本文意在巩固基础知识,并不是对其进行深入剖析,还望理解.本文是对此项知识的整理文,有些内容来源于网络,其他为博主原创,所以难免会有一些小得瑕疵,敬请谅解.所有示例均是博主测试过的,如有转载请标明出处, ...

  10. Service Discovery in WCF 4.0 – Part 1 z

    Service Discovery in WCF 4.0 – Part 1 When designing a service oriented architecture (SOA) system, t ...