ASP.NET Core MVC和Visual Studio入门

Posted on Leave a commentPosted in ASP.NET Core

本教程将教你使用Visual Studio 2017创建 ASP.NET Core MVC web应用程序的基础知识。

安装Visual Studio 2017 和.Net Core

安装Visual Studio 2017 社区版,选择社区版下载。如果你已经安装了Visual Studio 2017,请跳过此步骤。
Visual Studio 2017 主页

运行安装程序然后选择以下模块:
  • ASP.NET 和Web开发
  • .NET Core 跨平台开发

创建一个Web应用程序

从Visual Studio中,选择 文件->新建->项目

完成新建项目对话框中:
  • 左边窗口中,点击.NET Core
  • 在中间的窗口点击 ASP.NET Core Web应用程序(.NET Core)
  • 项目名称”MvcMovie”
  • 点击确定

完成新建 APS.NET Core Web 应用程序对话框中:
  • 右上角版本选择下拉框中选择 ASP.NET Core 1.1
  • 模板选择Web应用程序
  • 身份验证不进行身份验证
  • 点击确定

到这里一个项目就创建完了,并且Visual Studio还给你的项目添加了Bootstrap框架和几个页面。这是一个简单的项目,也是一个很好的开始。

你可以在非调试模式下按 F5 或者在调试模式下按 Ctrl F5 来运行这个程序。

  • 在Visual Studio 创建项目的时候,由于端口号是随机分配的,所以你地址栏的端口号,有可能和我的不一样。

在本教程的下一部分,我们会了解 MVC 并开始编写一些代码。

本文翻译自:https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/start-mvc
转载请注明出处:http://www.shuaibi.org/archives/93.html

.net点选验证码实现思路分享

Posted on Leave a commentPosted in ASP.NET

哈哈好久没冒泡了,最进看见点选验证码有点意思,所以想自己写一个。

先上效果图

如果你被这个效果吸引了就请继续看下去。

贴代码前先说点思路:

1.要有一个汉字库,并按字形分类。(我在数据库里是安部首分类的)

2.获取验证码(也就是取几个文字做验证码)

3.根据取出来的文字去找形近字

4.排列验证码文字和形近字

5.绘制图片

6.显示

6.写个博客分享一下(分享代码改变世界)

 

一、获取字库

我国文化博大精深,辣么多的字从哪儿来?当然我不可能手动加进去,于是我就在网上随便找了一个能查汉字的网站,去抓别人的数据。抓数据的方法请点传送门。传送门里说的只是思路,如果有不明白的请艾特我。我会在下面共享我的字库。

 

二、获取验证码

