I have a JSONP WCF Endpoint and am trying to track down why I am getting a 504 error.
HTTP/1.1 504 Fiddler - Receive Failure
Content-Type: text/html Connection: close Timestamp: 11:45:45:9580 ReadResponse() failed: The server did not return a response for this request.
I can set a breakpoint anywhere inside of my Endpoint, step through code, see it successfully gather the data required for the response, hit the final line of code, then as soon as I step out of the WCF call I get a 504 error. This was working last week!
[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.Negotiat开发者_StackOverflow社区eSetup 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;
}
}
My 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>
As I said, the code runs all the way through so I am trying to figure out why it is not sending a response.
I'm sorry I don't have a direct solution for you, but when chasing down WCF-related issues, I've found that turning on the WCF trace logs, running through the scenario, then going over the logs in SvcTraceViewer.exe helps... you'll get some visibility into the stack which is likely where things are breaking down on you.
You can use the "WCF Service Configuration Editor" to turn on/off the various log settings and levels.
I just had a similar issue and tracing was the only way to identify it (as already suggested by @Tyler). I also had an HTTP 504 return from the server and also debugging the service in Visual Studio didn't show any exception. In fact, from the debugger it looked like the service properly returned the response.
In my particular case the cause of the error was that one of the members of my data contract class was an enum type and the values haven't been marked with the EnumMemberAttribute.
You can find more info about configuring tracing in WCF here and about enums in WCF services data contracts here.
For this particular problem it ended up being my connection string. Being in a web service, it was not pulling from the web site's config file. With a little bit of magic (hard coding) I got the Context to finally activate and the system started working. Not fully through this 504 yet as I have other underlying errors now popping up - will continue this answer as I figure it out.
2/1/2010 - Once I cleared up the connection string errors I found a couple basic EF errors that were very quickly cleaned up. It is now up and running again.
I had the same issue couple of times:
In one scenario one of the public property (DataMember) only had getter and no setter. Changing that DataMember to have both getter and setter solved the problem.
In the other scenario I was serializing/deserializing EF4 POCO's (with Navigation properties populated) to/from JSON and this caused an recursive loop during deserialization. Changing the POCO's attribute to
[DataContract(IsReference = true)]
helped solve the recursive loop problem, but since DataContractJsonSerializer does not support references I had to switch the format to XML. (P.S. - With WEB API the default JSON serializer will be JSON.NET which will handle reference without problems).
Hint: As others have suggested, WCF Trace Logging is your friend to solve 504 errors.
Hopefully this will help someone. I had a WCF rest service returning JSON and fiddler was giving me a 504, ReadResponse() failed: The server did not return a response for this request.
My issue was that I was returning a model like this:
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 };
}
}
and wcf doesn't seem understand how to encode an object. The object I was returning was totally fine just strings and ints. I had to change the response to this for it to work:
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 };
}
}
Had the same problem and senario as odyth above. In my case it was DateTime
attribute how was NULL
in the respons class, how caused the 504 response by Fiddler. No problems with NULL
string attributes.
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; }
}
If it's any help to anyone, I ran into this trying to return a list of Entity Framework 4 `EntityObject' from Web Api. To fix it, I just made it do an explicit selection, since EntityObject doesn't like to be serialized.
return Request.CreateResponse(HttpStatusCode.OK, people.Select(p => new {
p.Id,
p.Name,
p.CreateDate
}));
精彩评论