public TRS SendRequest <TRS>(ProtoRequest protoRequest) { if (protoRequest == null) { throw new ArgumentNullException("protoRequest"); } var requestPayload = protoRequest.Request == null ? null : SerializeToJson(protoRequest.Request); var requestHeaders = protoRequest.RequestHeaders ?? new Dictionary <string, string>(); string existingAcceptTypes; requestHeaders.TryGetValue("accept", out existingAcceptTypes); requestHeaders["accept"] = RestfulServiceConstants.ProtoContentType + (string.IsNullOrEmpty(existingAcceptTypes) ? string.Empty : "," + existingAcceptTypes); requestHeaders["content-type"] = RestfulServiceConstants.JsonContentType; byte[] response; WebHeaderCollection responseHeaders; using (var client = new ExtendedWebClient(protoRequest.Timeout)) { foreach (var requestHeader in requestHeaders) { client.Headers.Add(requestHeader.Key, requestHeader.Value); } var method = protoRequest.Method ?? "GET"; if (string.Equals(method, "GET", StringComparison.OrdinalIgnoreCase)) { response = client.DownloadData(protoRequest.ServiceUri); } else { byte[] requestPayloadBytes; if (string.IsNullOrEmpty(requestPayload)) { requestPayloadBytes = new byte[0]; } else { requestPayloadBytes = Encoding.UTF8.GetBytes(requestPayload); } response = client.UploadData(protoRequest.ServiceUri, method, requestPayloadBytes); } responseHeaders = client.ResponseHeaders; } ResponseHeaders = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); foreach (var responseHeaderKey in responseHeaders.AllKeys) { ResponseHeaders.Add(responseHeaderKey, responseHeaders.Get(responseHeaderKey)); } var responseContentType = ResponseHeaders["content-type"]; if (responseContentType.Equals(RestfulServiceConstants.ProtoContentType, StringComparison.OrdinalIgnoreCase)) { string modelKey; if (!ResponseHeaders.TryGetValue(RestfulServiceConstants.RqModelTypeHeaderKey, out modelKey)) { throw new InvalidDataException("The server sent a protoBuf response with no model key in the header, the service on the server side is behaving in an unexpected manner, contact the service administrator."); } var metaDataKey = GetMetaDataKey(protoRequest, modelKey); var metaData = MetaDatas.GetOrAdd(metaDataKey, s => GetMetaData(protoRequest, modelKey)); var serializer = ObjectBuilder.GetSerializer(); try { return(serializer.Deserialize <TRS>(response, metaData, ModeType.WebAPI)); } catch { ClearMetaData(protoRequest); throw; } } if (IsContentTypeSupported(responseContentType)) //deliberately put before json, in case custom json serialization is required. { return(DeserializeData <TRS>(responseContentType, response)); } if (responseContentType.Equals(RestfulServiceConstants.JsonContentType, StringComparison.OrdinalIgnoreCase)) { return(JsonSerializer.FromJson <TRS>(response)); } throw new InvalidDataException(string.Format( "The response returned by the server did not contain a supported content-type header value, the returned content type was '{0}', supported types are '{1}' & {2}", responseContentType, RestfulServiceConstants.ProtoContentType, RestfulServiceConstants.JsonContentType)); }