Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF Restful returning HttpResponseMessage wants to negotiate when setting content

I have a WCF Restful service and I would like the methods to return HttpResponseMessage because it seems structured rather than just returning the data or the exception or whatever else might make its way there.

I am assuming this is a correct, if not let me know, but my problem is what happens when I try to set HttpResponseMessage.Content. When I do this, the client in which I made the RESTful call request authentication.

Here is my code:

In the interface:

[WebGet(UriTemplate = "/GetDetailsForName?name={name}"
                    , ResponseFormat = WebMessageFormat.Json)]
HttpResponseMessage GetDetailsForName(string name);

In the class:

public HttpResponseMessage GetDetailsForName(string name)
{
   HttpResponseMessage hrm = new HttpResponseMessage(HttpStatusCode.OK)
       {
       //If I leave this line out, I get the response, albeit empty  
       Content = new StringContent("Hi") 
       };

   return hrm;
}

I wanted to try to use Request.CreateResponse but I can't seem to get to Request from my WCF Restful method. OperationContext.Current.RequestContext does not have CreateResponse.

Any pointers?

like image 296
Matt Avatar asked Sep 15 '15 21:09

Matt


2 Answers

I had a similar error, but not quite the same. I was trying to serialize a plain object and was getting an net::ERR_Conection_Reset message. The wcf method executed 7 times and never threw an exception.

I discovered I had to annotate the class I was returning so that my JSON serializer would understand how to serialize the class. Here is my wcf method:

[OperationContract]
[WebGet(
    UriTemplate = "timeexpensemap", 
    ResponseFormat = WebMessageFormat.Json)]
    public TimeexpenseMap timeexpensemap() {
        string sql = "select * from blah"
        DbDataReader reader = this.GetReader(sql);
        TimeexpenseMap tem = null;
        if (reader.Read()) {
            tem = new TimeexpenseMap();
            // Set properties on tem object here
        }
        return tem;
    }

My original class which failed to serialize had no annotations:

public class TimeexpenseMap {
    public long? clientid { get; set; }
    public int? expenses { get; set; }
}

The annotated class serialized without issues:

[DataContract]
public class TimeexpenseMap {
    [DataMember]
    public long? clientid { get; set; }
    [DataMember]
    public int? expenses { get; set; }
}
like image 65
birwin Avatar answered Nov 13 '22 00:11

birwin


Unfortunately this will not work. The demonstrated code says:

Construct an HttpResponseMessage object, serialize it with a JSON serializer and pass the result over the wire.

The problem is HttpResponseMessage is disposable and not meant to be serialized, while StringContent cannot be serialized at all.

As to why you are redirected to an authentication form - the service throws an exception when it cannot serialize StringContent and returns a 400 HTTP status code which gets interpreted as an authentication issue.

like image 28
Roman Pletnev Avatar answered Nov 12 '22 22:11

Roman Pletnev