Link to home
Start Free TrialLog in
Avatar of Vas Chintpal
Vas Chintpal

asked on

WCF error: The remote server returned an error: (400) Bad Request

I am having trouble while sending the request to a rest service. The service works fine on my desktop, but getting the following error when i host on the IIS.

The remote server returned an error: (400) Bad Request.

After some analysis i noticed that the error i am getting is with the POST. All Get methods are working fine. I am trying to send a JSON string to create a record.

Here is my source code:

ServiceContract

namespace WcfRestService
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IOrderService" in both code and config file together.
    [ServiceContract]
    public interface IOrderService
    {
        [OperationContract]
        [WebInvoke(UriTemplate = "/PlaceOrder",
            RequestFormat = WebMessageFormat.Json,
            ResponseFormat = WebMessageFormat.Json, Method = "POST")]
        bool PlaceOrder(OrderContract order);

        [OperationContract]
        [WebGet(UriTemplate = "/GetOrderDetails/{OrderID}",
            RequestFormat = WebMessageFormat.Json,
            ResponseFormat = WebMessageFormat.Json)]
        OrderContract GetOrderDetails(string OrderID);

        [OperationContract]
        [WebGet(UriTemplate = "/GetOrderTotal/{OrderID}",
                ResponseFormat = WebMessageFormat.Json)]
        string GetOrderTotal(string OrderID);
    }
}

Open in new window


Service


namespace WcfRestService
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "OrderService" in code, svc and config file together.
    // NOTE: In order to launch WCF Test Client for testing this service, please select OrderService.svc or OrderService.svc.cs at the Solution Explorer and start debugging.
    public class OrderService : IOrderService
    {
        string XmlPath = "C:\\Test\\Wcf\\Orders.xml";
        public bool PlaceOrder(OrderContract order)
        {
            try
            {
                XDocument doc = XDocument.Load(XmlPath);

                doc.Element("DocumentElement").Add(
                        new XElement("Products",
                        new XElement("OrderID", order.OrderID),
                        new XElement("OrderDate", order.OrderDate),
                        new XElement("ShippedDate", order.ShippedDate),
                        new XElement("ShipCountry", order.ShipCountry),
                        new XElement("OrderTotal", order.OrderTotal)));

                doc.Save(XmlPath);
            }
            catch (Exception ex)
            {
                throw new FaultException<string>
                        (ex.Message);
            }
            return true;
        }

        public string GetOrderTotal(string OrderID)
        {
            string orderTotal = string.Empty;

            try
            {
                XDocument doc = XDocument.Load(XmlPath);

                orderTotal =
                (from result in doc.Descendants(XmlPath)
                .Descendants("Orders")
                 where result.Element("OrderID").Value == OrderID.ToString()
                 select result.Element("OrderTotal").Value)
                .FirstOrDefault<string>();

            }
            catch (Exception ex)
            {
                throw new FaultException<string>
                        (ex.Message);
            }
            return orderTotal;
        }

        public OrderContract GetOrderDetails(string OrderID)
        {
            OrderContract order = new OrderContract();

            try
            {
                XDocument doc = XDocument.Load(XmlPath);

                IEnumerable <XElement> orders =
                    (from result in doc.Descendants("DocumentElement")
                        .Descendants("Orders")
                     where result.Element("OrderID").Value == OrderID.ToString()
                     select result);

                order.OrderID = orders.ElementAt(0)
                                            .Element("OrderID").Value;
                order.OrderDate = orders.ElementAt(0)
                                            .Element("OrderDate").Value;
                order.ShippedDate = orders.ElementAt(0)
                                            .Element("ShippedDate").Value;
                order.ShipCountry = orders.ElementAt(0)
                                            .Element("ShipCountry").Value;
                order.OrderTotal = orders.ElementAt(0)
                                            .Element("OrderTotal").Value;
            }
            catch (Exception ex)
            {
                throw new FaultException<string>
                        (ex.Message);
            }
            return order;
        }

    }
}

Open in new window


Web.config


<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <!--
    For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367.

    The following attributes can be set on the <httpRuntime> tag.
      <system.Web>
        <httpRuntime targetFramework="4.6" />
      </system.Web>
  -->
  <system.web>
    <compilation targetFramework="4.6" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <system.serviceModel>
	
	<bindings>
      <webHttpBinding>
        <binding name="webBinding" maxReceivedMessageSize="5000000">
        </binding>
      </webHttpBinding>
    </bindings>
	
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
    <services>
      <service behaviorConfiguration="Default" name="WcfRestService.OrderService">
        <endpoint address="" behaviorConfiguration="webBehavior" binding="webHttpBinding" bindingConfiguration="webBinding" contract="WcfRestService.IOrderService" />
        <endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="webBehavior">
          <webHttp helpEnabled="true" />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="Default">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true" />
  </system.webServer>
</configuration>

Open in new window


Client


static void Main(string[] args)
        {
            //GetOrderDetails("10248");
            //GetOrderTotal("10250");
            PlaceOrder();
            Console.ReadKey(true);
        }


private static void PlaceOrder()
        {
            OrderContract order = new OrderContract
            {
                OrderID = "10556",
                OrderDate = DateTime.Now.ToString(),
                ShippedDate = DateTime.Now.AddDays(10).ToString(),
                ShipCountry = "India",
                OrderTotal = "782"
            };

            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(OrderContract));
            MemoryStream mem = new MemoryStream();
            ser.WriteObject(mem, order);
            string data = Encoding.UTF8.GetString(mem.ToArray(), 0, (int)mem.Length);
            WebClient webClient = new WebClient();
            webClient.Headers["Content-type"] = "application/json";
            webClient.Encoding = Encoding.UTF8;
            //webClient.UploadString("http://localhost:59082/OrderService.svc/PlaceOrder", "POST", data);
            webClient.UploadString("http://myserver.com/WcfRestService/OrderService.svc/PlaceOrder", "POST", data);


            Console.WriteLine("Order placed successfully...");
        }

Open in new window


As i mentioned earlier, all methods are working fine on my desktop. But PlaceOrder() method throwing "Bad request error" because its using POST with JSON.  Any help would appreciated.
ASKER CERTIFIED SOLUTION
Avatar of Vas Chintpal
Vas Chintpal

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial