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.
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:
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.
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);
}
}
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;
}
}
}
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>
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...");
}
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.