这个就比较简单了这里我就直接贴代码了,下面的代码就是随机排序后取4条数据,我这样写是为了图方便。个人觉得先随机生成ID,然后直接根据ID取数据,这样查询速度会比下面这种写法快。(注意我用的数据库是MySql

        /// <summary>
        /// 获取验证码
        /// </summary>
        public List<VerificationCode.Model.WenZhi> GetCodeText()
        {
            const string sql = "SELECT * FROM wenzhi ORDER BY RAND() LIMIT 4";
            var dataReader = dbHelper.GetDataReader(sql);
            var list = DataReaderToList(dataReader);
            dataReader.Close();
            return list;
        }

 

三、根据取出来的文字去找形近字

因为第一步的时候我存部首了,所以这里我直接根据部首取获取当前部首的形近字。

        /// <summary>
        /// 获取答案备选
        /// </summary>
        /// <param name="buShouCode">部首编码</param>
        /// <param name="id">当前文字ID</param>
        /// <param name="number">数量</param>
        /// <returns></returns>
        public List<VerificationCode.Model.WenZhi> GetAnswer(string buShouCode, int id,int number=1)
        {
            string sql = $"SELECT * FROM wenzhi where BuShouCode='{buShouCode}' and ID <> {id} ORDER BY RAND() LIMIT "+ number;
            var dataReader = dbHelper.GetDataReader(sql);
            var list = DataReaderToList(dataReader);
            dataReader.Close();
            return list;
        }

 

四.排列验证码文字和形近字

  下面的代码是先把备选答案和验证码放在一个集合里然后再对集合排序

 public Model.Code GetCode()
        {
          
            var wenzlist = _wenZhiDal.GetCodeText();  //获取验证码
            var listAnsuwr = new List<Answer>();//实例化备选答案对象
            var answerCode = string.Empty;//答案
            var result = new Model.Code
            {
                Id = Guid.NewGuid().ToString()
            };
            //根据验证码获取备选答案并把添加到答案添加到备选答案集合
            foreach (var item in wenzlist)
            {
                answerCode += item.ID + ",";
                result.AnswerValue += item.Text;
                var answerList = _wenZhiDal.GetAnswer(item.BuShouCode, item.ID);
                listAnsuwr.Add(new Answer { Id = item.ID.ToString(), Img = GetImage(item.Text) });
                listAnsuwr.AddRange(answerList.Select(answer => new Answer { Id = answer.ID.ToString(), Img = GetImage(answer.Text) }));
            }
            //如果答案个数不够就再去取几个
            if (listAnsuwr.Count < 9)
            {
                var ran = new Random();
                var randKey = ran.Next(0, 4);
                var item = wenzlist[randKey];
                var answerList = _wenZhiDal.GetAnswer(item.BuShouCode, item.ID, 9 - listAnsuwr.Count);
                listAnsuwr.AddRange(answerList.Select(answer => new Answer { Id = answer.ID.ToString(), Img = GetImage(answer.Text) }));
            }
            result.CodeImg = GetImage(result.AnswerValue);//获取图片
            result.AnswerValue = answerCode.TrimEnd(',');
            result.Answer = RandomSortList(listAnsuwr);//打乱正确答案与形近字的顺序
            return result;
        }

这是对集合排序的代码

        /// <summary>
        /// 随机排列集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="listT"></param>
        /// <returns></returns>
        private static List<T> RandomSortList<T>(IEnumerable<T> listT)
        {
            var random = new Random();
            var newList = new List<T>();
            foreach (var item in listT)
            {
                newList.Insert(random.Next(newList.Count + 1), item);
            }
            return newList;
        }

 

五、绘制图片

下面是画图的代码,验证码和备选答案对应两种不同的画法(里面注释写的还算清楚)。不要担心文字旋转x°后人类分不出来,哈哈。代码最后一句我把图片转成了Base64,方便前端调用。

 

private static string GetImage(string text)
        {
            Image image;
            switch (text.Length)
            {
                case 1:
                    image = new Bitmap(50, 40);
                    break;
                case 4:
                    image = new Bitmap(120, 40);
                    break;
                default:
                    image = new Bitmap(50, 40);
                    break;
            }
            Brush brushText = new SolidBrush(Color.FromArgb(255, 0, 0, 0));
            var graphics = Graphics.FromImage(image);
            graphics.SmoothingMode = SmoothingMode.AntiAlias;
            graphics.Clear(Color.White);
            var font = new Font(new FontFamily("华文彩云"), 20, FontStyle.Regular);
            if (text.Length > 1)//画验证码
            {
                //先来两条直线做干扰 然后再画文字
                graphics.DrawLine(new Pen(brushText, new Random().Next(1, 3)), new Point(new Random().Next(0, 10), new Random().Next(10, 40)), new Point(new Random().Next(100, 120), new Random().Next(10, 30)));
                graphics.DrawLine(new Pen(brushText, new Random().Next(1, 3)), new Point(new Random().Next(20, 50), new Random().Next(0, 10)), new Point(new Random().Next(100, 120), new Random().Next(30, 40)));
                graphics.DrawString(text, font, brushText, 0, 10);

            }
            else//画备选答案
            {
                Point middle = new Point(25, 20);
                graphics.TranslateTransform(middle.X, middle.Y);
                //这里是360°随机旋转 
                graphics.RotateTransform(new Random().Next(0, 360));
                var format = new StringFormat(StringFormatFlags.NoClip)
                {
                    Alignment = StringAlignment.Center,
                    LineAlignment = StringAlignment.Center
                };
                graphics.DrawString(text, font, brushText, 0, 0, format);

            }
            brushText.Dispose();
            graphics.Dispose();
            return ImageToBase64(image);
        }

 

六、显示

直接调用GetCode方法就能返回验证码对象

下面是后台代码,应为正确答案是放在AnswerValue里的所以我先把取出来放Session里面,然后把值清空后再通过json返回给浏览器。

        public string GetVerCode()
        {
            var code = new VerificationCode.Code().GetCode();
            Session["VERCODE"] = code.AnswerValue;
            code.AnswerValue = "";
            return JsonConvert.SerializeObject(code);
        }

现在来堆点html代码

<div class="form-group">
                    <ul class="vercode">
                        <li><img src=''/></li>
                        <li><img src=''/></li>
                        <li><img src=''/></li>
                        <li><img src=''/></li>
                        <li class="delete" onclick="delete_input()"></li>
                    </ul>
                    <div>
                        <img id="code-image"/> <a href="javascript:void(0);" onclick="load_vercode()">看不清?</a>
                    </div>
                    <ul class="vercode-anwser">
                        <li><img /></li>
                        <li><img /></li>
                        <li><img /></li>
                        <li><img /></li>
                        <li><img /></li>
                        <li><img /></li>
                        <li><img /></li>
                        <li><img /></li>
                        <li><img /></li>
                    </ul>
                </div>

 

再来点js代码,这里只实现的图片上的效果,还没对数据验证(这里说说验证思路:每个图片对应一个ID,取到选择图片的ID用逗号分隔,然后与Session里的值对比)

<script>
        $(function () {
            //加载验证码
            load_vercode();
            //绑定验证码点击事件
            $(".vercode-anwser").find("img").on("click", null, function () {
                $(".vercode").find("img[src='']:eq(0)").attr("src", $(this).attr("src"));
            });
        });

        function load_vercode() {
            $(".vercode").find("img").attr("src", "");
            $.get("GetVerCode", function (data) {
                var result = JSON.parse(data);
                $("#code-image").attr("src", "data:image/png;base64," + result.CodeImg);
                $(".vercode-anwser").find("img").each(function (index) {
                    $(this).attr("src", "data:image/png;base64," + result.Answer[index].Img);
                });
            });
        }
        //删除事件
        function delete_input() {
            $(".vercode").find("img[src!='']:last").attr("src", "");
        }
    </script>

到这里代码就差不多了,以上思路只是单纯的个人想法,有兴趣的朋友一起来讨论吧。

源代码在这里–>地址 http://pan.baidu.com/s/1eS5Mn30 密码:7iud

分享代码改变世界

 

Android SwipeRefreshLayout 下拉刷新

Posted on Leave a commentPosted in Android

以前写下拉刷新 感觉好费劲,要判断ListView是否滚到顶部,还要加载头布局,还要控制 头布局的状态,等等一大堆。感觉麻烦死了。今天学习了SwipeRefreshLayout 的用法,来分享一下,有说的不对的地方请大家指点。

SwipeRefreshLayout 是Google在support v4 19.1版本的library更新的一个下拉刷新组件,也就是说 开发的时候把Android版本调到4.4或者以上才会有这个。

先来看看效果图

再来看看布局文件里的代码(我这里放的是一个ListView 当然也可以放其他控件 只要你高兴就好)

 <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/main_srl_bloglist"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <ListView
            android:id="@+id/main_lv_bolg_list"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:divider="#00000000"
            android:dividerHeight="5dp"></ListView>

    </android.support.v4.widget.SwipeRefreshLayout>

最后来看看Activiy里的代码吧(这里我用的AndroidAnnotations 所以没有写 findViewById 哈哈)

 //设置刷新时动画的颜色,可以设置4个
        mSwipeRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_light, android.R.color.holo_red_light, android.R.color.holo_orange_light, android.R.color.holo_green_light);
        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                mIndex=1;
                mBlogList.clear();
                loadBlogData();
            }
        });

