Попытка получить базовый URL Http с параметрами строки запроса, обработанными в службе WCF - PullRequest
2 голосов
/ 30 августа 2010

Я пытаюсь обработать сообщение сторонним сервером (Paypal), обработанным моим сервером через службу WCF (.Net 3.5 SP1). Все, что мне нужно, это получить и обработать значения с помощью строки запроса. Это звучит невероятно легко, но после выходных я все еще в тупике. Любая помощь будет принята с благодарностью.

Передача следующего URL из моего браузера в службу вызывает ошибку несоответствия AddressFilter (ниже).

http://localhost:9409/PPInfo.svc/ReadResponse?RESULT=0&AUTHCODE=10001&RESPMSG=APROVED&PNREF=12345

производит

<Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">
- <Code>
  <Value>Sender</Value> 
- <Subcode>
  <Value xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:DestinationUnreachable</Value> 
  </Subcode>
  </Code>
- <Reason>
  <Text xml:lang="en-US">The message with To 'http://localhost:9409/PPInfo.svc/ReadResponse?RESULT=0&AUTHCODE=10001&RESPMSG=APROVED&PNREF=12345' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree.</Text> 
  </Reason>
  </Fault>

// web.config
 <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ASEEESPrivate.PPInfoBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="ASEEESPrivate.PPInfoBehavior" name="ASEEESPrivate.PPInfo">
        <endpoint address="" binding="webHttpBinding" contract="ASEEESPrivate.IPPInfo">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
  </system.serviceModel>
</configuration>

================================

[ServiceContract]
public interface IPPInfo
{
    // expecting RESULT = 0 and RESPMSG = APPROVED
    [OperationContract] 
    [WebGet(UriTemplate = "Presponse?RESULT={result}&AUTHCODE={authcode}&RESPMSG={respmsg}&AVSDATA={avsdata}&PNREF={pnref}", 
        BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml)]
    void ReadResponse();
}

=========================================

// write parameters of query string to tlkpOnlineMessage table
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, AddressFilterMode=AddressFilterMode.Any)]
    public class PPInfo : IPPInfo
    {

        public void ReadResponse()
        {
            var qString = HttpContext.Current.Request.QueryString;

            var ctx =
                new MembershipEntities();

            var log = new tlkpOnlineMessage();

            foreach (string s in qString)
            {
                log.LoginPageMsg = s;
                ctx.AddTotlkpOnlineMessages(log);
            }

            ctx.SaveChanges();
        }
    }

1 Ответ

2 голосов
/ 31 августа 2010

Помимо опечатки в вашем коде, я полагаю, что у вас есть две проблемы, которые легко исправить:

1) Для службы RESTful вы должны определить поведение конечной точки и включить поведение webHttp.Вы можете сделать это, добавив <endpointBehavior> в ваш web.config следующим образом:

<behaviors>
  <serviceBehaviors>
    <behavior name="ASEEESPrivate.PPInfoBehavior">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="ASEEESPrivate.PPInfoEndpointBehavior">
      <webHttp />
    </behavior>
  </endpointBehaviors>
</behaviors>

И затем добавьте это поведение конечной точки в определение вашего сервиса:

  <service behaviorConfiguration="ASEEESPrivate.PPInfoBehavior" name="WcfRestService1.PPInfo">
    <endpoint address="" binding="webHttpBinding" contract="WcfRestService1.IPPInfo"
              behaviorConfiguration="ASEEESPrivate.PPInfoEndpointBehavior">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>

2) Во-вторыхвы определяете UriTemplate для вашего сервиса с заполнителями (результат, код авторизации и т. д.), но не определяете параметры для них в вашем интерфейсе.Если вы собираетесь определить UriTemplate для своего определения сервиса с заполнителями, то вам нужно, чтобы ваш сервис определил эти параметры соответствующим образом.Вы можете сделать это следующим образом:

[ServiceContract]
public interface IPPInfo
{
    // expecting RESULT = 0 and RESPMSG = APPROVED
    [OperationContract]
    [WebGet(UriTemplate = "ReadResponse?RESULT={result}&AUTHCODE={authcode}&RESPMSG={respmsg}&AVSDATA={avsdata}&PNREF={pnref}",
        BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml)]
    void ReadResponse(string result, string authcode, string respmsg, string avsdata, string pnref);
}


[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, AddressFilterMode = AddressFilterMode.Any)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class PPInfo : IPPInfo
{

    public void ReadResponse(string result, string authcode, string respmsg, string avsdata, string pnref)
    {
      ...
    }
}

Используя UriTemplate, вам не нужно извлекать параметры строки запроса;или, если вы хотите извлечь параметры из строки запроса, не определяйте UriTemplate.

После внесения этих двух изменений я смог запустить службу на своем компьютере локально.

Надеюсь, это поможет!

...