Domanda

Ho un endpoint WCF JSONP e sto cercando di rintracciare il motivo per cui ricevo un errore 504.

HTTP/1.1 504 Fiddler - Ricezione fallita
Tipo di contenuto:testo/html
Connessione:vicino
Timestamp:11:45:45:9580
ReadResponse() non è riuscito:Il server non ha restituito una risposta per questa richiesta.

Posso impostare un punto di interruzione ovunque all'interno del mio endpoint, scorrere il codice, vederlo raccogliere con successo i dati richiesti per la risposta, premere l'ultima riga di codice, quindi non appena esco dalla chiamata WCF ricevo un errore 504. Funzionava la settimana scorsa!

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceContract(Name = "NegotiateService", Namespace = "http://rivworks.com/Services/2009/01/15")]
public class NegotiateService //: svcContracts.INegotiateService
{
    public NegotiateService() { }

    [OperationContract]
    [WebGet(ResponseFormat = WebMessageFormat.Json)]
    public dataObjects.NegotiateSetup GetSetup(string method, string jsonInput)
    {
        dataObjects.NegotiateSetup resultSet = new dataObjects.NegotiateSetup();

        using (RivFeedsEntities1 _dbFeed = new FeedStoreReadOnly(AppSettings.FeedAutosEntities_connString, "", "").ReadOnlyEntities())
        {
            using (RivEntities _dbRiv = new RivWorksStore(AppSettings.RivWorkEntities_connString, "", "").NegotiationEntities())
            {
                // Deserialize the input and get all the data we need...
                Newtonsoft.Json.Linq.JObject o = Newtonsoft.Json.Linq.JObject.Parse(jsonInput);
                string urlRef = String.Format("{0}", o["ref"]).Replace("\"", "");
                string clientDate = String.Format("{0}", o["dt"]).Replace("\"", "");
                string ProductID = String.Format("({0})", o["productId"]).Replace("\"", "");
                string SKU = String.Format("{0}", o["sku"]).Replace("\"", "");
                string env = String.Format("{0}", o["env"]).Replace("\"", "");

                IList<Product> efProductList = null;
                Product workingProduct = null;
                vwCompanyDetails workingCompany = null;
                bool foundItem = false;

                if (!String.IsNullOrEmpty(SKU))
                    efProductList = _dbRiv.Product.Include("Company").Where(a => a.SKU == SKU).ToList();
                else if (!String.IsNullOrEmpty(ProductID))
                    efProductList = _dbRiv.Product.Include("Company").Where(a => a.ProductId == new Guid(ProductID)).ToList();

                foreach (Product product in efProductList)
                {
                    if (String.IsNullOrEmpty(product.URLDomain))
                    {
                        var efCompany = _dbRiv.vwCompanyDetails
                                              .Where(a => a.defaultURLDomain != null && a.CompanyId == product.Company.CompanyId)
                                              .FirstOrDefault();

                        if (efCompany != null && urlRef.Contains(efCompany.defaultURLDomain))
                        {
                            foundItem = true;
                            workingProduct = product;
                            workingCompany = efCompany;
                        }
                    }
                    else
                    {
                        if (urlRef.Contains(product.URLDomain))
                        {
                            foundItem = true;
                            workingProduct = product;
                            workingCompany = _dbRiv.vwCompanyDetails
                                                   .Where(a => a.CompanyId == product.Company.CompanyId)
                                                   .FirstOrDefault();
                        }
                    }
                }

                if (foundItem)
                {
                    try
                    {
                        // Update the resultSet...
                        if (workingProduct != null && workingCompany != null)
                        {
                            string rootUrl = String.Empty;
                            try
                            {
                                rootUrl = AppSettings.RootUrl;
                            }
                            catch
                            {
                                rootUrl = env + @"/";
                            }
                            resultSet.button = workingProduct.ButtonConfig;
                            resultSet.swfSource = String.Format(@"{0}flash/negotiationPlayer.swf", rootUrl);
                            resultSet.gateway = rootUrl;
                            resultSet.productID = workingProduct.ProductId.ToString();
                            resultSet.buttonPositionCSS = workingProduct.buttonPositionCSS;
                        }
                    }
                    catch (Exception ex)
                    {
                        log.WriteLine("      ERROR: ", ex.Message);
                        log.WriteLine("STACK TRACE: ", ex.StackTrace);
                    }
                }
            }
        }
        return resultSet;
    }
}

Il mio web.config:

<!-- WCF configuration -->
<system.serviceModel>
  <behaviors>
    <endpointBehaviors>
      <behavior name="JsonpServiceBehavior">
        <webHttp />
      </behavior>
    </endpointBehaviors>
  </behaviors>

  <services>
    <service name="RivWorks.Web.Service.NegotiateService">
      <endpoint address=""
              binding="customBinding"
              bindingConfiguration="jsonpBinding"
              behaviorConfiguration="JsonpServiceBehavior"
              contract="RivWorks.Web.Service.NegotiateService" />
    </service>
  </services>

  <extensions>
    <bindingElementExtensions>
      <add name="jsonpMessageEncoding" type="RivWorks.Web.Service.JSONPBindingExtension, RivWorks.Web.Service, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
    </bindingElementExtensions>
  </extensions>

  <bindings>
    <customBinding>
      <binding name="jsonpBinding" >
        <jsonpMessageEncoding />
        <httpTransport manualAddressing="true"/>
      </binding>
    </customBinding>
  </bindings>    
