做法有两种,一种是在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. 反汇编调试Android

    https://code.google.com/p/android/issues/detail?id=73076 http://my.unix-center.net/~Simon_fu/?p=527 ...

  2. CSS实现微信对话框

  3. javascript闭包中循环问题

    如下的html,为什么每次输出都是5,而不是点击每个p,就alert出对应的1,2,3,4,5. <html > <head> <meta http-equiv=&quo ...

  4. Bzoj2654:tree

    题目 Bzoj Sol 神题! 二分所有的白边减去一个值,这样做\(kruskal\)就会多选一些白边 就这样 二分范围为\([-101, 101]\)!!! # include <bits/s ...

  5. js String字符串对象常见方法总结

    String对象常用来保存文本形式的数据. 其转化方法有二种: String(s) new String(s) String对象方法有: charAt() charCodeAt() concat() ...

  6. C++类继承--继承后函数的值

    类的继承会首先寻找基类,若基类未实现,则会寻找派生类的函数 1. class继承,函数不继承 #include <stdio.h> class Base { public: Base(){ ...

  7. vs2010开发activex(MFC)控件/ie插件(三),js调用ocx控件的接口函数

    原文:http://blog.csdn.net/yhhyhhyhhyhh/article/details/50802280   js调用ocx控件的接口函数,先看demo效果:      简单测试过程 ...

  8. listview cacheColorHint,listSelector属性

    ListView是常用的显示控件,默认背景是和系统窗口一样的透明色,如果给ListView加上背景图片,或者背景颜色时,滚动时listView会黑掉, 原因是,滚动时,列表里面的view重绘时,用的依 ...

  9. 在IDEA中设置方法自动注释(带参数和返回值)

    第一部分 设置 打开设置面板 新建 在线模板 新建自动添加规则,注意 这里触发的字符 不能随便写 必须为 * Template text 区域 看上去有点乱,但是是为了显示时的对齐,该区域的内容如下( ...

  10. Linux 学习笔记之关机问题

    在linux领域内大多用在服务器上,很少遇到关机的操作. 正确的关机流程为:sync > shutdown > reboot > halt 关机指令为:shutdown ,你可以ma ...