WCF 休息 - 没有找到元素错误

Posted

技术标签:

【中文标题】WCF 休息 - 没有找到元素错误【英文标题】:WCF Rest - no elemnt found error 【发布时间】:2013-09-24 11:44:59 【问题描述】:

我设计了一个 WCF REST 服务并尝试通过 html 页面中的 JQuery 使用它。当我在创建 WCF 服务的解决方案中添加 html 页面时,我根据需要得到了结果。但是当我在不同的解决方案中创建 HTML 页面时,我开始收到错误,例如找不到元素并且返回的结果为空。

我在服务中放置了一个调试器,我注意到即使消费者 html 页面保存在不同的解决方案中,它仍然会在调用服务时命中 global.asax 文件,但它没有命中任何方法。 我什至放了“crossDomain:true”和“jQuery.support.cors = true;”在用于启用跨域问题的脚本中,以及我也在 Global.asax 文件中进行了更改,但没有用。 请尽快为我提供相同的解决方案。

我将带有配置文件和 DataContracts 的实际代码连同 HTML 代码放在这里:

ICouponService.cs:

    [ServiceContract]
public interface ICouponService

    [OperationContract]
    [WebInvoke(UriTemplate = "/GenerateCoupon",
        Method = "POST",
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json)]
    CouponData GenerateCoupon(CouponData objCustomerData);

    [OperationContract]
    [WebInvoke(UriTemplate = "/UpdateGeneratedCoupon",
        Method = "POST",
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json)]
    ResponseMessage UpdateGeneratedCoupon(CouponData objCustomerData);

CouponService.cs:

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
public class CouponService : ICouponService


    public CouponData GenerateCoupon(CouponData objCustomerData)
    
return objCouponData;
    


    public ResponseMessage UpdateGeneratedCoupon(CouponData objCustomerData)
    
return objResponseMessage;

    
    

CouponData.cs:

    [DataContract]
    public class CouponData
    
    [DataMember(EmitDefaultValue = false)]
    public string Email  get; set; 

    [DataMember(EmitDefaultValue = false)]
    public string Points  get; set; 

    [DataMember(EmitDefaultValue = false)]
    public string ActiveFlag  get; set; 

    [DataMember(EmitDefaultValue = false)]
    public string CouponCode  get; set; 

    [DataMember(EmitDefaultValue = false)]
    public string RequestID  get; set; 

    [DataMember(EmitDefaultValue = false)]
    public string LoyaltyID  get; set; 

    [DataMember(EmitDefaultValue = false)]
    public string Result  get; set; 

    [DataMember(EmitDefaultValue = false)]
    public string ReturnFlag  get; set; 

    [DataMember(EmitDefaultValue = false)]
    public string UserName  get; set; 

    [DataMember(EmitDefaultValue = false)]
    public string Password  get; set; 

ResponseMessage.cs:

    [DataContract]
public class ResponseMessage

    [DataMember(EmitDefaultValue = false)]
    public string Response  get; set; 

全球.asax: 首先我认为可能有一些 Header 问题,所以我在 Global 文件中添加了相同的内容,如下所示:

    protected void Session_Start(object sender, EventArgs e)
    
        string sessionId = Session.SessionID;
    

    protected void Application_BeginRequest(object sender, EventArgs e)
    
        HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        HttpContext.Current.Response.Cache.SetNoStore();
        EnableCrossDomainAjaxCall();
    

    private void EnableCrossDomainAjaxCall()
    

        if (!string.IsNullOrEmpty(Request.ServerVariables["HTTP_ORIGIN"]))
        
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", Request.ServerVariables["HTTP_ORIGIN"]); 
            if (!string.IsNullOrEmpty(HttpContext.Current.Request.HttpMethod))
            
                if (HttpContext.Current.Request.HttpMethod == "OPTIONS" || HttpContext.Current.Request.HttpMethod == "POST" || HttpContext.Current.Request.HttpMethod == "GET")
                
                    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST");
                    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
                    HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
                    //HttpContext.Current.Response.End();
                
            
        
    

Web.config:

    <?xml version="1.0"?>
    <configuration>
    <system.web>
    <compilation debug="true" targetFramework="4.0" />
    </system.web>
    <system.serviceModel>
    <services>
    <service behaviorConfiguration="ServiceBehaviour" name="SAM_STORE_LoyaltyProgram_WCFLibrary.CouponService">
    <endpoint address="" behaviorConfiguration="web" binding="webHttpBinding"
      contract="SAM_STORE_LoyaltyProgram_WCFLibrary.ICouponService" />
   </service>
   <service name="SAM_STORE_LoyaltyProgram_WCFServices.qqq">
    <endpoint address="" behaviorConfiguration="SAM_STORE_LoyaltyProgram_WCFServices.qqqAspNetAjaxBehavior"
      binding="webHttpBinding" contract="SAM_STORE_LoyaltyProgram_WCFServices.qqq" />
   </service>
   </services>
   <behaviors>
  <endpointBehaviors>
    <behavior name="web">
      <webHttp />
    </behavior>
    <behavior name="SAM_STORE_LoyaltyProgram_WCFServices.qqqAspNetAjaxBehavior">
      <enableWebScript />
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="ServiceBehaviour">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
      <dataContractSerializer maxItemsInObjectGraph="5000" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
  multipleSiteBindingsEnabled="true" />
<bindings>
    <webHttpBinding>
    <binding maxBufferSize="5000" maxReceivedMessageSize="5000"
      transferMode="Streamed">
      <readerQuotas maxDepth="5000" maxStringContentLength="5000"
        maxArrayLength="5000" maxBytesPerRead="5000" maxNameTableCharCount="5000" />
      <security mode="None" />
    </binding>
    </webHttpBinding>
    </bindings>
    </system.serviceModel>
    <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    </system.webServer>
    </configuration>