在onRefresh 里调用获取数据的方法就好了 数据获取完毕 别忘了 修改状态

mSwipeRefreshLayout.setRefreshing(false);

哈哈 以前要写成吨的代码 用SwipeRefreshLayout 就这几行代码 是不是很方便。

Android通过Volley请求WebApi共通

Posted on Leave a commentPosted in Android

思路:

1.把请求网络的方法放到一个类里面

2.创建一个接口将数据发给Activity

3.Activity 实现接口获得服务器返回的数据

4.解析数据

 

来我们一先来看第一步

请求网络

在这里请求网络我们用Volley 。Volley是Android平台上的网络通信库,能使网络通信更快,更简单,更健壮。当然Volley对加载图片的时候内存控制的很好,后面加载图片还会用到。

创建一个CallWebservice 类

package org.shuaibi.hi_blog.utils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import org.json.JSONObject;

import android.content.Context;
import android.widget.Toast;

import com.android.volley.RequestQueue;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;

public class CallWebservice  {

    private final String HTTPHOST="http://blog.haojima.net/api/home/";  //主机地址
    public static RequestQueue requestQueue;
    private Context mContnxt; 
    private int mMark;
    private ServiceCallBack mServiceCallBack; 

    public CallWebservice(Context context,String function,HashMap&lt;String, String&gt; params,int mark)
    {
        this.mContnxt=context;
        this.mMark=mark;
        this.mServiceCallBack=(ServiceCallBack) context;
        createUrl(function,params);
    }

    public void createUrl(String function,HashMap&lt;String, String&gt; params)
    {
        //拼主机名和方法名

        String url=this.HTTPHOST+function;
        //拼参数

        if(params!=null){
            url+="?";
            Iterator&lt;Entry&lt;String, String&gt;&gt; iterator = params.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry&lt;String, String&gt; obj = (Entry&lt;String, String&gt;) iterator.next();
                url+=obj.getKey().toString()+"="+obj.getValue().toString()+"&amp;";
            }
            url=url.substring(0, url.length()-1); //去掉最后一个 &amp;
        }
        //请求服务器

        getJsonResult(url);

    }

    public void getJsonResult(String url)
    {
        if(CallWebservice.requestQueue==null)
        {
            requestQueue=Volley.newRequestQueue(mContnxt);
        }
        JsonObjectRequest jsonObjectRequest=new JsonObjectRequest(url, null, new Listener&lt;JSONObject&gt;() {
            @Override
            public void onResponse(JSONObject response) {
                mServiceCallBack.serviceResult(response, mMark);
            }
        }, new ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
             Toast.makeText(mContnxt, error.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
        requestQueue.add(jsonObjectRequest);
    }
}

下面来写接口

package org.shuaibi.hi_blog.utils;

import org.json.JSONObject;

/**

 * 

 * @描述: 服务器返回值回调

 * @作者: ZeroX

 * @时间: 2015-9-16

 * @参数: 

 * @接口: 

 *

 */
public interface ServiceCallBack {
    void serviceResult(JSONObject jsonObject,int mark);
}

看见了接口的代码很简单就几句话, 里面的jsonObject 就是服务器返回值 mark 是标记当一个Activity里有多个请求网络的地方 我们就可以用mark 区分哈哈 。

这样请求网络就算完成了,下面介绍用法

HashMap<String, String> params=new HashMap<String, String>();
        params.put("idex",mIndex+"");
        params.put("sizePage", mPageSize+"");
        params.put("ContentLength", "80");
        new CallWebservice(this,"get",params,GETBLOGLIST);

上面代码就是调用一个 方法的写法  里面的GETBLOGLIST 是定义的一个常量我写的1,用来区分多个网络请求的这个数就是 上面接口里的mark

最后就是Activity实现 ServiceCallBack 这个接口了 实现一下serviceResult 这个方法

public class MainActivity extends Activity implements ServiceCallBack
@Override
    public void serviceResult(JSONObject jsonObject, int mark) {
        try {
            switch (mark) {
            case GETBLOGLIST:
                 blogResultHander(jsonObject.getJSONArray("blog"));
mPageCount=jsonObject.getInt("total");
                break;
            default:
                break;
            }
        } catch (JSONException e) {
            // TODO Auto-generated catch block

            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block

            e.printStackTrace();
        }

    }

最后就是解析Json了

 /**

     * 博客列表返回值处理

     * @param jsonArray 博客列表

     */
    public void blogResultHander(JSONArray jsonArray) throws Exception
    {
        for (int i = 0; i &lt; jsonArray.length(); i++) {
            JSONObject jsonObject=jsonArray.getJSONObject(i);
            HashMap&lt;String, String&gt; itemHashMap=new HashMap&lt;String, String&gt;();
            itemHashMap.put("UserName", jsonObject.getJSONObject("BlogUsersSet").getString("UserNickname"));
            itemHashMap.put("CreateTime", jsonObject.getString("BlogCreateTime"));
            itemHashMap.put("Title", jsonObject.getString("BlogTitle"));
            itemHashMap.put("Content", jsonObject.getString("BlogContent"));
            itemHashMap.put("Comment", jsonObject.getString("BlogCommentNum"));
            itemHashMap.put("Visibility", jsonObject.getString("BlogReadNum"));
            mBlogList.add(itemHashMap); //这是一个List&lt;HashMap&lt;String,String&gt;&gt;
        }

    

    }

哈哈我们已经把 重服务器返回的数据放到List里了。

上面代码只是提共参考哟 完整代码请点击这里 

Android Studio配置 AndroidAnnotations

Posted on Leave a commentPosted in Android

以前用Eclicps 用习惯了现在 想学学 用Android Studio 两天的钻研终于 在我电脑上装了一个Android Studio 并完成了AndroidAnnotations 的配置。

AndroidAnnotations是一个能够让你快速进行Android开发的开源框架,它能让你专注于真正重要的地方。使代码更加精简,使项目更加容易维护,它的目标就是“Fast Android Development.Easy maintainance”。 说白了 就是可以少写很多代码,哈哈。

AndroidAnnotations是一个开源项目 项目地址 有兴趣的朋友可以去研究一下。好了 废话不多说了。

1 我们需要把 AndroidAnnotations下载下来

2 新建文件夹 compile-libs

3 将androidannotations-3.2.jar 复制到 compile-libs 将 androidannotations-api-3.2.jar 复制到libs下

如:

4 在项目的build.gradle 添加 classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.4’

如:

5 在Model 的build.gradle  添加

5.1 apply plugin: ‘android-apt’

def AAVersion = ‘3.2+’

5.2  apt “org.androidannotations:androidannotations:$AAVersion”
compile “org.androidannotations:androidannotations-api:$AAVersion”
compile ‘com.android.support:support-v4:22.1.1’

5.3 apt {

arguments {

androidManifestFile variant.outputs[0].processResources.manifestFile

resourcePackageName ‘org.shuaibi.hi_blog’

}

}

如:

到这里配置就算完成了 下面来看一下 怎么使用

package org.shuaibi.hi_blog.activity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;
import org.shuaibi.hi_blog.R;

@EActivity(R.layout.activity_main)  //指定视图
public class MainActivity extends Activity {

    @ViewById(R.id.main_tv_hello)
    TextView mHelloWord; //绑定控件

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Click(R.id.main_tv_hello) //点击事件按
    public void hello_Click() {
        Intent intent = new Intent(this, BlogDetailActivity_.class);
        startActivity(intent);
    }


    @AfterViews //视图加载完毕后执行
    public void init() {

        Toast.makeText(this, "视图加载完毕", Toast.LENGTH_SHORT).show();

    }

}

最后 要在 AndroidManifest 文件中 给Activity加上 _ (这是一个下横杠)

如果要在 Eclipse 中配置请 移步到这里–> 传送

对Android Studio 不是很熟 有什么不对的地方请多多指教

Android万能的Adapter

Posted on Leave a commentPosted in Android

啊哈,今天来分享一个万能AndroidAdapter,想提高工作效率,和懒的程序猿同胞们有福了,嘻嘻。
代码很简单就不做解释了 直接上代码
先来个CommonAdapter继承BaseAdapter


package org.shuaibi.androidexplore.utils;

import java.util.List;

import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

/**
*
* @描述: CommonAdapter
* @作者: ZeroX
* @时间: 2015-8-30
* @参数:
* @接口:
*
*/
public abstract class CommonAdapter<T> extends BaseAdapter {

protected List<T> mList;
protected Context mContext;
protected RequestQueue mQueue;
protected ImageLoader mImageLoader;

public CommonAdapter(){

}
public CommonAdapter(List<T> list,Context context)
{
this.mList=list;
this.mContext=context;
this.mQueue = Volley.newRequestQueue(context);
this.mImageLoader = new ImageLoader(mQueue, new BitmapCache());
}

@Override
public int getCount() {

return mList.size();
}

@Override
public Object getItem(int position) {
return mList.get(position);
}

@Override
public long getItemId(int position) {

return position;
}

@Override
public abstract View getView(int position, View convertView, ViewGroup parent);

}

&nbsp;

&nbsp;

 

然后是ViewHolder 这是重点

 


package org.shuaibi.androidexplore.utils;

import android.content.Context;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
*
* @描述: ViewHolder
* @作者: ZeroX
* @时间: 2015-8-30
* @参数:
* @接口:
*
*/
public class ViewHolder {

private SparseArray<View> mView;
private View mConvertView;
public int mPosition;

public ViewHolder(Context context,ViewGroup parent,int position,int layoutId)
{
mView=new SparseArray<View>();
mPosition=position;
mConvertView=LayoutInflater.from(context).inflate(layoutId, parent,false);
mConvertView.setTag(this);
}

public    ViewHolder ()
{

}
public static ViewHolder get(Context context,View convertView,ViewGroup parent,int position,int layoutId)
{
if(convertView==null)
{
return new ViewHolder(context, parent, position, layoutId);
}else {
ViewHolder viewHolder=(ViewHolder) convertView.getTag();
viewHolder.mPosition=position;
return viewHolder;
}

}

@SuppressWarnings("unchecked")
public<T extends View> T getView(int viewId)
{
View view=mView.get(viewId);
if(view==null)
{
view=mConvertView.findViewById(viewId);
mView.put(viewId, view);
}
return (T) view;

}

public View getConvertView()
{
return mConvertView;
}

}

下面是使用方法


package org.shuaibi.androidexplore.adapter;

import java.util.HashMap;
import java.util.List;

import org.shuaibi.androidexplore.R;
import org.shuaibi.androidexplore.config.Config;
import org.shuaibi.androidexplore.utils.CommonAdapter;
import org.shuaibi.androidexplore.utils.ViewHolder;
import com.android.volley.toolbox.NetworkImageView;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

/**
*
* @描述: 产品列表适配器
* @作者: ZeroX
* @时间: 2015-8-30
* @参数:
* @接口:
*
*/
public class ProductListAdapter extends CommonAdapter<HashMap<String, String>> {

public ProductListAdapter(List<HashMap<String, String>> list,Context context)
{
super(list,context);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder holder=ViewHolder.get(mContext, convertView, parent, position,R.layout.item_main);

HashMap<String, String> dataHashMap=(HashMap<String, String>) mList.get(position);
((TextView)holder.getView(R.id.main_tv_productName)).setText(dataHashMap.get("ProductName"));
((NetworkImageView)holder.getView(R.id.main_iv_productimg)).setImageUrl(Config.FILE_ADDRESS+dataHashMap.get("ImageUrl"),mImageLoader);

return holder.getConvertView();
}

}

看是不是比以前少写了很多代码。有不明白的地方 可以去这里看视频

 

 

Android通过Soap请求Webservice共通

Posted on Leave a commentPosted in Android

好久都没写了,今天总结的是Android中通过Soap协议访问Webservice共通类。
首先下载一个第三方jar包k2soap-android-timeout.jar 将下载的文件 放到libs 文件夹下。
实现思路
新建一个接口ServiceCallBack用来传递数据

package org.shuaibi.exploration.utils;

import org.json.JSONObject;

/**
 *
 * @author ZeroX
 *
 */
public interface ServiceCallBack {
	/**
	 * 接口返回值
	 * @param jsonObject 返回的json
	 * @param mark 调用接口时传的标识
	 */
	public void ServiceResult(JSONObject jsonObject,int mark);
}

新建CallWebservice类继承Thread 在线程里面请求网络,然后后将返回的数据发给主线程,最后通过ServiceCallBack发送给Activity ,再在Activity 里处理返回的数据 废话不多说 直接上代码

package org.shuaibi.exploration.utils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import org.apache.http.conn.ConnectTimeoutException;
import org.json.JSONException;
import org.json.JSONObject;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;


import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.widget.Toast;



@SuppressLint("HandlerLeak")
public class CallWebServiceBySoap extends Thread{
	private String method,httphost;
	private HashMap<String, String> params;
	private Context context;
	private ServiceCallBack serviceCallBack;
	private int mark;

	/**
	 * Activity访问WebService
	 * @param context 上下文 一定要传 this
	 * @param method 方法名称
	 * @param params 参数名称 
	 * @param serviceName service名
	 * @param mark 标记
	 */
	public CallWebServiceBySoap(Context context,String method, HashMap<String, String> params, String httpHost,int mark)
	{
		this.method=method;
		this.params=params;
		this.httphost=httpHost;
		this.context=context;
		this.serviceCallBack=(ServiceCallBack) context;
		this.mark=mark;
	}

	/**
	 * Fragment访问WebService
	 * @param context 上下文 一定要传 this
	 * @param method 方法名称
	 * @param params 参数名称 
	 * @param serviceName service名
	 * @param mark 标记
	 */
	public CallWebServiceBySoap(Fragment fragment,String method, HashMap<String, String> params, String httpHost,int mark)
	{
		this.method=method;
		this.params=params;
		this.httphost=httpHost;
		this.context=fragment.getActivity();
		this.serviceCallBack=(ServiceCallBack) fragment;
		this.mark=mark;
	}

	@Override
	public void run() {
		super.run();
		Message message=new Message();
		try {
			message.what=1;

			message.obj=getJSONObject(method,params,httphost);
		}catch(ConnectTimeoutException e){
			message.what=-5;
			e.printStackTrace();

		}catch (IOException e) {
			message.what=-5;

			e.printStackTrace();
		}catch (XmlPullParserException e) {

			message.what=-6;
			e.printStackTrace();
		} catch (JSONException e) {

			message.what=-7;
			e.printStackTrace();
		}
		resuleHandler.sendMessage(message);
	}


	Handler resuleHandler=new Handler()
	{
		public void handleMessage(android.os.Message msg) {
			try {

				switch(msg.what)
				{
				case 1:
					int result=((JSONObject)msg.obj).getInt("result");
					switch(result){
					case 1: //状态为1将数据 发到Activity处理
						serviceCallBack.ServiceResult((JSONObject)msg.obj, mark);
						break;
					default ://其他状态 弹出提示信息
						Toast.makeText(context,((JSONObject)msg.obj).getString("msg"), Toast.LENGTH_SHORT).show();
						break;
					}

					break;
				case -5:
					if(Config.NETWORKNUM==0){
						Config.NETWORKNUM++;
						Toast.makeText(context,"连接服务器失败,请检查网络!", Toast.LENGTH_SHORT).show();
					}
					break;
				case -6:
					if(Config.NETWORKNUM==0){
						Config.NETWORKNUM++;
						Toast.makeText(context,"数据解析异常,请稍后再试!", Toast.LENGTH_SHORT).show();
					}
					break;
				case -7: 
					if(Config.NETWORKNUM==0){
						Config.NETWORKNUM++;
						Toast.makeText(context,"返回数据异常!", Toast.LENGTH_SHORT).show();
					}
					break;
				default:

					if(Config.NETWORKNUM==0){
						Config.NETWORKNUM++;
						Toast.makeText(context, "连接服务器失败,请检查网络", Toast.LENGTH_SHORT).show();
					}
					break;
				}
			} catch (JSONException e) {
				Toast.makeText(context, "数据处理异常,请稍后再试", Toast.LENGTH_SHORT).show();
				e.printStackTrace();
			}
		};
	};

	public static JSONObject getJSONObject(String method, HashMap<String, String> params, String httphost) throws IOException, XmlPullParserException, JSONException  {
		String wsdlURL = "http://" + Config.WEBSERVICE_IP + httphost;
		String webMethod = method;
		String namespace = Config.NAME_SPACE;
		String soapAction = namespace + webMethod;
		// 步骤2 创建一个SoapObject对象
		SoapObject soapObject = new SoapObject(namespace, webMethod);
		if(params!=null){
			// 步骤3 传递参数
			Iterator<Entry<String, String>> iterator = params.entrySet().iterator();
			// 循环读取 传递参数
			while (iterator.hasNext()) {
				Entry<String, String> obj = (Entry<String, String>) iterator.next();
				// 将参数添加到SoapObject对象中
				soapObject.addProperty(obj.getKey().toString(), obj.getValue().toString());
			}
		}
		// 步骤4 创建SoapSerializationEnvelope
		SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		envelope.dotNet = true;
		// 步骤5 设置一下传回对象
		envelope.bodyOut = soapObject;
		envelope.setOutputSoapObject(soapObject);
		// 步骤6 创建HttpTransportSE用于传输对象
		HttpTransportSE se = new HttpTransportSE(wsdlURL, 1000 * 10);
		JSONObject jsonObject = null;
		se.call(soapAction, envelope);
		// 步骤8获取从webService返回的结果
		if (envelope.getResponse() != null) {
			jsonObject = new JSONObject(envelope.getResponse().toString());
			Config.NETWORKNUM=0;
		}
		return jsonObject;
	}



}

 

使用方法


package org.shuaibi.exploration.activity;

import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;
import org.json.JSONObject;
import org.shuaibi.exploration.R;
import org.shuaibi.exploration.utils.CallWebServiceByPost;
import org.shuaibi.exploration.utils.ServiceCallBack;

import android.os.Bundle;
import android.widget.TextView;
import android.app.Activity;
/**
 *
 * @author ZeroX
 *
 */
@EActivity(R.layout.activity_main)
public class MainActivity extends Activity implements ServiceCallBack {

	private final int GETIMG=1;
	private int num=10;

	@ViewById(R.id.tv_result)
	public TextView tv_result;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	}

	@AfterViews
	public void initData()
	{
		//请求WebService
		new CallWebServiceByPost(this, "meinv?num="+num, null, GETIMG).start();
	}

	@Override
	public void ServiceResult(JSONObject jsonObject, int mark) {
		switch (mark) {
		case GETIMG:
			//处理接口返回值
			tv_result.setText(jsonObject.toString());
			break;

		default:
			break;
		}

	}

}

