WCF - (504) The server did not return a response for this request
Asked Answered
P

7

22

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.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;
    }
}

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.

Posh answered 28/1, 2010 at 18:59 Comment(1)
any final solution with full source code sample working about it ?Barouche
P
5

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.

Posh answered 29/1, 2010 at 16:27 Comment(0)
B
31

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.

Beaverbrook answered 28/1, 2010 at 19:22 Comment(6)
I am seeing some weird behavior on the Entity Framework not loading the Context requested. <grrrr/>Posh
This helped me identify and address my problem immediately! I actually didn't even know this was specifically a WCF issue. Thanks!Wicket
Your solution solved my issue after struggling with it for a few days!!! The problem with WCF exceptions is that you can never know what's the real exception, you only get that nasty 'NotFound' bastard.Jephum
What if WCF is a Lightswitch app? How to enable tracing?Premer
Thank you for this solution! Hit the nail on the head with regards to identifying the issue.Evanesce
Found the issue was that i hadn't add a new return object as a 'ServiceKnownType' - only found this due to tracingAllout
W
8

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.

Wrung answered 14/7, 2011 at 16:2 Comment(1)
+1 for the configuring tracing in WCF link. It helped me find the issue. For me it was a class not marked with DataContract attribute.Idol
P
5

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.

Posh answered 29/1, 2010 at 16:27 Comment(0)
T
4

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.

Thorrlow answered 24/10, 2011 at 18:38 Comment(0)
L
4

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 };
    }
}
Lette answered 20/7, 2012 at 8:25 Comment(0)
S
2

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; }
}
Sensualism answered 22/2, 2016 at 10:17 Comment(0)
C
0

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
}));
Conceptualism answered 30/9, 2015 at 15:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.