Kirsty White
Kirsty White

Reputation: 1220

"404" for PUT method to WCF web service?

I have a PUT request which is returning a 404 error from my client, the code looks like this:

    {
        string uriupdatestudent = string.Format("http://localhost:8000/Service/Student/{0}/{1}/{2}", textBox16.Text, textBox17.Text, textBox18.Text);
        byte[] arr = Encoding.UTF8.GetBytes(uriupdatestudent);
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uriupdatestudent);
        req.Method = "PUT";
        req.ContentType = "application/xml";
        req.ContentLength = arr.Length;
        using (Stream reqStrm = req.GetRequestStream())
        {
            reqStrm.Write(arr, 0, arr.Length);
            reqStrm.Close();
        }
        using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse())
        {
            MessageBox.Show(resp.StatusDescription);
            resp.Close();
        }
    }

The OperationContract and Service looks like this:

    [OperationContract]
    [WebInvoke(Method = "PUT", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, UriTemplate = "/Student")]
    void UpdateStudent(Student student);

    public void UpdateStudent(Student student) 
    {
        var findStudent = students.Where(s => s.StudentID == student.StudentID).FirstOrDefault();

        if (findStudent != null)
        {
            findStudent.FirstName = student.FirstName;
            findStudent.LastName = student.LastName;
        }

    }
[DataContract(Name="Student")]
public class Student
{
    [DataMember(Name = "StudentID")]
    public string StudentID { get; set; }
    [DataMember(Name = "FirstName")]
    public string FirstName { get; set; }
    [DataMember(Name = "LastName")]
    public string LastName { get; set; }
    [DataMember(Name = "TimeAdded")]
    public DateTime TimeAdded;
    public string TimeAddedString

Upvotes: 2

Views: 1719

Answers (2)

Kirsty White
Kirsty White

Reputation: 1220

So in order to answer my question I had to do two things:

I had to change my operation contract so that it can take the input string studentID, then I could delcare the student collection.

    [OperationContract]
    [WebInvoke(Method = "PUT", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, UriTemplate = "/Student/{studentID}")]
    void UpdateStudent(string studentID, Student student);

    public void UpdateStudent(string studentID, Student student) 
    {
        var findStudent = students.Where(s => s.StudentID == studentID).FirstOrDefault();

        if (findStudent != null)
        {
            findStudent.FirstName = student.FirstName;
            findStudent.LastName = student.LastName;
        }

    }

Then from the client side I had to go back to using the string builder method in order to send the collection as xml.

    {
        string uriupdatestudent = string.Format("http://localhost:8000/Service/Student/{0}", textBox16.Text);
        StringBuilder sb = new StringBuilder();
        sb.Append("<Student>");
        sb.AppendLine("<FirstName>" + this.textBox17.Text + "</FirstName>");
        sb.AppendLine("<LastName>" + this.textBox18.Text + "</LastName>");
        sb.AppendLine("</Student>");
        string NewStudent = sb.ToString();
        byte[] arr = Encoding.UTF8.GetBytes(NewStudent);
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uriupdatestudent);
        req.Method = "PUT";
        req.ContentType = "application/xml";
        req.ContentLength = arr.Length;
        Stream reqStrm = req.GetRequestStream();
        reqStrm.Write(arr, 0, arr.Length);
        reqStrm.Close();
        HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
        MessageBox.Show(resp.StatusDescription);
        reqStrm.Close();
        resp.Close();
    }

There was a person who had put an answer prior to this and he was correct so I would like to thank you and your answer would have been accepted! (if it wasnt deleted)

Upvotes: 1

KodeKreachor
KodeKreachor

Reputation: 8882

Based on the uri you're calling, is your service able to resolve it given the extra routing information being passed to it?

You could try updating the service method signature to accept and map the ncoming uri parameters:

[WebInvoke(Method = "PUT", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, UriTemplate = "/Student/{fname}/{lname}/{id}")]
    void UpdateStudent(string fname, string lname, string id);

Otherwise you could just serialize your Student object on the client into XML and send it along with the request inside the body of the request. In this case you would simply make a request to: http://localhost:8000/Service/Student and WCF would deserialize the incoming request's body to a corresponding Student object.

Upvotes: 0

Related Questions