AndroidAnnotaions框架使用

Posted on Leave a commentPosted in Android
转眼干Android 也有一些日子了。平时在工作中findViewById和setOnClickListener像这些都是经常写的。一个项目下来,这样的语句会写一大堆。感觉这样的语句写多少遍都不会有什么高。那么问题来了,我们可不可以不写这写语句,答案是坑定的,当然可以。
现在就来介绍我们今天的主角AndroidAnnotaions,这个框架是一个开源框架,大家可以以在GitHub上找到它,这次我们只讨论怎么使用 ,所以就直接下载jar 包 来用。

解压文件能看见两个jar 包

androidannotations-api-3.2.jar
androidannotations-3.2.jar
把androidannotations-api-3.2.jar放到libs 文件夹下
然后在项目中新建一个 文件夹 compile-lib 把下载的androidannotations-3.2.jar放到该文件夹下
右键项目 Build Path -> Configur Build Path ->Java Compiler -> Annotation Processin -> Enable projecr specific settings 打上对号 -> Factory Path ->Add Jars 找到放到 compile-lib 里面的 androidannotations-3.2.jar -> apply
完成上面配置后现在就来 开始使用吧
package org.shuaibi.androidannotions;

import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;

import com.example.androidannotions.R;

import android.os.Bundle;
import android.app.Activity;
import android.widget.Button;
import android.widget.TextView;

