一个简单的WCF+MVC+JQuery程序实现用户的显示和增加

前不久出去面试,有家公司让上机写一个增加用户的的程序,当时没写,回来后简单的写了下,算是记录下吧。

实现功能:列表显示和增加。

 

步骤一:构建整个解决方案

•Contracts:一个类库项目,定义服务契约(Service Contract),引用System.ServiceMode程序集(WCF框架的绝大部分实现和API定义在该程序集中);

•Services:一个类库项目,提供对WCF服务的实现。定义在该项目中的所有WCF服务实现了定义在Contracts中相应的服务契约,所以Services具有对Contracts项目的引用;

•Hosting:一个控制台(Console)应用,实现对定义在Services项目中的服务的寄宿,该项目须要同时引用Contracts和Services两个项目和System.ServiceMode程序集

ASP.NET MVC3 Web Application:前端界面显示,该项目需要同时引用Contracts项目和System.ServiceMode程序集

 对于WCF这一部分的代码,是参考博客园里面的一篇文章,http://www.cnblogs.com/artech/archive/2007/02/26/656901.html(我的WCF之旅(1):创建一个简单的WCF程序)

 

步骤二:创建服务契约 

一般地,我们通过接口的形式定义服务契约。通过下面的代码,将一个接口ICalculator定义成服务契约。WCF广泛采用基于自定义特性(Custom Attribtue)的声明式编程模式,我们通过在接口上应用System.ServiceModel.ServiceContractAttribute特性将一个接口定义成服务契约。通过应用ServiceContractAttribute特性将接口定义成服务契约之后,接口的方法成员并不能自动成为服务的操作。在此方面,WCF采用的是显式选择(Explicit Opt-in)的策略:我们须要在相应的操作方法上面显式地应用OperationContractAttribute特性。

using System.ServiceModel;
namespace WcfServices.Contracts
{
    [ServiceContract(Name="UserService",Namespace="http://www.teresa.com/")]
    public interface IUser
    {        
        [OperationContract]
        DataSet GetUsers();

        [OperationContract]
        void AddUser(string name,string stuNo);
    }
}

 

步骤三:创建服务 
当服务契约成功创建时,我们需要通过实现服务契约来创建具体的WCF服务。WCF服务CalculatorService定义在Services项目中,实现了服务契约接口ICalculator,实现了所有的服务操作。CalculatorService定义如下:

using WcfServices.Contracts;
namespace WcfServices.Services
{
    public class UserService : IUser
    {
        public DataSet GetUsers()
        {
            DataSet dst = new DataSet();
            string strConn = "server=local;database=WcfTesting;Integrated Security=SSPI";
            SqlConnection conn = new SqlConnection(strConn);
            conn.Open();
            string strQueryString = "select * from [User] order by Id desc ";
            SqlDataAdapter ada=new SqlDataAdapter(strQueryString,conn);
            ada.Fill(dst);
            conn.Close();
            return dst;
        }
        public void AddUser(string name, string stuNo)
        {
            string strConn = "server=local;database=WcfTesting;Integrated Security=SSPI";
            SqlConnection conn = new SqlConnection(strConn);
            conn.Open();
            string strCommand = string.Format("INSERT INTO [User] values('{0}','{1}')", name, stuNo);
            SqlCommand com = new SqlCommand(strCommand,conn);
            com.ExecuteNonQuery();
            conn.Close();
        }

     }
}
View Code

补充说明:User表只建立了三个字段,Id(自增),name,stuNo.

步骤四:通过自我寄宿的方式寄宿服务

WCF服务需要依存一个运行着的进程(宿主),服务寄宿就是为服务指定一个宿主的过程。WCF是一个基于消息的通信框架,采用基于终结点(Endpoint)的通信手段。终结点由地址(Address)、绑定(Binding)和契约(Contract)三要素组成,由于三要素应为首字母分别为ABC,所以就有了易于记忆的公式:Endpoint = ABC。一个终结包含了实现通信所必需的所有信息,我们可以这样认识终结点的ABC:  •地址(Address):地址决定了服务的位置,解决了服务寻址的问题 •绑定(Binding):绑定实现了通信的所有细节,包括网络传输、消息编码,以及其他为实现某种功能(比如安全、可靠传输、事务等)对消息进行的相应处理。WCF中具有一系列的系统定义绑定,比如BasicHttpBinding、WsHttpBinding、NetTcpBinding等 •契约(Contract):契约是对服务操作的抽象,也是对消息交换模式以及消息结构的定义

服务寄宿的目的就是开启一个进程,为WCF服务提供一个运行的环境。通过为服务添加一个或多个终结点,使之暴露给潜给的服务消费者。服务消费者最终通过相匹配的终结点对该服务进行调用。我们可以完全通过代码的方式完成所有的服务寄宿工作,下面的代码体现了通过一个控制台应用对CalculatorService的寄宿:

using WcfServices.Contracts;
using WcfServices.Services;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace Hosting
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(UserService)))
            {
                host.AddServiceEndpoint(typeof(IUser), new WSHttpBinding(), "http://127.0.0.1:9999/userservice");
                if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
                {
                    ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
                    behavior.HttpGetEnabled = true;
                    behavior.HttpGetUrl = new Uri("http://127.0.0.1:9999/userservice/metadata");
                    host.Description.Behaviors.Add(behavior);
                }
                host.Opened += delegate
                {
                    Console.WriteLine("CalculatorService started,press any key can stop the service!");
                };
                host.Open();
                Console.Read();
            }
        }
    }
}
View Code

