- / 获取FCKEditor中的内容: content为Editor实例的ID
- function getEditorContents(){
- var oEditor = FCKeditorAPI.GetInstance(“content”);
- alert(oEditor.GetXHTML(true));
- }
- // 向编辑器插入指定代码
- function insertHTMLToEditor(codeStr){
- var oEditor = FCKeditorAPI.GetInstance(“content”);
- if (oEditor.EditMode==FCK_EDITMODE_WYSIWYG){
- oEditor.InsertHtml(codeStr);
- }else{
- return false;
- }
- }
- // 统计编辑器中内容的字数
- function getLength(){
- var oEditor = FCKeditorAPI.GetInstance(“content”);
- var oDOM = oEditor.EditorDocument;
- var iLength ;
- if(document.all){
- iLength = oDOM.body.innerText.length;
- }else{
- var r = oDOM.createRange();
- r.selectNodeContents(oDOM.body);
- iLength = r.toString().length;
- }
- alert(iLength);
- }
- // 执行指定动作
- function ExecuteCommand(commandName){
- var oEditor = FCKeditorAPI.GetInstance(“content”) ;
- oEditor.Commands.GetCommand(commandName).Execute() ;
- }
- // 设置编辑器中内容
- function SetContents(codeStr){
- var oEditor = FCKeditorAPI.GetInstance(“content”) ;
- oEditor.SetHTML(codeStr) ;
- }
[转载]ASP.NET MVC 3 开发的20个秘诀(十二)[20 Recipes for Programming MVC 3]:缩放图片尺寸创建缩略图
[转载][翻译]ASP.NET MVC 3 开发的20个秘诀(十二)[20 Recipes for Programming MVC 3]:缩放图片尺寸创建缩略图 – O2DS – 博客园.
议题
用户上传到网站上的大多数的图片都是大尺寸的照片,通常在用户想看完整图片之前网站会展示出这些图片或照片的缩略图。
解决方案
使用以下的类来调整上传的图片文件的宽和高:FileStream,Image,Bitmap和Graphics。
讨论
在下面的示例中,将修改和重组之前创建的FileUpload类。创建一个新的称为“ResizeImage”的方法来调整图片大小。调整之后的图 片文件将被保存到源文件存储文件夹的子文件夹“Thumbnails”中。同时也要修改DeleteFile方法,添加同时删除原始图像和缩略图,并且为 了避免重复代码要创建一个新的删除功能的方法。下面显示变化部分的类代码:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.IO; using System.Drawing; using System.Drawing.Drawing2D; namespace MvcApplication4.Utils { public static class FileUpload { public static char DirSeparator = System.IO.Path.DirectorySeparatorChar; public static string FilesPath = "Content" + DirSeparator + "Uploads" + DirSeparator; public static string UploadFile(HttpPostedFileBase file) { ... // 保存缩略图 ResizeImage(file, 150, 100); ... } public static void DeleteFile(string fileName) { // 如果没有指定文件名就什么都不做 if (fileName.Length == 0) return; // 设置删除路径 string path = FilesPath + DirSeparator + fileName; string thumbPath = FilesPath + DirSeparator + "Thumbnails" + DirSeparator + fileName; RemoveFile(path); RemoveFile(thumbPath); } private static void RemoveFile(string path) { // 检查文件是否存在 if (File.Exists(Path.GetFullPath(path))) { // 删除文件 File.Delete(Path.GetFullPath(path)); } } public static void ResizeImage(HttpPostedFileBase file, int width, int height) { string thumbnailDirectory = String.Format(@"{0}{1}{2}", FilesPath, DirSeparator, "Thumbnails"); // 检查目标文件夹是否存在 if (!Directory.Exists(thumbnailDirectory)) { // 假如文件夹不存在就创建它 Directory.CreateDirectory(thumbnailDirectory); } // 设置缩略图保存路径 string imagePath = String.Format(@"{0}{1}{2}", thumbnailDirectory, DirSeparator, file.FileName); // 将文件流保存到磁盘 FileStream stream = new FileStream(Path.GetFullPath( imagePath), FileMode.OpenOrCreate); // 缩放上传的文件 Image OrigImage = Image.FromStream(file.InputStream); // 创建缩略图对象 Bitmap TempBitmap = new Bitmap(width, height); // 创建缩略图画质 Graphics NewImage = Graphics.FromImage(TempBitmap); NewImage.CompositingQuality = CompositingQuality.HighQuality; NewImage.SmoothingMode = SmoothingMode.HighQuality; NewImage.InterpolationMode = InterpolationMode.HighQualityBicubic; // 创建Rectangle对象进行绘制 Rectangle imageRectangle = new Rectangle(0, 0, width, height); NewImage.DrawImage(OrigImage, imageRectangle); // 保存缩略图 TempBitmap.Save(stream, OrigImage.RawFormat); // 释放资源 NewImage.Dispose(); TempBitmap.Dispose(); OrigImage.Dispose(); stream.Close(); stream.Dispose(); } } }
在上面的示例中,我们做了许多修改,特别创建ResizeImage方法。首先,判断“Thumbnails”文件夹是否存在以及创建功能。接下来,会创建一个新的FileStream对象,并将编辑后的图片保存到“Thumbnails”文件夹中。
从提交的InputStream创建原始图片对象。然后基于缩略图的尺寸创建缩略图的Bitmap位图实例。然后基于这个Bitmap对象创建新的 Graphics对象,然后设置图像的画质、平滑度、插值模式,如果不设置这些值,缩略图会因为很像素化和比例变形变的很难看。
将这些值都设置完毕,创建一个原始尺寸的Recangle对象,将这个对象缩放后绘制到之前创建的Graphics对象中,这时才实际调整尺寸。最后保存Bitmap对象,释放所有资源。
参考
[转载]c# 扩展方法奇思妙用基础篇八:Distinct 扩展
[转载]c# 扩展方法奇思妙用基础篇八:Distinct 扩展 – 鹤冲天 – 博客园.
刚看了篇文章 《Linq的Distinct太不给力了》,文中给出了一个解决办法,略显复杂。
试想如果能写成下面的样子,是不是更简单优雅:
1 2 |
var p1 = products.Distinct(p => p.ID); var p2 = products.Distinct(p => p.Name); |
使用一个简单的 lambda 作为参数,也符合 Linq 一贯的风格。
可通过扩展方法 实现:
Distinct 扩展方法
首先,创建一个通用比较的类,实现 IEqualityComparer<T> 接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Linq; public class CommonEqualityComparer<T, V> : IEqualityComparer<T> { private Func<T, V> keySelector; public CommonEqualityComparer(Func<T, V> keySelector) { this.keySelector = keySelector; } public bool Equals(T x, T y) { return EqualityComparer<V>.Default.Equals(keySelector(x), keySelector(y)); } public int GetHashCode(T obj) { return EqualityComparer<V>.Default.GetHashCode(keySelector(obj)); } } |
第 17 行,用到了 EqualityComparer<T> 类,本文最后有简要说明。
借助上面这个类,Distinct 扩展方法就很好写了:
1 2 3 4 5 6 7 |
public static class DistinctExtensions { public static IEnumerable<T> Distinct<T, V>(this IEnumerable<T> source, Func<T, V> keySelector) { return source.Distinct(new CommonEqualityComparer<T, V>(keySelector)); } } |
呵呵,简单吧!
Distinct 使用示例
根据 ID :
1 2 3 4 5 6 7 |
var data1 = new Person[] { new Person{ ID = 1, Name = "鹤冲天"}, new Person{ ID = 1, Name = "ldp"} }; var ps1 = data1 .Distinct(p => p.ID) .ToArray(); |
根据 Name:
1 2 3 4 5 7 |
var data2 = new Person[] { new Person{ ID = 1, Name = "鹤冲天"}, new Person{ ID = 2, Name = "鹤冲天"} }; var ps2 = data2 .Distinct(p => p.Name) .ToArray(); |
看了回复后,我做了些改进,推荐使用下面的方式:
改进
回复中有朋友提到“不区分大小写地排除重复的字符串”,也不难实现,只需要把上面的代码改进下就 OK:
CommonEqualityComparer<T, V> 类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Linq; public class CommonEqualityComparer<T, V> : IEqualityComparer<T> { private Func<T, V> keySelector; private IEqualityComparer<V> comparer; public CommonEqualityComparer(Func<T, V> keySelector, IEqualityComparer<V> comparer) { this.keySelector = keySelector; this.comparer = comparer; } public CommonEqualityComparer(Func<T, V> keySelector) : this(keySelector, EqualityComparer<V>.Default) { } public bool Equals(T x, T y) { return comparer.Equals(keySelector(x), keySelector(y)); } public int GetHashCode(T obj) { return comparer.GetHashCode(keySelector(obj)); } } |
Distinct 扩展方法:
1 2 3 4 5 6 7 8 9 10 11 12 |
public static class DistinctExtensions { public static IEnumerable<T> Distinct<T, V>(this IEnumerable<T> source, Func<T, V> keySelector) { return source.Distinct(new CommonEqualityComparer<T, V>(keySelector)); } public static IEnumerable<T> Distinct<T, V>(this IEnumerable<T> source, Func<T, V> keySelector, IEqualityComparer<V> comparer) { return source.Distinct(new CommonEqualityComparer<T, V>(keySelector, comparer)); } } |
借助可选参数,这两个扩展方法也可以合成一个:
1 2 3 4 5 |
public static IEnumerable<T> Distinct<T, V>(this IEnumerable<T> source, Func<T, V> keySelector, IEqualityComparer<V> comparer = EqualityComparer<V>.Default)
{
return source.Distinct(new CommonEqualityComparer<T, V>(keySelector, comparer));
}
|
(同样,CommonEqualityComparer<T, V>类的两个构造函数也可以合二为一)
使用示例:
1 2 3 4 5 6 7 |
var data3 = new Person[] { new Person{ ID = 1, Name = "LDP"}, new Person{ ID = 2, Name = "ldp"} }; var ps3 = data3 .Distinct(p => p.Name, StringComparer.CurrentCultureIgnoreCase) .ToArray(); |
EqualityComparer<T> 类 简要说明
EqualityComparer<T>为 IEqualityComparer<T> 泛型接口的实现提供基类,它在 .net 4 中有五个重要的子类,见下图:
这五个子类分别用不同类型数据的相等性比较,从类名我们可以略知一二。
这五个子类都是内部类(internal),不能直接访问,EqualityComparer<T> 类提供一个简单的属性 Default。EqualityComparer<T> 会根据传入的 T 的类型,加载不同的子类,并会予以缓存提高性能。
——————-
[转载]ASP.NET MVC3 20个秘方-(19)URL—其实我更想懂你:路由用户到特定的Controller和Action
[转载]【译】MVC3 20个秘方-(19)URL—其实我更想懂你:路由用户到特定的Controller和Action – 技术弟弟 – 博客园.
问题
当今如此对搜索引擎霸主的争夺战是如此激烈,像下边这样的网站地址很难在这场比赛中获胜:http://www.example.com/books/details?id=4
使用路由,网站可以变成这样:
http://www.example.com/20-recipes-for-mvc3
无论是对用户还是搜索引擎,这将提供更多的语境。
解决方案
使用RouteCollectionExtensions 类下的MapRoute 函数去生成更友好的名字去展示内容而不是数字ID。
讨论
在MVC中可以通过Web.config和Global.asax.cs文件设置路由。在web.config中包含 System.Web.Routing程序集并且在Global.asax.cs中使用它去对在它其中的所有controller和action创建一个 默认的路由机制。因此在添加BooksController的时候,可以通过/Books 访问不带扩展名的 URL,就像在ASP.NET 官网那样。
接下来的秘方将演示设立几个不同的有用的技术去创建路由。
第一个路由将允许网站直接连接到book的title上。例如,有一本书叫MVC3的20个秘方,它可以通过http://localhost /20 Recipes for Programming MVC 3这个地址被直接访问。然而当前的解决方案就需要一个更复杂的URL就像:http://localhost/Books/Details?id=1。 要开始创建这个路由,打开在MVC project里的Global.asax.cs文件。在RegisterRoutes()函数里创建里了一个默认的路由。在第一次加载网站的时候 Application_Start()函数会调用它。下边的例子包含一个更新的RegisterRoutes 函数,添加了一个新的路由到MapRoute函数中:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; using MvcApplication.Models; using System.Data.Entity; using System.Globalization; using System.Threading; namespace MvcApplication { public class MvcApplication : System.Web.HttpApplication { public static void RegisterGlobalFilters( GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); } public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "BookName", // Route name "{Keyword}", // URL with parameters new { controller = "Books", action = "Index", id = UrlParameter.Optional }, new { Keyword = "\\w+" }); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } protected void Application_Start() { Database.SetInitializer<BookDBContext>( new BookInitializer()); AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); } protected void Application_AcquireRequestState( object sender, EventArgs e) { if (HttpContext.Current.Session != null) { CultureInfo ci = (CultureInfo)this.Session["CurrentLanguage"]; if (ci == null) { ci = new CultureInfo("en"); this.Session["CurrentLanguage"] = ci; } Thread.CurrentThread.CurrentUICulture = ci; Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name); } } } }
在上边的例子里,MapRoute 函数接收4个参数。
- route name,在这里是BookName。
- 附带任何参数的URL。在这里是{Keyword},这是可变的,一会儿会用到。
- 这个参数默认的是controller ,action和任何附加的变量。在这个例子里,默认的controller是Books 并且Action是Index
- 他包含(例如,变量)对于URL。在这里,前边提到的Keyword变量传递到BooksController的Index action上。
当搜索关键字时,他可以在URL的域名后边输入一个书名或关键字,如果仅仅返回了一个结果,用户将被重定向到详细信息页面,并看到那本书。否则用户 将看到一个根据他关键字的搜索结果。在下一个例子里。一个新的路由将被创建。它将口占RouteBase类。均需一个更复杂的路由。将用一个子域名替代在 域名后边输入书名。例如 http://mvc3book.localhost/ 将返回上述图书的详细内容-MVC3编程的20个秘方。
为了让这成为可能,BOOK model 需要被更新去包含一个新的参数,名为“ShortName”。 此参数将被用来作为子域,并允许书籍通过创建扩展的RouteBase类的类进行搜索。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.ComponentModel.DataAnnotations; using MvcApplication.Validations; namespace MvcApplication.Models { public class Book { public int ID { get; set; } [Required] public string ShortName { get; set; } [Required] [Display(Name = "TitleDisplay", ResourceType = typeof(Resources.Resource1))] public string Title { get; set; } [Display(Name = "IsbnDisplay", ResourceType = typeof(Resources.Resource1))] [Required] [IsbnValidation] public string Isbn { get; set; } [Display(Name = "SummaryDisplay", ResourceType = typeof(Resources.Resource1))] [Required] public string Summary { get; set; } [Display(Name = "AuthorDisplay", ResourceType = typeof(Resources.Resource1))] [Required] public string Author { get; set; } [Display(Name = "ThumbnailDisplay", ResourceType = typeof(Resources.Resource1))] public string Thumbnail { get; set; } [Display(Name = "PriceDisplay", ResourceType = typeof(Resources.Resource1))] [Range(1, 100)] public double Price { get; set; } [Display(Name = "PublishedDisplay", ResourceType = typeof(Resources.Resource1))] [DataType(DataType.Date)] [Required] public DateTime Published { get; set; } } }
现在必须创建一个新的类将包含新的路由背后的逻辑。选择Utils文件夹中,右键单击并选择“添加→类。这个新的类将被称为 BookDomainRoute.cs。下面的类将从Request.Headers为当前HttpContext检索域名。该域名将被.”操作符的分成 “数组。执行一些错误检查以确保我们有一个子域名不是WWW。
第一块子域,例如,ShortName,是用来执行书本上表的搜索,找到特定书籍。如果查找到了书籍,创建一个新的对象类RouteData,设置 Controller为Books,Action 设置为Detail,最后的ID是这本书的ID。如果没有找到书籍,主页将显示出来。在下面的例子,它可以很容易改变以直接导航用户到一个错误页或根据 Keyword 跳转到Books/index 页(在前面的例子)。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Routing; using System.Web.Mvc; using MvcApplication.Models; namespace MvcApplication.Utils { public class BookDomainRoute : RouteBase { private BookDBContext db = new BookDBContext(); public override RouteData GetRouteData(HttpContextBase httpContext) { // Get the domain name var url = httpContext.Request.Url.Authority; // Split into array of parts var pieces = url.Split('.'); // Ensure there is a subdomain and it's not www if (pieces.Length < 2 && pieces[0] != "www") { return null; } string ShortName = pieces[0]; // Find the book by ShortName var books = from b in db.Books select b; books = books.Where(b => b.ShortName.ToUpper().Contains(ShortName.ToUpper())); // Check to make sure a book was found if (books.Count() == 0) { return null; } // Get the first result Book book = books.First(); // Set the route data RouteData routeData = new RouteData(this, new MvcRouteHandler()); routeData.Values.Add("controller", "Books"); routeData.Values.Add("action", "Details"); routeData.Values.Add("id", book.ID); return routeData; } public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) { return null; } } }
最后Global.asax.cs文件必须再次更新,包括新创建的路由。为了使新的路由类可以找到。需要添加using语句到utils目录。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; using MvcApplication.Models; using System.Data.Entity; using System.Globalization; using System.Threading; using MvcApplication.Utils; namespace MvcApplication { // Note: For instructions on enabling IIS6 or IIS7 classic mode, // visit http://go.microsoft.com/?LinkId=9394801 public class MvcApplication : System.Web.HttpApplication { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); } public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.Add(new BookDomainRoute()); routes.MapRoute( "BookName", // Route name "{Keyword}", // URL with parameters new { controller = "Books", action = "Index", id = UrlParameter.Optional }, // Parameter defaults new { Keyword = "\\w+" }); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults ); } protected void Application_Start() { Database.SetInitializer<BookDBContext>(new BookInitializer()); AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); String connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["BooksDBContext"].ConnectionString; System.Web.Caching.SqlCacheDependencyAdmin.EnableNotifications(connectionString); System.Web.Caching.SqlCacheDependencyAdmin.EnableTableForNotifications(connectionString, "Books"); } protected void Application_AcquireRequestState(object sender, EventArgs e) { if (HttpContext.Current.Session != null) { CultureInfo ci = (CultureInfo)this.Session["CurrentLanguage"]; if (ci == null) { ci = new CultureInfo("en"); this.Session["CurrentLanguage"] = ci; } Thread.CurrentThread.CurrentUICulture = ci; Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name); } } } }
上述的例子包含良好的使用路由的伟大的开始。两者都可以很容易地更新执行其他路由,例如,子域名可以用来显示用户的特定的个人资料页,或以前实施的 多语种秘方可更新为使用一个路由类允许象en.example.com或fr.example.com一样的URL设置当前的语言文化。
另请参见
[转载]实例:在Android调用WCF服务
[转载][翻译]实例:在Android调用WCF服务 – 一味 – 博客园.
原文:http://fszlin.dymetis.com/post/2010/05/10/Comsuming-WCF-Services-With-Android.aspx
在移动设备中,使用XML传输可能会消耗更多的资源,Android没有提供任何组件来直接调用WCF,但是我们可以通过第三方的包(例如:org.apache.http,org.json)来相对简单的调用REST形式的WCF服务。
本文将演示如何创建REST形式的WCF服务和在Android上如何调用服务。
第一步,创建一个包含两个GET操作和一个POST操作的Service Contract。由于是通过JSON对象传输数据,这里需要指定Request和Response的数据格式为JSON。为了支持多个参数,还需要设置 BodyStyle为WrappedRequest。
1 namespace HttpWcfWeb 2 { 3 [ServiceContract(Namespace = "http://services.example.com")] 4 public interface IVehicleService 5 { 6 [OperationContract] 7 [WebGet( 8 UriTemplate = "GetPlates", 9 BodyStyle = WebMessageBodyStyle.WrappedRequest, 10 ResponseFormat = WebMessageFormat.Json, 11 RequestFormat = WebMessageFormat.Json)] 12 IList<string> GetPlates(); 13 14 [OperationContract] 15 [WebGet(UriTemplate = "GetVehicle/{plate}", 16 BodyStyle = WebMessageBodyStyle.WrappedRequest, 17 ResponseFormat = WebMessageFormat.Json, 18 RequestFormat = WebMessageFormat.Json)] 19 Vehicle GetVehicle(string plate); 20 21 [OperationContract] 22 [WebInvoke( 23 Method = "POST", 24 UriTemplate = "SaveVehicle", 25 BodyStyle = WebMessageBodyStyle.WrappedRequest, 26 ResponseFormat = WebMessageFormat.Json, 27 RequestFormat = WebMessageFormat.Json)] 28 void SaveVehicle(Vehicle vehicle); 29 } 30 }
下一步,定义一个用于数据传输的对象,这个对象很简单。
1 namespace HttpWcfWeb 2 { 3 [DataContract] 4 public class Vehicle 5 { 6 [DataMember(Name = "year")] 7 public int Year 8 { 9 get; 10 set; 11 } 12 13 [DataMember(Name = "plate")] 14 public string Plate 15 { 16 get; 17 set; 18 } 19 20 [DataMember(Name = "make")] 21 public string Make 22 { 23 get; 24 set; 25 } 26 27 [DataMember(Name = "model")] 28 public string Model 29 { 30 get; 31 set; 32 } 33 } 34 }
现在,我们修改web.config文件,发布WCF服务。
<system.serviceModel> <behaviors> <endpointBehaviors> <behavior name="httpBehavior"> <webHttp /> </behavior> </endpointBehaviors> <serviceBehaviors> <behavior name=""> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> <services> <service name="HttpWcfWeb.VehicleService"> <endpoint address="" behaviorConfiguration="httpBehavior" binding="webHttpBinding" contract="HttpWcfWeb.IVehicleService" /> </service> </services> </system.serviceModel>
由于VS内置的开发服务器只能处理来自本机的请求,所以需要把服务部署到IIS。
另外,如果你在URL中使用主机名(比如:机器名)的话,你也许还需要在设备或模拟器中设置DNS,这样才可以解析主机名。方法是,进入“系统设置 (Setting)”->无线网络设置(Wireless Control)->网络接入点,选择正在使用的那一个,填写代理和端口。
现在,我需要创建Android客户端来调用WCF服务。
在启动过程中,活动(Activity)调用IVehicleService.GetPlates方法填充Spinner。
当Load Vehicle按钮点击时,通过调用IVehicleService.GetVehicle方法得到Vehicle对象并填充到EditText中。
点击Save按钮时,将数据包装并提交到IVehicleService.SaveVehicle方法。
public class MainActivity extends Activity { private final static String SERVICE_URI = "http://lt0.studio.entail.ca:8080/VehicleService.svc"; private Spinner plateSpinner; private EditText makeEdit; private EditText plateEdit; private EditText yearEdit; private EditText modelEdit; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); plateSpinner = (Spinner)findViewById(R.id.plate_spinner); makeEdit = (EditText)findViewById(R.id.make_edit); plateEdit = (EditText)findViewById(R.id.plate_edit); yearEdit = (EditText)findViewById(R.id.year_edit); modelEdit = (EditText)findViewById(R.id.model_edit); } @Override public void onResume() { super.onResume(); // Invoke IVehicleService.GetPlates and populate plateSpinner refreshVehicles(); } }
在数据保存或者Activity被恢复(resumed)的时候会调用refreshVehicles方法,它向WCF服务发送一个Get请求,得到一个由JSON字符串表达的数据对象。
private void refreshVehicles() { try { // Send GET request to <service>/GetPlates HttpGet request = new HttpGet(SERVICE_URI + "/GetPlates"); request.setHeader("Accept", "application/json"); request.setHeader("Content-type", "application/json"); DefaultHttpClient httpClient = new DefaultHttpClient(); HttpResponse response = httpClient.execute(request); HttpEntity responseEntity = response.getEntity(); // Read response data into buffer char[] buffer = new char[(int)responseEntity.getContentLength()]; InputStream stream = responseEntity.getContent(); InputStreamReader reader = new InputStreamReader(stream); reader.read(buffer); stream.close(); JSONArray plates = new JSONArray(new String(buffer)); // Reset plate spinner ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); for (int i = 0; i < plates.length(); ++i) { adapter.add(plates.getString(i)); } plateSpinner.setAdapter(adapter); } catch (Exception e) { e.printStackTrace(); } }
onLoadVehicleClick 方法处理Load Vehicle 点击事件,和refreshVehicles 方法相似,它发送一个GET请求到WCF服务,通过plate number得到一个vehicle对象,但区别在于,它在结果处理中使用了JSONObject 转换,就像直接从WCF服务中拿到的vehicle对象一样。
public void onLoadVehicleClick(View button) { try { // Send GET request to <service>/GetVehicle/<plate> DefaultHttpClient httpClient = new DefaultHttpClient(); HttpGet request = new HttpGet(SERVICE_URI + "/GetVehicle/" + plateSpinner.getSelectedItem()); request.setHeader("Accept", "application/json"); request.setHeader("Content-type", "application/json"); HttpResponse response = httpClient.execute(request); HttpEntity responseEntity = response.getEntity(); // Read response data into buffer char[] buffer = new char[(int)responseEntity.getContentLength()]; InputStream stream = responseEntity.getContent(); InputStreamReader reader = new InputStreamReader(stream); reader.read(buffer); stream.close(); JSONObject vehicle = new JSONObject(new String(buffer)); // Populate text fields makeEdit.setText(vehicle.getString("make")); plateEdit.setText(vehicle.getString("plate")); modelEdit.setText(vehicle.getString("model")); yearEdit.setText(vehicle.getString("year")); } catch (Exception e) { e.printStackTrace(); } }
当Save按钮点击时,调用onSaveVehicleClick 方法。这个方法中简单的将所有的文本字段的值放入一个JSONObject对象,然后提交(POST)给WCF服务。注意所有的数据包装进了一个叫vehicle的对象,WCF收到后,会将其作为名称为vehicle的参数。
public void onSaveVehicleClick(View button) { try { Editable make = makeEdit.getText(); Editable plate = plateEdit.getText(); Editable model = modelEdit.getText(); Editable year = yearEdit.getText(); boolean isValid = true; // Data validation goes here if (isValid) { // POST request to <service>/SaveVehicle HttpPost request = new HttpPost(SERVICE_URI + "/SaveVehicle"); request.setHeader("Accept", "application/json"); request.setHeader("Content-type", "application/json"); // Build JSON string JSONStringer vehicle = new JSONStringer() .object() .key("vehicle") .object() .key("plate").value(plate) .key("make").value(make) .key("model").value(model) .key("year").value(Integer.parseInt(year.toString())) .endObject() .endObject(); StringEntity entity = new StringEntity(vehicle.toString()); request.setEntity(entity); // Send request to WCF service DefaultHttpClient httpClient = new DefaultHttpClient(); HttpResponse response = httpClient.execute(request); Log.d("WebInvoke", "Saving : " + response.getStatusLine().getStatusCode()); // Reload plate numbers refreshVehicles(); } } catch (Exception e) { e.printStackTrace(); } }
最后,在AndroidManifest.xml中添加Internet的访问权限。
<uses-permission android:name="android.permission.INTERNET" />
DEMO可以运行。
[原创]EasyUI的Form中fckeditor编辑器不显示编辑的值问题解决办法
最近项目需要用到页面编辑器,于是沿用以前项目的代码,使用fckeditor编辑器,具体整合方法见[原创]JQuery的FckEditor插件使用教程,按上述方法整合后的代码如下:
$(function(){
//初始化FCKEditor
$.fck.config = { path: ‘../../FCKeditor/’, width: 700, height: 300, toolbar: ‘Basic’ };
$(‘textarea#Meeting_Content’).fck();
});
但是编辑数据时编辑器显示不出值,分析原因可能是EasyUI的form组件加载数据是在编辑器初始化之后赋值给textarea导致编辑器显示不住编辑的值,因此需要在
EasyUI的form组件的onLoadSuccess事件中再将加载后的值赋给编辑器显示出来才行,于是加入了form的onLoadSuccess事件,代码如下:
$(function(){
//初始化FCKEditor
$.fck.config = { path: ‘../../FCKeditor/’, width: 700, height: 300, toolbar: ‘Basic’ };
$(‘textarea#Meeting_Content’).fck();
$(‘#editform’).form({
onLoadSuccess: function(data) {
$.fck.content(‘infoContent’, $(‘#infoContent’).val());
}
});
});
编辑显示值的问题解决了,但是在EasyUI的datagrid中显示编辑器保存的内容时,firefox下的行的高度变高了,开始以为是JQuery的fckEditor的插件的样式和EasyUI的样式有重名冲突,但是查看处理后的代码发现没冲突,于是发现是因为编辑器保存后的值都加入了p标签,导致行变高了,那就在datagrid之前用正则
表达式去除掉html标签,这样就ok了!
[转载]原型设计工具集
[转载]让程序员最头疼的事——原型设计 – 紫青城 – 博客园.
1、源码:江苏雨情系统.rp 下载: 江苏雨情系统.rar
2、一个比较好的Axure RP Libraries:Better GUI.rplib 下载: BetterGUI.rar
3、原型生成后的html,可直接点击运行,查看原型运行效果下载: 原型HTML.rar
4、AxureRP-Pro-5.6.0.2097汉化版注册码
IloveyouAxure
UChpuxwbDW6eAIaAf9UujEFSBwN3vpEz9snHvlCQVJGQy4p7WrCyKLLvV5QLvqva
[转载][C#基础知识]Ref 关键字在修饰在引用类型时的行为
[转载][C#基础知识]Ref 关键字在修饰在引用类型时的行为 – sujiantao – 博客园.
这是个老话题了,不过还是有一些初学者不是太明白,这个也是在面试时容易问的问题。
试验1:Ref对于改变引用对象的属性时的影响
namespace SOVT
{
class Program
{
static void Main()
{
MyClass myClass=new MyClass();
Console.WriteLine(myClass.Field);
ChangeMyClass(myClass);
Console.WriteLine(myClass.Field);
ChangeMyClass(ref myClass);
Console.WriteLine(myClass.Field);
Console.ReadKey();
}
public class MyClass
{
public int Field;
}
public static void ChangeMyClass(MyClass myClass)
{
myClass.Field = 1;
}
public static void ChangeMyClass(ref MyClass myClass)
{
myClass.Field = 2;
}
}
}
其运行结果为:

结论:对于引用对象,无论是否有Ref关键字修饰,都能改变其调用方法外部的引用的对象的字段值,用不用Ref无影响。
试验2:Ref对于在方法内部改变其指向对象时影响
namespace SOVT
{
class Program
{
static void Main()
{
MyClass myClass=new MyClass();
Console.WriteLine(myClass.Field);
ChangeMyClass(myClass);
Console.WriteLine(myClass.Field);
ChangeMyClass(ref myClass);
Console.WriteLine(myClass.Field);
Console.ReadKey();
}
public class MyClass
{
public int Field;
}
public static void ChangeMyClass(MyClass myClass)
{
myClass = new MyClass {Field = 1};
}
public static void ChangeMyClass(ref MyClass myClass)
{
myClass = new MyClass { Field = 2 };
}
}
}
运行结果:

结论:对于再分配引用对象的引用的操作,没有Ref修饰时是不能在外部生效的,只有有Ref修饰的引用参数才能使再分配操作应用于外部。
小结:
- 当没有Ref修饰引用类型的参数时,在方法中只能改变此引用参数的属性内容,而不能改变整个引用参数对象本身。
- 当有Ref修饰引用类型的参数时,则可以在方法中改变此引用参数的指向位置,而不仅是其属性内容。
- 当 一个引用类型传给一个方法时,是传递了这个引用类型对象的引用的副本(不是对象本身),所以对于在调用方法外部的引用和方法中的引用来说,这两个引用都指 向堆上的同一个对象。所以在修改此对象的属性值时,修改同时会应用于内部和外部的两个引用上。但重新分配其引用位置时,则只是修改副本引用的引用位置,原 引用(方法外部)的位置不变,原引用还是指向原来的对象。
- 而如果加上Ref关键字,这时传入的参数则为些引用对象的原始引用,而不是引用的副本,这样的话,你就不但可以修改原始引用对象的内容,还可以再分配此引用的引用位置(用New 来重新初始化)。
- 如果你只想在方法中改变引用参数的内容,没有必要使用Ref来修饰引用参数。
- 如果你希望在方法中改变引用对象参数的引用(调用方法外的),如重新初始化对象,则需要使用Ref关键字来修饰参数。
[转载]B2C电子商务系统研发——商品模块E-R图建模
[转载]B2C电子商务系统研发——商品模块E-R图建模 – 颜超敏 – 博客园.

【说明】:这只是我提出的一种建模思路,电子商务的业务比较复杂,而且各个网站和系统会有其特定的需求,
这个模型虽然具备一定的通用性,但不能保证适用所有的业务。各位读者可以根据自己项目的需要来做调整。
- 商品
模块的核心实体之一。承担和内部、外部的关联。该表内设计基础属性和冗余信息。
前台商品详细页面,已本实体的记录作为单元,一条记录一个详细页面。 - 商品SKU
模块的另一个核心实体,从属于商品。每一个商品SKU是商品关联的规格的一种组合。
比如 [颜色SKU-红色] + [尺码SKU-42码] 形成一种组和。这个组合构成一个商品SKU。
价格、库存和关联购物车、订单等,都通过此实体完成。 - 商品描述
和商品是一对一关系,将只会在商品详细页面使用的SEO、描述等相关字段分离出来,
对提高商品列表的检索效率会有帮助。 - 商品媒体
通过媒体类型来区分图片、视频和文档等。 - 属性扩展模块
上面粉红色框住的部分是属性扩展模块,通过各类关联为商品模块实现SKU、评论项、查询属性和普通描述性
属性的扩展。从设计上考虑,属性扩展模块并不从属商品模块,它可以为其它的实体(如分类、订单、客户)
提供属性扩展服务。当然SKU属性则是商品独有的。 - 商品库存
这块是可选的设计,需要专设一章来分析,而对于有紧迫进度要求的项目,可以先直接在商品SKU实体中设计
一个“库存数量”字段,留待以后扩展也可以。
[原创]EasyUI的datagrid页脚footer使用注意事项
最近项目中遇到datagrid数据需要再form加载完成后根据具体的商品显示页脚footer合计数量的问题,页面初始化的时候不加载datagrid数据,初始化完成后需要读取form中的项目值然后加载对应的数据到
datagrid中,问题代码如下:
$('#grid').datagrid({
showFooter:true
});
$('#form').form({
onLoadSuccess:function(data){
//datagrid
$('#grid').datagrid({
url:'/grid/getData?id='+$('#id').val()+'&r='+Math.random()
});
}
});
结果datagrid不显示页脚footer,列数据能显示正常,分析问题原因是因为页面创建datagrid的时候因为没有数据导致错误,firefox中提示rows未定义,当然未定义了,因为我根本没给datagrid赋值,这样datagrid的页脚就显示不出来,那么怎么修改呢,参考了我以前写的文章[原创]EasyUI的DataGrid合击汇总页脚使用教程得到解决办法,那就初始化的时候给datagrid一个空的数据集,让它顺利初始化完成,然后再当form加载成功后更换它的数据,代码如下:
var nullData='{"rows":[],"total":0;"footer":{"Footer":"合计","num":0}}';
var json=eval('(' + nullData + ')');
$('#grid').datagrid({
data:json,
showFooter:true
});
$('#form').form({
onLoadSuccess:function(data){
//datagrid
$('#grid').datagrid({
url:'/grid/getData?id='+$('#id').val()+'&r='+Math.random()
});
}
});
Mikel

![image[1]_3 image[1]_3](http://images.cnblogs.com/cnblogs_com/yiway/201112/20111216171303183.png)