@EActivity(R.layout.activity_main) //设置页面视图
public class MainActivity extends Activity {

@ViewById(R.id.btn_main_clickme)  //找id为btn_main_clickme的Button 相当于findViewById
Button mClickMe;
@ViewById(R.id.tv_main_helloword)
TextView mHelloWord;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}

@Click(R.id.btn_main_clickme) //给id为btn_main_clickme的Button 设置点击事件
void myButton()
{
mHelloWord.setText("点了我一下");

}

}
上面代码只是简单介绍了AndroidAnnotations 的基本用法。更多用法请参见官方文档

Asp.Net Mvc 使用WebUploader 多图片上传

Posted on Leave a commentPosted in ASP.NET

最近由于项目需要上传多张图片,对于我这只菜鸟来说,以前上传图片都是直接拖得控件啊,而且还是一次只能传一张。由于现在 项目用的是MVC,像Asp那样 拖控件 是不现实了。在我脑海中立刻就浮现出一个想法,网上一定有插件,哈哈。去网上一搜索,哇哦这么多。在众多的插件中我被百度的WebUploader吸引了。官网上写着:”WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件…”;就是这句里面的”简单”和”现代” 这两个词深深的吸引了我,当然官网提供的Demo也很酷,而且还是开源的,哇咔咔。既然决定用这个了,我就下了一份源代码下来。打开一看,什么gui ,居然是php的。当时的心情你们能理解么?于是我就抱着试一试的心态搜索了一下 “webuploader asp.net” 哈哈居然搜到到Demo了.Demo 是从 eflay 这位前辈的博客上看的。我借用了他的后台方法,由于前面js写的太复杂我没敢用。好了不扯废话了下面就来演示根据WebUploader官方提供的API和前面说的那位前辈的后台方法完成图片上传。

