通过jQuery以HTTP GET/POST方式调用WCF服务

时间:2023-02-09 13:20:26

1.建立WCF项目,默认会建立一个.svc文件,不过这里我们不用它,因为这是以普通方式访问WCF服务的文件,我们要建立一个“启用了AJAX的WCF服务”的.svc文件。(当然你也可以使用默认的这个svc文件,不过需要修改web.config的地方要多一些)
2.修改建立好的.svc文件标记,增加Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory"属性,如

<%@ ServiceHost Language="C#" Debug="true" Service="Scheduler_WcfService.SchedulerService" CodeBehind="SchedulerService.svc.cs"    Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory"%>

3.修改web.config,如下

<system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
    <services>
      <service name="Scheduler_WcfService.SchedulerService" behaviorConfiguration="Scheduler_WcfService.SchedulerService">
        <endpoint address="" behaviorConfiguration="Scheduler_WcfService.SchedulerServiceBehavior"
          binding="webHttpBinding" contract="Scheduler_WcfService.ISchedulerService" />
        <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="Scheduler_WcfService.SchedulerServiceBehavior">
          <enableWebScript />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="Scheduler_WcfService.SchedulerService">
          <serviceMetadata httpGetEnabled="true" httpGetUrl=""/>
          <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
</system.serviceModel>

注意一些节点
<enableWebScript />、<serviceMetadata httpGetEnabled="true" httpGetUrl=""/>、<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />

4.WCF服务如下

WCF契约接口


namespace Scheduler_WcfService
{
    // 注意: 如果更改此处的接口名称 "ISchedulerService",也必须更新 Web.config 中对 "ISchedulerService" 的引用。
    [ServiceContract]
    public interface ISchedulerService
    {

        // 任务: 在此处添加服务操作

        [OperationContract]
        XElement GetCalendars(ParamObject param);

        [OperationContract]
        string AddCalendar(ParamObject param);

        [OperationContract]
        string DeleteCalendar(ParamObject param);

        [OperationContract]
        string UpdateCalendar(ParamObject param);

    }


    // 使用下面示例中说明的数据约定将复合类型添加到服务操作。
    [DataContract]
    public partial class ParamObject
    {
       
    }
}

契约接口实现如下


