Bitbored
Bitbored

Reputation: 477

Posting an object via REST XML in C# WCF returns 400 Bad request

I'm trying to Post an object to a WCF Service using REST with XML, but I keep getting the "error: (400) Bad Request" thrown. I know there are a lot of posts on this site concerning the same problem, but I can't seem to find a solution.

My WCF service code:

IPhoneBookService.cs:

    [OperationContract]
    [WebInvoke( UriTemplate = "/addentry/", 
                Method = "POST",
                BodyStyle = WebMessageBodyStyle.Bare, 
                RequestFormat = WebMessageFormat.Xml, 
                ResponseFormat = WebMessageFormat.Xml)]
    void AddEntry(Contact contact);

PhoneBookService.cs:

    DataPhonebookDataContext dc = new DataPhonebookDataContext();
    public void AddEntry(Contact contact)
    {
        if (contact == null)
        {
            throw new ArgumentNullException("contact");
        }
        dc.Contacts.InsertOnSubmit(contact);

        try
        {
            dc.SubmitChanges();
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }           

    }

Client (ASP page) code:

    private WebClient client = new WebClient();
    HttpWebRequest req;
    protected void Page_Load(object sender, EventArgs e)
    {
        req = (HttpWebRequest)WebRequest.Create("http://localhost:1853/PhoneBookService.svc/addentry/");
        req.Method = "POST";
        req.ContentType = "application/xml; charset=utf-8";
        req.Timeout = 30000;
        client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
    }
    protected void btnAddEntry_Click(object sender, EventArgs e)
    {
        var contact = new Contact(); //Contact class from WCF service reference
        contact.LastName = txtLastName.Text;
        contact.FirstName = txtFirstName.Text;
        contact.PhoneNumber = txtPhone.Text;

        //Code using Webclient
        //client.UploadData(new Uri("http://localhost:1853/PhoneBookService.svc/addentry/"), TToByteArray<Contact>(contact));

        //Code using webrequest
        byte[] buffer = TToByteArray<Contact>(contact);
        req.ContentLength = buffer.Length;
        Stream PostData = req.GetRequestStream();
        PostData.Write(buffer, 0, buffer.Length);
        PostData.Close();

        HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
        Encoding enc = System.Text.Encoding.GetEncoding(1252);
        StreamReader loResponseStream =
        new StreamReader(resp.GetResponseStream(), enc);
        string response = loResponseStream.ReadToEnd();
    }
    private byte[] TToByteArray<T>(T item)
    {
        BinaryFormatter bf = new BinaryFormatter();
        MemoryStream ms = new MemoryStream();

        if (!typeof(T).IsSerializable)
        {
            throw new ArgumentException("The type of the argument must be serializable");
        }
        bf.Serialize(ms, item);
        return ms.ToArray();
    }

The Contact class is defined in the DataContext, witch is generated by a LinqToSQL class. I edited the Contact class to be serializable.

Upvotes: 0

Views: 2446

Answers (1)

Gerald Degeneve
Gerald Degeneve

Reputation: 545

You created a web service that listens to XML post requests. This implies that the request message Format has to be XML.

Your client on the other Hand serializes the contract in binary Format. Try to use the XMLSerializer, not the BinaryFormatter.

The WebMessageBodyStyle.Bare attribute does not indicate binary data. It only indicates that the message is not wrapped in additional XML tags with meta information.

if you want to receive Binary data in your Service, you should declare the Input Parameter as Stream, then no automatic serialization is done on the Server and you receive the message exactly the way the client sent it.

Upvotes: 1

Related Questions