J'ai un point de terminaison JSONP WCF et j'essaie de comprendre pourquoi j'obtiens une erreur 504.
HTTP/1.1 504 Fiddler - Échec de réception
Content-Type: text/html
Connexion: fermer
Horodatage: 11: 45: 45: 9580
ReadResponse () a échoué: le serveur n'a pas renvoyé de réponse pour cette demande.
Je peux définir un point d'arrêt n'importe où dans mon point de terminaison, parcourir le code, le voir rassembler avec succès les données requises pour la réponse, appuyer sur la dernière ligne de code, puis dès que je sors de l'appel WCF, l'erreur 504 s'affiche. Cela fonctionnait la semaine dernière!
[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;
}
}
Mon 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>
Comme je l'ai dit, le code est complet, j'essaie donc de comprendre pourquoi il n'envoie pas de réponse.
Pour ce problème particulier, cela a fini par être ma chaîne de connexion. Étant dans un service Web, il n'était pas extrait du fichier de configuration du site Web. Avec un peu de magie (codage difficile), le contexte a finalement été activé et le système a commencé à fonctionner. Pas encore complètement à travers ce 504, car d’autres erreurs sous-jacentes apparaissent maintenant - poursuivra cette réponse comme je le découvre.
2/1/2010 - Une fois que j'ai effacé les erreurs de chaîne de connexion, j'ai trouvé quelques erreurs EF de base qui ont été nettoyées très rapidement. Il est maintenant de nouveau opérationnel.
Je suis désolé, je n'ai pas de solution directe pour vous, mais lors de la recherche de problèmes liés à WCF, j'ai constaté qu'activer les journaux de trace WCF, exécuter le scénario, puis parcourir les journaux dans SvcTraceViewer.exe aide ... vous obtiendrez une certaine visibilité dans la pile, ce qui est probable lorsque les choses se détériorent sur vous.
Vous pouvez utiliser " Éditeur de configuration de service WCF " pour activer/désactiver les différents paramètres et niveaux du journal.
Je viens d'avoir un problème similaire et le traçage était le seul moyen de l'identifier (comme l'a déjà suggéré @Tyler). J'ai également eu un retour HTTP 504 du serveur et également le débogage du service dans Visual Studio n'a montré aucune exception . En fait, à partir du débogueur, il semblait que le service avait correctement renvoyé la réponse.
Dans mon cas particulier, l'erreur était due au fait qu'un des membres de ma classe de contrat de données était un type enum et que les valeurs n'avaient pas été marquées avec EnumMemberAttribute.
Vous trouverez plus d’informations sur la configuration du traçage dans WCF ici et sur les énumérations dans les contrats de données de services WCF ici .
J'ai eu le même problème à plusieurs reprises:
Dans un scénario, une propriété publique (DataMember) ne contenait que Getter et aucun séparateur. Changer ce DataMember pour avoir à la fois le getter Et le setter a résolu le problème.
Dans l'autre scénario, je sérialisais/désérialisais les POCO EF4 (avec les propriétés de navigation renseignées) vers/depuis JSON, ce qui provoquait une boucle récursive lors de la désérialisation. La modification de l'attribut de POCO en [DataContract(IsReference = true)]
a permis de résoudre le problème de la boucle récursive, mais comme DataContractJsonSerializer ne prend pas en charge les références, j'ai dû permuter le format au format XML. ( P.S. - Avec l'API WEB, le sérialiseur JSON par défaut sera JSON.NET, qui gérera la référence sans problèmes).
Conseil: Comme l'ont suggéré d'autres personnes, Enregistrement de trace WCF est votre ami pour résoudre les erreurs de 504.
J'espère que cela aidera quelqu'un. Un service de repos WCF renvoyait JSON et le violoneur me donnait un 504; ReadResponse () échouait: le serveur n’avait pas renvoyé de réponse pour cette demande.
Mon problème était que je retournais un modèle comme celui-ci:
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 };
}
}
et wcf ne semble pas comprendre comment encoder un objet. L'objet que je retournais était tout à fait correct, juste des cordes et des entrailles. J'ai dû changer la réponse à cela pour que cela fonctionne:
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 };
}
}
Avait le même problème et senario comme odyth ci-dessus. Dans mon cas, il s'agissait de l'attribut DateTime
qui était NULL
dans la classe de réponse et de la manière dont la réponse 504 de Fiddler était provoquée. Aucun problème avec les attributs de chaîne NULL
.
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; }
}
Si cela peut aider quelqu'un, j'ai rencontré ce problème en essayant de renvoyer une liste d'entityObject Entity Framework 4 à partir de Web Api. Pour résoudre ce problème, je viens de lui faire faire une sélection explicite, car EntityObject n'aime pas être sérialisé.
return Request.CreateResponse(HttpStatusCode.OK, people.Select(p => new {
p.Id,
p.Name,
p.CreateDate
}));