Index.html(用于调用服务的脚本):

    <script src="js/jquery-1.7.min.js" type="text/javascript"></script>
<script type="text/javascript">
    var Type;
    var Url;
    var Data;
    var ContentType;
    var DataType;
    var ProcessData;
    var method;
    var eMail;
    var points;
    var requestId;
    var couponCode;
    var returnFlag;
    var userName;
    var password;

    //Generic function to call Service
    function CallService() 
        $.ajax(
            type: Type,
            url: Url,
            data: Data,
            contentType: ContentType,
            dataType: DataType,
            //crossDomain:true,  --This is not working
            processdata: ProcessData,
            success: function (msg) 
                ServiceSucceeded(msg);
            ,
            error: function (msg) 
                alert("Service Failed");
                ServiceFailed(msg);
            
        );
    

    function SetGenerateCouponValues() 
        eMail = $("#txtEmail").val();
        points = $("#txtPoints").val();
        requestId = $("#txtRequestId").val();
        userName = 'username';
        password = 'JEBtJHVu';
    

    function DestroyGenerateCouponValues() 
        eMail = null;
        points = null;
        requestId = null;
        userName = null;
        password = null;
    

    function SetUpdateCouponValues() 
        couponCode = $("#txtCode").val();
        returnFlag = $("#txtFlag").val();
        userName = 'username';
        password = 'JEBtJHVu';
    

    function DestroyUpdateCouponValues() 
        couponCode = null;
        returnFlag = null;
        userName = null;
        password = null;

    

    function ServiceFailed(result) 
        alert('Service call failed: ' + result.status + '' + result.statusText);
        Type = null; Url = null; Data = null; ContentType = null; DataType = null; ProcessData = null;
    

    function GenerateCoupon() 
        SetGenerateCouponValues();
        Type = "POST";
        Url = "ServiceURL";
        Data = ' "Email": "' + eMail + '",   "Points": "' + points + '",  "UserName": "' + userName + '",  "Password": "' + password + '",  "RequestID": "' + requestId + '"';
        ContentType = "application/json; charset=utf-8";
        DataType = "json";
        ProcessData = true;
        method = "GenerateCoupon";
        CallService();
        DestroyGenerateCouponValues();
    

    function UpdateGeneratedCoupon() 
        SetUpdateCouponValues();
        Type = "POST";
        Url = "ServiceURL";
        Data = ' "CouponCode": "' + couponCode + '",   "ReturnFlag": "' + returnFlag + '",  "UserName": "' + userName + '",  "Password": "' + password + '"';
        ContentType = "application/json; charset=utf-8";
        DataType = "json";
        ProcessData = true;
        method = "UpdateGeneratedCoupon";
        CallService();
        DestroyUpdateCouponValues();
    

    function ServiceSucceeded(result) 
        if (DataType == "json") 
            if (method == "GenerateCoupon") 
                var string = "Coupon Code : " + result.CouponCode + "<br/>" + "Points : " + result.Points + "<br/>" + "Result : " + result.Result;
                $("#resultCreate").html(string);
                $("#lblCouponCode").text(result.CouponCode);
                $("#lblPoints").text(result.Points);
                $("#lblResult").text(result.Result);
            
            else if (method == "UpdateGeneratedCoupon") 
                var string = "Response : " + result.Response;
                $("#resultDelete").html(string);
                $("#lblResponse").text(result.Response);
            
        
    

    /*function ServiceFailed(xhr) 
    alert("FAIL" + xhr.responseText);
    if (xhr.responseText) 
    var err = xhr.responseText;
    if (err)
    error(err);
    else
    error( Message: "Unknown server error." )
    
    return;
    */

    $(document).ready(
     function () 
         //jQuery.support.cors = true;  --This is not working

         $("#btnsubmit").click(function () 
             GenerateCoupon();
         );

         $("#btnUpdateGeneratedCoupon").click(function () 
             UpdateGeneratedCoupon();
         );
     );
</script>

请尽快为我提供相同的解决方案。

【问题讨论】:

此代码在 IIS 上部署时可以在 IE10 和其他浏览器上正常工作,但它仍然会导致 IE9 及以下版本的 IE 出现问题。在 IE 上显示错误 - “访问被拒绝。” 【参考方案1】:

尝试启用WCF tracing 和ETW tracing 以查看调用服务操作时服务器端发生的情况。

【讨论】:

我也试过这个,但我没有从日志中得到任何有用的信息,即。日志文件不包含任何错误。 你看到请求进入服务了吗? 正如我在上面发布的,当部署在 IIS 上时,此代码在 IE10 和其他浏览器上运行良好,但它仍然会导致 IE9 及以下版本的 IE 出现问题。在 IE 上它显示和错误 - “访问被拒绝。”,在 IE9 及以下版本的 IE 中它甚至没有命中服务。【参考方案2】:

是调用ServiceSucceeded方法吗?? 如果调用 ServiceSucceeded 尝试将 $.support.cors = true; 放入 CallService() 启动然后检查它

【讨论】:

是的,是调用ServiceSucceeded方法,我也试过代码$.support.cors = true;但它仍然显示相同的错误,没有找到元素。

以上是关于WCF 休息 - 没有找到元素错误的主要内容,如果未能解决你的问题,请参考以下文章

WCF 休息 WebInvoke 获取方法不起作用返回 404 错误

同一端点(svc 文件)上的两个休息式 WCF 合同

在 WCF 休息服务中处理 404

WCF 休息服务 - 获得对 HTTP 响应标头的访问权限

未找到 WCF 休息方法/操作 - 一切似乎都已正确配置

从同一主机上的子域访问时未找到 WCF 错误