>

WCF Service 4.5 F/W를 사용하여 REST Full API를 개발 중입니다. 고객에게 예외 또는 비즈니스 유효성 검사 메시지를 보내는 방법을 제안하십시오. 나는 매우 일반적인 해결책을 찾고 있는데 최선의 방법을 제안하십시오. 아래에서 몇 가지 접근법을 시도했습니다.

<올>
  • 클라이언트에 응답을 보내기 전에 OutgoingWebResponseContext를 설정하십시오.

  • 정상적으로 작동하는 정의 된 결함 계약 REST FULL 환경에서 작동하지 않는 서비스 참조 (프록시 클래스) 추가

  • 캐치 블록에 WebFaultException 클래스 추가

  • WCF Rest Starter Kit-이것에 관한 기사와 게시물을 얻었지만 CodePlex 공식 앉아 더 이상 사용할 수 없다고 제안했습니다. 링크 . 그래서 저는 이것과 함께 가고 싶지 않습니다.

  • 이들은 예상대로 작동하지 않습니다. 샘플 코드 스 니펫 :     인터페이스 :

       [OperationContract]
        [FaultContract(typeof(MyExceptionContainer))]
        [WebInvoke(Method = "GET", UriTemplate = "/Multiply/{num1}/{num2}", BodyStyle = WebMessageBodyStyle.Wrapped,RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]
        string Multiply(string num1, string num2);
    
    

    구현 :

            public string Multiply(string num1, string num2)
        {
            if (num1 == "0" || num2 == "0")
            {
                try
                {
                    MyExceptionContainer exceptionDetails = new MyExceptionContainer();
                    exceptionDetails.Messsage = "Business Rule violatuion";
                    exceptionDetails.Description = "The numbers should be non zero to perform this operation";
                    //OutgoingWebResponseContext outgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse;
                    //outgoingWebResponseContext.StatusCode = System.Net.HttpStatusCode.ExpectationFailed;
                    //outgoingWebResponseContext.StatusDescription = exceptionDetails.Description.ToString();
                   // throw new WebFaultException<MyExceptionContainer>(exceptionDetails,System.Net.HttpStatusCode.Gone);
                    throw new FaultException<MyExceptionContainer>(exceptionDetails,new FaultReason("FaultReason is " + exceptionDetails.Messsage + " - " + exceptionDetails.Description));
                }
                catch (Exception ex)
                {
                    throw new FaultException(ex.Message);
                }
            }
            return Convert.ToString(Int32.Parse(num1) * Int32.Parse(num2));
        }
    
    

    Web.Config :

     <system.serviceModel>
    <services>
      <service name="TestService.TestServiceImplementation" behaviorConfiguration="ServiceBehaviour">
        <endpoint binding="webHttpBinding" contract="TestService.ITestService" behaviorConfiguration="webHttp" >
        </endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehaviour">
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="webHttp" >
          <webHttp helpEnabled="true" faultExceptionEnabled="true"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    
    

    고객 :

    try
            {
                string serviceUrl = "http://localhost:51775/TestService.cs.svc/Multiply/0/0";
                //Web Client
                //WebClient webClient = new WebClient();
                //string responseString = webClient.DownloadString(serviceUrl);
                WebRequest req = WebRequest.Create(serviceUrl);
                req.Method = "GET";
                req.ContentType = @"application/xml; charset=utf-8";
                HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
                if (resp.StatusCode == HttpStatusCode.OK)
                {
                    XmlDocument myXMLDocument = new XmlDocument();
                    XmlReader myXMLReader = new XmlTextReader(resp.GetResponseStream());
                    myXMLDocument.Load(myXMLReader);
                    Console.WriteLine(myXMLDocument.InnerText);
                }
                Console.ReadKey();
            }
            catch (Exception ex)
            { 
            Console.WriteLine(ex.Message);
            }
    
    

    이것은 나의 첫 번째 질문입니다. 모든 열정적 인 개발자들에게 감사합니다 ..!

    • 답변 # 1

      FaultException 대신

      다음을 사용하십시오.

      서버 :

      catch (Exception ex)
                  {
                      throw new System.ServiceModel.Web.WebFaultException<string>(ex.ToString(), System.Net.HttpStatusCode.BadRequest);
                  }
      
      

      고객 :

      catch (Exception ex)
                  {
                      var protocolException = ex as ProtocolException;
                      var webException = protocolException.InnerException as WebException;
                      if (protocolException != null && webException != null)
                      {
                          var responseStream = webException.Response.GetResponseStream();
                          var error = new StreamReader(webException.Response.GetResponseStream()).ReadToEnd();
                          throw new Exception(error);
                      }
                      else
                          throw new Exception("There is an unexpected error with reading the stream.", ex);
                  }
      
      

    • 답변 # 2

      wcf에서 진정한 휴식을 취하는 것은 불가능한 일이지만 http 프로토콜의 일부를 활용하는 것은 물론 가능합니다.

      서비스의 오류 메시지를 제어하려면 wcf 스택에 연결하고 여기에 정의 된 오류 처리를 재정의하는 오류 처리기 (I errorhandler 구현)를 제공해야합니다.

      이 인터페이스에는 두 가지 방법이 있습니다. 하나는 wcf에게 특정 예외 (bool HandleError)를 처리 할 수 ​​있는지 알리고 다른 하나는 HandleError가 true를 반환하면 호출합니다. 이 두 번째 방법 인 ProvideFault를 사용하면 예외 발생시 클라이언트에 응답하는 방법을 정의 할 수 있습니다.

      핸들러를 연결하여 더 세분화 할 수 있습니다. 그리고 휴식을 취하고 있기 때문에 아마도 http probablystatus 코드를 사용하여 해당되는 경우 오류 상태를 알려야합니다.

      http://blogs.msdn.com/b/carlosfigueira/archive/2011/06/07/wcf-extensibility-ierrorhandler.aspx

      http://www.remondo.net/wcf-global-exception-handling-attribute-and-ierrorhandler/

    • 답변 # 3

      Web.Config :

      <system.serviceModel>
         <services>
          <service name="TestService.TestServiceImplementation">
            <endpoint address=""
                      binding="webHttpBinding"
                      contract="TestService.Service.ITestServiceImplementation" />
          <service/>
        <services/>
          <behaviors>
            <serviceBehaviors>
              <behavior>         
                <serviceMetadata httpGetEnabled="true"/>         
                <serviceDebug includeExceptionDetailInFaults="true"/>
              <behavior/>
            <serviceBehaviors/>
          <behaviors/>
          <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
        <system.serviceModel/>
       <system.webServer>
          <modules runAllManagedModulesForAllRequests="true"/>   
          <directoryBrowse enabled="true"/>
        <system.webServer/>
      
      

      구현 :

      public string Multiply(string num1, string num2)
      {
          if (num1 == "0" || num2 == "0")
          {
              try
              {
                  MyExceptionContainer exceptionDetails = new MyExceptionContainer();
                  exceptionDetails.Messsage = "Business Rule violatuion";
                  exceptionDetails.Description = "The numbers should be non zero to perform this operation";
                  //OutgoingWebResponseContext outgoingWebResponseContext = WebOperationContext.Current.OutgoingResponse;
                  //outgoingWebResponseContext.StatusCode = System.Net.HttpStatusCode.ExpectationFailed;
                  //outgoingWebResponseContext.StatusDescription = exceptionDetails.Description.ToString();
                 // throw new WebFaultException<MyExceptionContainer>(exceptionDetails,System.Net.HttpStatusCode.Gone);
                  throw new FaultException<MyExceptionContainer>(exceptionDetails,new FaultReason("FaultReason is " + exceptionDetails.Messsage + " - " + exceptionDetails.Description));
              }
              catch (FaultException ex)
              {
                  throw new FaultException(ex.Message);
              }
          }
          return Convert.ToString(Int32.Parse(num1) * Int32.Parse(num2));
      }
      
      

    관련 자료

  • 이전 javascript - D3 그래프에서 가장자리에 이미지를 추가하는 방법은 무엇입니까?
  • 다음 nodejs 버전 v01109 용 엣지 모듈