</system.serviceModel>

Come ho detto, il codice viene eseguito fino in fondo, quindi sto cercando di capire perché non invia una risposta.

È stato utile?

Soluzione 3

Per questo particolare problema è diventata la mia stringa di connessione.Essendo in un servizio Web, non veniva estratto dal file di configurazione del sito Web.Con un po' di magia (hard coding) sono riuscito finalmente ad attivare il contesto e il sistema ha iniziato a funzionare.Non ancora completamente attraverso questo 504 poiché ora stanno emergendo altri errori sottostanti: continuerò questa risposta man mano che lo capirò.

01/02/2010 - Una volta eliminati gli errori della stringa di connessione, ho riscontrato un paio di errori EF di base che sono stati eliminati molto rapidamente.Ora è di nuovo attivo e funzionante.

Altri suggerimenti

Mi dispiace di non avere una soluzione diretta per te, ma durante la ricerca di problemi relativi a WCF, ho scoperto che l'attivazione dei registri di traccia WCF, l'esecuzione dello scenario, quindi l'esame dei registri in SvcTraceViewer.exe aiuta...otterrai una certa visibilità nello stack che è probabilmente il punto in cui le cose ti stanno crollando.

È possibile utilizzare il "Editor di configurazione del servizio WCF" per attivare/disattivare le varie impostazioni e livelli di registro.

Ho appena avuto un problema simile e il tracciamento era l'unico modo per identificarlo (come già suggerito da @Tyler).Ho anche ricevuto una risposta HTTP 504 dal server e ho anche eseguito il debug del servizio in Visual Studio non ha mostrato alcuna eccezione.In effetti, dal debugger sembrava che il servizio avesse restituito correttamente la risposta.

Nel mio caso particolare la causa dell'errore era che uno dei membri della mia classe di contratto dati era di tipo enum e i valori non erano stati contrassegnati con EnumMemberAttribute.

È possibile trovare ulteriori informazioni sulla configurazione della traccia in WCF Qui e sulle enumerazioni nei contratti dati dei servizi WCF Qui.

Ho avuto lo stesso problema un paio di volte:

  • In uno scenario uno dei beni pubblici (Datamember) aveva solo Getter e nessun setter.Modifica quel DataMember per avere sia Getter che Setter hanno risolto il problema.

  • Nell'altro scenario stavo serializzando/deserializzando POCO EF4 (con le proprietà di navigazione popolate) su/da JSON e questo ha causato un ciclo ricorsivo durante la deserializzazione.Modifica dell'attributo del POCO in [DataContract(IsReference = true)] ha aiutato a risolvere il problema del ciclo ricorsivo, ma poiché DataContractJsonSerializer non supporta i riferimenti ho dovuto cambiare il formato in XML.(PS - Con l'API WEB il serializzatore JSON predefinito sarà JSON.NET che gestirà il riferimento senza problemi).

Suggerimento: Come altri hanno suggerito, Registrazione della traccia WCF è tuo amico per risolvere 504 errori.

Spero che questo possa aiutare qualcuno.Avevo un servizio di riposo WCF che restituiva JSON e il violinista mi stava dando un 504, ReadResponse() non è riuscito:Il server non ha restituito una risposta per questa richiesta.

Il mio problema era che stavo restituendo un modello come questo:

public class ServerResult
{
    public StatusCode Status { get; set; }
    public object Data { get; set; }

    public static ServerResult CreateServerResult(StatusCode status)
    {
        return new ServerResult() { Status = status };
    }

    public static ServerResult CreateServerResult(StatusCode status, object data)
    {
        return new ServerResult() { Data = data, Status = status };
    }
}

e wcf non sembra capire come codificare un oggetto.L'oggetto che stavo restituendo andava benissimo, solo stringhe e int.Ho dovuto modificare la risposta a questo perché funzionasse:

public class ServerResult<T>
{
    public StatusCode Status { get; set; }
    public T Data { get; set; }

    public static ServerResult<T> CreateServerResult(StatusCode status)
    {
        return new ServerResult<T>() { Status = status };
    }

    public static ServerResult<T> CreateServerResult(StatusCode status, T data)
    {
        return new ServerResult<T>() { Data = data, Status = status };
    }
}

Aveva lo stesso problema e scenario di Odyth sopra.Nel mio caso lo era DateTime attribuire com'era NULL nella classe respons, come ha causato la risposta 504 di Fiddler.Nessun problema con NULL attributi di stringa.

public class Brevutskick
{
    public string DocumentCode { get; set; }
    public string DocumentName { get; set; }
    public string Status { get; set; }
    public DateTime DateCreated { get; set; }
    public string DataTemplate { get; set; }
}

Se può essere d'aiuto a qualcuno, mi sono imbattuto in questo tentativo di restituire un elenco di "EntityObject" di Entity Framework 4 da Web Api.Per risolverlo, ho semplicemente fatto fare una selezione esplicita, poiché a EntityObject non piace essere serializzato.

return Request.CreateResponse(HttpStatusCode.OK, people.Select(p => new {
    p.Id,
    p.Name,
    p.CreateDate
}));
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top