WCF服务寄宿通过一个特殊的对象完成:ServiceHost。在上面的例子中,基于WCF服务的类型(typeof(UserService))创建了ServieHost对象,并添加了一个终结点。具体的地址为http://127.0.0.1:9999/UserService,采用了WSHttpBinding,并指定了服务契约的类型IUser。
 
松耦合是SOA的一个基本的特征,WCF应用中客户端和服务端的松耦合体现在客户端只须要了解WCF服务基本的描述,而无须知道具体的实现细节,就可以实现正常的服务调用。WCF服务的描述通过元数据(Metadata)的形式发布出来。WCF中元数据的发布通过一个特殊的服务行为ServiceMetadataBehavior实现。在上面提供的服务寄宿代码中,我们为创建的ServiceHost添加了ServiceMetadataBehavior,并采用了基于HTTP-GET的元数据获取方式,元数据的发布地址通过ServiceMetadataBehavior的HttpGetUrl指定。在调用ServiceHost的Open方法对服务成功寄宿后,我们可以通过该地址获取服务相关的元数据。在IE地址栏上键入http://127.0.0.1:9999/UserService/metadata,你将会得到以WSDL形式体现的服务元数据。

步骤五:创建MVC web项目实现前端界面显示。

1.新建一个用户control,里面有显示和增加用户的两个Action。

using WcfServices.Contracts;

namespace MvcWcf.Controllers
{
    public class UserController : Controller
    {
        //
        // GET: /User/

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Users()
        {
            using (ChannelFactory<IUser> channelFactory = new ChannelFactory<IUser>(new WSHttpBinding(), "http://127.0.0.1:9999/userservice"))
            {
                IUser proxy = channelFactory.CreateChannel();
                using (proxy as IDisposable)
                {
                   ViewBag.Users= proxy.GetUsers().Tables[0];
                   
                }
            }
            return View();
        }

        [HttpPost]
        public string AddUser(string name, string num)
        {
            try
            {
                using (ChannelFactory<IUser> channelFactory = new ChannelFactory<IUser>(new WSHttpBinding(), "http://127.0.0.1:9999/userservice"))
                {
                    IUser proxy = channelFactory.CreateChannel();
                    using (proxy as IDisposable)
                    {
                        proxy.AddUser(name, num);
                        return "1";
                    }
                }
            }
            catch (Exception e)
            {
                return e.ToString();
            }
           
        }
    }
}
View Code

2.创建显示用户列表的View。

在方法Users上面右击,选择命令Add View,将进入到Users.cshtml,代码如下:

@{
    ViewBag.Title = "Users";
    var usersTable = ViewBag.Users;
}
<script type="text/javascript" src="../../Scripts/jquery-1.5.1.js"></script>
<script type="text/javascript">
    function AddUser() {
        $("#tblUser tr").first().after("<tr><td><input type=text /></td><td><input type=text /></td></tr>");
        $("#btnSave").attr("style", "display:");
        $("#btnCancle").attr("style", "display");
        $("#btnAdd").attr("style", "display:none");
    }
    function CancleAdd() {
        $("#tblUser tr").first().next().remove();
        $("#btnSave").attr("style", "display:none");
        $("#btnCancle").attr("style", "display:none");
        $("#btnAdd").attr("style", "display:");
    }
    function SaveUser() {
        var name = $("#tblUser tr td :input").first().val();
        var num = $("#tblUser tr td :input").last().val();
        var KeyNameJason = "{'name':'" + name + "','num':'" + num + "'}";
        $.ajax(
        {
            type: 'POST',
            contentType: 'application/json',
            url: '/User/AddUser',
            async: false,
            data: KeyNameJason,
            dataType: "text",
            success: function (data) {
                $("#tblUser tr").first().next().remove();
                $("#tblUser tr").first().after("<tr><td>" + name + "</td><td>" + num + "</td></tr>");
                $("#btnSave").attr("style", "display:none");
                $("#btnCancle").attr("style", "display:none");
                $("#btnAdd").attr("style", "display:");
                alert("Add user successfully!");
            },
            error: function (data) {
                alert(data);
            }
        });
    }
</script>
<h2>
    Users</h2>
<div>
    <div>
        <input type="button" id="btnAdd" style="width: 80px" value="Add" onclick="AddUser();" />
        <input type="button" id="btnSave" style="width:80px; display:none" value="Save" onclick="SaveUser()" />
        <input type="button" id="btnCancle" style="width:80px; display:none" value="Cancle" onclick="CancleAdd()" />
    </div>
    <div>
        <table border="1" id="tblUser">
            <tbody>
                <tr>
                    <th style="width: 120px">
                        Name
                    </th>
                    <th style="width: 120px">
                        Num
                    </th>
                </tr>
                @{
             
                    foreach (var row in usersTable.Rows)
                    {
                    <tr>
                        <td>@row[1]
                        </td>
                        <td>@row[2]
                       
                        </td>
                    </tr>
                    }   
                }
            </tbody>
        </table>
    </div>
</div>
View Code

将该MVC项目设置成启动项目,按F5运行,在地址栏输入如下:http://localhost:[端口号]/User/Users.
就可以看到列表页面和增加之类的按钮了。

 

 

posted @ 2013-09-12 16:48  Teresa.luo  阅读(526)  评论(0编辑  收藏  举报