1. 下载WebUploader

2. 将下载到的压缩包里面的文件复制到自己的项目中

3. 添加引用

1 <!--引入Jquery-->
2 <script src="~/Script/jquery-1.8.2.min.js"></script>
3 <!--引入Css-->
4 <link href="~/CSS/webuploader.css" rel="stylesheet" />
5 <!--引入Js-->
6 <script src="~/Script/webuploader.js"></script>

4.准备一个放图片的容器和一个上传按钮

<div id="fileList"></div> <!--这是存放图片的容器-->
<div class="cp_img_jia" id="filePicker"></div> <!--这是上传按钮-->

5.创建Web Uploader实例并监听事件

复制代码

  1 <script type="text/javascript">
  2 
  3     var applicationPath = window.applicationPath === "" ? "" : window.applicationPath || "../../";
  4     $(function () {
  5         var $ = jQuery,
  6         $list = $('#fileList'),
  7         // 优化retina, 在retina下这个值是2
  8         ratio = window.devicePixelRatio || 1,
  9         // 缩略图大小
 10         thumbnailWidth = 90 * ratio,
 11         thumbnailHeight = 90 * ratio,
 12         // Web Uploader实例
 13         uploader;
 14         uploader = WebUploader.create({
 15             // 选完文件后,是否自动上传。
 16             auto: false,
 17 
 18             // swf文件路径
 19             swf: applicationPath + '/Script/Uploader.swf',
 20 
 21             // 文件接收服务端。
 22             server: applicationPath + '/Home/UpLoadProcess',
 23 
 24             // 选择文件的按钮。可选。
 25             // 内部根据当前运行是创建,可能是input元素,也可能是flash.
 26             pick: '#filePicker',
 27 
 28             //只允许选择图片
 29             accept: {
 30                 title: 'Images',
 31                 extensions: 'gif,jpg,jpeg,bmp,png',
 32                 mimeTypes: 'image/*'
 33             }
 34         });
 35        
 36         // 当有文件添加进来的时候
 37         uploader.on('fileQueued', function (file) {
 38             var $li = $(
 39                     '<div id="' + file.id + '" class="cp_img">' +
 40                         '<img>' +
 41                     '<div class="cp_img_jian"></div></div>'
 42                     ),
 43                 $img = $li.find('img');
 44 
 45 
 46             // $list为容器jQuery实例
 47             $list.append($li);
 48 
 49             // 创建缩略图
 50             // 如果为非图片文件,可以不用调用此方法。
 51             // thumbnailWidth x thumbnailHeight 为 100 x 100
 52             uploader.makeThumb(file, function (error, src) {
 53                 if (error) {
 54                     $img.replaceWith('<span>不能预览</span>');
 55                     return;
 56                 }
 57 
 58                 $img.attr('src', src);
 59             }, thumbnailWidth, thumbnailHeight);
 60         });
 61 
 62         // 文件上传过程中创建进度条实时显示。
 63         uploader.on('uploadProgress', function (file, percentage) {
 64             var $li = $('#' + file.id),
 65                 $percent = $li.find('.progress span');
 66 
 67             // 避免重复创建
 68             if (!$percent.length) {
 69                 $percent = $('<p class="progress"><span></span></p>')
 70                         .appendTo($li)
 71                         .find('span');
 72             }
 73 
 74             $percent.css('width', percentage * 100 + '%');
 75         });
 76 
 77         // 文件上传成功,给item添加成功class, 用样式标记上传成功。
 78         uploader.on('uploadSuccess', function (file, response) {
 79             
 80             $('#' + file.id).addClass('upload-state-done');
 81         });
 82 
 83         // 文件上传失败,显示上传出错。
 84         uploader.on('uploadError', function (file) {
 85             var $li = $('#' + file.id),
 86                 $error = $li.find('div.error');
 87 
 88             // 避免重复创建
 89             if (!$error.length) {
 90                 $error = $('<div class="error"></div>').appendTo($li);
 91             }
 92 
 93             $error.text('上传失败');
 94         });
 95 
 96         // 完成上传完了,成功或者失败,先删除进度条。
 97         uploader.on('uploadComplete', function (file) {
 98             $('#' + file.id).find('.progress').remove();
 99         });
100 
101         //所有文件上传完毕
102         uploader.on("uploadFinished", function ()
103         {
104            //提交表单
105 
106         });
107 
108         //开始上传
109         $("#ctlBtn").click(function () {
110             uploader.upload();
111 
112         });
113 
114         //显示删除按钮
115         $(".cp_img").live("mouseover", function ()
116         {
117             $(this).children(".cp_img_jian").css('display', 'block');
118 
119         });
120         //隐藏删除按钮
121         $(".cp_img").live("mouseout", function () {
122             $(this).children(".cp_img_jian").css('display', 'none');
123 
124         });
125         //执行删除方法
126         $list.on("click", ".cp_img_jian", function ()
127         {
128             var Id = $(this).parent().attr("id");
129             uploader.removeFile(uploader.getFile(Id,true));
130             $(this).parent().remove();
131         });
132       
133     });
134 
135 
136 </script>

