WCF Restful returning HttpResponseMessage wants to

2019-06-15 11:10发布

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?

3条回答
叛逆
2楼-- · 2019-06-15 11:27

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.

查看更多
地球回转人心会变
3楼-- · 2019-06-15 11:38

If I am calling, for example a public string getDetails(int ID) and an error is thrown, this works ...

catch(Exception ex)
 {
 OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
 response.StatusCode = System.Net.HttpStatusCode.OK; //this returns whatever Status Code you want to set here
 response.StatusDescription = ex.Message.ToString(); //this can be accessed in the client
 return "returnValue:-998,message:\"Database error retrieving customer details\""; //this is returned in the body and can be read from the stream
 }
查看更多
放我归山
4楼-- · 2019-06-15 11:40

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; }
}
查看更多
登录 后发表回答