namespace Scheduler_WcfService
{

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class SchedulerService : ISchedulerService
    {
        // 添加 [WebGet] 属性以使用 HTTP GET
        private string ConnectionString
        {
            get
            {
                return ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
            }
        }

        /// <summary>
        /// 获取当前时间日历xml
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [WebGet(ResponseFormat = WebMessageFormat.Xml, RequestFormat = WebMessageFormat.Json)]
        public XElement GetCalendars(ParamObject param)
        {
            string outputStr = "";
            string selectedTime = param.Selectedtime;
            string timeType = param.Timetype;
            string currUser = param.CurrUser;
            Calendar_BLL calendar_bll = new Calendar_BLL(ConnectionString);
            return calendar_bll.GetCalendarContentXML(calendar_bll.GetCalendars(selectedTime, timeType, currUser));
        }

        /// <summary>
        /// 增加操作
        /// </summary>
        /// <param name="param"></param>
        /// <param name="calendarContent"></param>
        /// <returns></returns>
        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        public string AddCalendar(ParamObject param)
        {
            string outputStr = "";
            string eventID = param.Event_id;
            DateTime startDate = DateTime.Now;
            DateTime.TryParse(param.Start_date, out startDate);
            DateTime endDate = DateTime.Now;
            DateTime.TryParse(param.End_date, out endDate);
            string text = param.Title;
            string detailvalue = param.Details;
            string currUser = param.CurrUser;
            string SectionId = param.Section_id;
            Calendar_BLL calendar_bll = new Calendar_BLL(ConnectionString);
            calendar_bll.AddCalendarContent(new Scheduler_Dal.Calendar_Content
            {
                event_id = eventID,
                text = text,
                start_date = startDate,
                end_date = endDate,
                details = detailvalue,
                section_id = SectionId
            });
            calendar_bll.AddCalendarPermission(new Scheduler_Dal.Calendar_Permission
            {
                ID = Guid.NewGuid().ToString(),
                event_id = eventID,
                userid = currUser,
                permission = "完全"
            });
            outputStr = "增加成功!";
            return outputStr;
        }

        /// <summary>
        /// 删除操作
        /// </summary>
        /// <param name="param"></param>
        /// <param name="calendarContent"></param>
        /// <returns></returns>
        [WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        public string DeleteCalendar(ParamObject param)
        {
            string outputStr = "";
            string eventID = param.Event_id;
            string currUser = param.CurrUser;
            Calendar_BLL calendar_bll = new Calendar_BLL(ConnectionString);
            calendar_bll.DeleteCalendarContent(new Scheduler_Dal.Calendar_Content
            {
                event_id = eventID
            });
            string calendar_permission_id = calendar_bll.GetCalendarPermission(new Scheduler_Dal.Calendar_Permission
            {
                event_id = eventID,
                userid = currUser,
                permission = "完全"
            });
            calendar_bll.DeleteCalendarPermission(new Scheduler_Dal.Calendar_Permission
            {
                ID = calendar_permission_id,
                event_id = eventID,
                userid = currUser,
                permission = "完全"
            });
            outputStr = "删除成功!";
            return outputStr;
        }


        /// <summary>
        /// 修改操作
        /// </summary>
        /// <param name="param"></param>
        /// <param name="calendarContent"></param>
        /// <returns></returns>
        [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        public string UpdateCalendar(ParamObject param)
        {
            string outputStr = "";
            string eventID = param.Event_id;
            DateTime startDate = DateTime.Now;
            DateTime.TryParse(param.Start_date, out startDate);
            DateTime endDate = DateTime.Now;
            DateTime.TryParse(param.End_date, out endDate);
            string text = param.Title;
            string detailvalue = param.Details;
            string SectionId = param.Section_id;
            Calendar_BLL calendar_bll = new Calendar_BLL(ConnectionString);
            calendar_bll.UpdateCalendarContent(new Scheduler_Dal.Calendar_Content
            {
                event_id = eventID,
                text = text,
                start_date = startDate,
                end_date = endDate,
                details = detailvalue,
                section_id = SectionId
            });
            outputStr = "编辑成功!";
            return outputStr;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        [WebGet(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        public string SearchCalendar(ParamObject param)
        {
            int indexPage = 0;
            int.TryParse(param.IndexPage, out indexPage);
            int pageSize = 0;
            int.TryParse(param.PageSize, out pageSize);
            Calendar_BLL calendar_bll = new Calendar_BLL(ConnectionString);
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            return serializer.Serialize(calendar_bll.SearchCalendars(param.Search_str, param.CurrUser, indexPage, pageSize));
        }
        // 在此处添加更多操作并使用 [OperationContract] 标记它们
    }

    /// <summary>
    /// 消息对象
    /// </summary>
    public partial class ParamObject
    {
        /// <summary>
        /// 请求时间类型
        /// </summary>
        private string _timetype = "";

        [DataMember]
        public string Timetype
        {
            get { return _timetype; }
            set { _timetype = value; }
        }

        .............   

    }
}

这里有几点说明

WebGet特性描述了方法可以接受HTTP GET的请求,不过众所周知GET的方式请求的字段有2k的限制,并且请求通常需要url转码处理。
对于大数据量需要使用WebInvoke特性描述方法,WebInvoke特性结合Method属性的基础传输谓词(如 HTTP POST、PUT 或 DELETE)可以REST的方式访问服务。

使用中还需要注意就是WebInvoke中的WebMessageBodyStyle属性指定是否包装参数和返回值,因为它直接关系到反序列化对象的json格式和序列化到客户端的后格式,特别是在调用方法存在多个复杂参数对象时是需要包装请求才能正确访问的。
Bare    不包装请求和响应。
Wrapped    包装请求和响应。
WrappedRequest    包装请求,但不包装响应。
WrappedResponse    包装响应,但不包装请求。

5.最后看一下客户端调用方式

     scheduler.attachEvent("onEventAdded", function(event_id, event_object) {
        addEvent({ Event_id: event_id,
            Start_date: event_object.start_date.format("yyyy-MM-dd HH:mm:ss"),
            End_date: event_object.end_date.format("yyyy-MM-dd HH:mm:ss"),
            Title: event_object.text,
            Details: event_object.details,
            CurrUser: scheduler.CurrUser,
            Section_id: event_object.section_id == "" ? "1" : event_object.section_id
        });
    });
    scheduler.attachEvent("onEventChanged", function(event_id, event_object) {
        updateEvent({ Event_id: event_id,
            Start_date: event_object.start_date.format("yyyy-MM-dd HH:mm:ss"),
            End_date: event_object.end_date.format("yyyy-MM-dd HH:mm:ss"),
            Title: event_object.text,
            Details: event_object.details,
            Section_id: event_object.section_id
        });
    });

function
reloadEvent(mode, date) {
    scheduler.clearAll();
    var param = encodeURI(JSON.stringify({ CurrUser: scheduler.CurrUser, Selectedtime: date, Timetype: mode }));
    scheduler.load(scheduler.WCFHOST + "GetCalendars?" + "param=" + param + "&refresh=" + Math.random());
}

function deleteEvent(eventid) {
    var param = encodeURI(JSON.stringify({ CurrUser: scheduler.CurrUser, Event_id: eventid }));
    $.get(scheduler.WCFHOST + "DeleteCalendar?" + "param=" + param, null,
         function(msg) {
             GrowMessage(JSON.parse(msg, null).d);
             reloadEvent(scheduler.customMode, scheduler.customDate);
         });
}

function addEvent(paramJson) {
    ajaxPost(scheduler.WCFHOST + "AddCalendar", JSON.stringify({ param: paramJson }), function(msg) {
        GrowMessage(JSON.parse(msg, null).d);
        reloadEvent(scheduler.customMode, scheduler.customDate);
    });
}
function updateEvent(paramJson) {
    ajaxPost(scheduler.WCFHOST + "UpdateCalendar", JSON.stringify({ param: paramJson }), function(msg) {
        GrowMessage(JSON.parse(msg, null).d);
        reloadEvent(scheduler.customMode, scheduler.customDate);
    });
}

function ajaxPost(url, data, successfun) {
    $.ajax({
        type: "POST",
        url: url,
        data: data,
        contentType: "application/json",
        dataType: "text",
        success: successfun,
        error: debugError
    });
}