复制代码

6 在Controller里新建一个Action用于保存图片并返回图片路径(这方法是 eflay 前辈博客上说的)

复制代码

 1  public ActionResult UpLoadProcess(string id, string name, string type, string lastModifiedDate, int size, HttpPostedFileBase file)
 2         {
 3             string filePathName = string.Empty;
 4 
 5             string localPath = Path.Combine(HttpRuntime.AppDomainAppPath, "Upload");
 6             if (Request.Files.Count == 0)
 7             {
 8                 return Json(new { jsonrpc = 2.0, error = new { code = 102, message = "保存失败" }, id = "id" });
 9             }
10 
11             string ex = Path.GetExtension(file.FileName);
12             filePathName = Guid.NewGuid().ToString("N") + ex;
13             if (!System.IO.Directory.Exists(localPath))
14             {
15                 System.IO.Directory.CreateDirectory(localPath);
16             }
17             file.SaveAs(Path.Combine(localPath, filePathName));
18 
19             return Json(new
20             {
21                 jsonrpc = "2.0",
22                 id = id,
23                 filePath = "/Upload/" + filePathName
24             });
25         
26         }

复制代码

这样就大功告成了。由于是第一次写博客,里面如果有写的不详细或不对的地方,欢迎大家指点。希望能和大家一起进步。

Demo下载地址http://pan.baidu.com/s/1hqqvB0o