Exemplo n.º 1
0
        /// <summary>
        /// Constructs an OData request body using the given settings
        /// </summary>
        /// <param name="contentType">The content type of the body</param>
        /// <param name="uri">The request uri</param>
        /// <param name="rootElement">The root payload element</param>
        /// <returns>An OData request body</returns>
        public ODataPayloadBody BuildBody(string contentType, ODataUri uri, ODataPayloadElement rootElement)
        {
            ExceptionUtilities.CheckArgumentNotNull(contentType, "contentType");
            ExceptionUtilities.CheckArgumentNotNull(rootElement, "rootElement");
            ExceptionUtilities.CheckAllRequiredDependencies(this);

            string charset = HttpUtilities.GetContentTypeCharsetOrNull(contentType);

            byte[] serializedBody      = null;
            var    batchRequestPayload = rootElement as BatchRequestPayload;

            if (batchRequestPayload != null)
            {
                string boundary;
                ExceptionUtilities.Assert(HttpUtilities.TryGetContentTypeParameter(contentType, HttpHeaders.Boundary, out boundary), "Could not find boundary in content type for batch payload. Content type was: '{0}'", contentType);
                serializedBody = this.BatchSerializer.SerializeBatchPayload(batchRequestPayload, boundary, charset);
            }
            else
            {
                IProtocolFormatStrategy strategy = this.FormatSelector.GetStrategy(contentType, uri);
                ExceptionUtilities.CheckObjectNotNull(strategy, "Strategy selector did not return a strategy for content type '{0}'", contentType);

                IPayloadSerializer serializer = strategy.GetSerializer();
                ExceptionUtilities.CheckObjectNotNull(serializer, "Strategy returned a null serializer");

                serializedBody = serializer.SerializeToBinary(rootElement, charset);
            }

            return(new ODataPayloadBody(serializedBody, rootElement));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Generates the raw test message with mixed encodings defined by the test case, as well as the expected ODataPayloadElement.
        /// </summary>
        /// <param name="testCase">The test case defining the structure and encodings of the batch payload.</param>
        /// <param name="payload">The payload to use for all generated batch operations.</param>
        /// <param name="payloadUri">The URI to use for all generated batch operations.</param>
        /// <param name="isRequest">If true, generates a batch request, otherwise a batch response.</param>
        /// <returns>The test descriptor for this test case/configuration.</returns>
        private BatchReaderMixedEncodingTestDescriptor CreateTestDescriptor(BatchReaderMixedEncodingTestCase testCase, ODataPayloadElement payload, ODataUri payloadUri, bool isRequest)
        {
            ExceptionUtilities.Assert(testCase.BatchEncoding != null, "Batch encoding has not been specified.");

            string batchBoundary    = "batch_" + Guid.NewGuid().ToString();
            string payloadUriString = this.UriConverter.ConvertToString(payloadUri);

            var batchPayload = isRequest ? (ODataPayloadElement) new BatchRequestPayload() : (ODataPayloadElement) new BatchResponsePayload();

            batchPayload.AddAnnotation(new BatchBoundaryAnnotation(batchBoundary));

            var rawMessage = new List <byte>();

            // TODO: Batch reader does not support multi codepoint encodings
            Encoding unsupportedEncoding = AsUnsupportedEncoding(testCase.BatchEncoding);

            foreach (var changeset in testCase.Changesets)
            {
                string   changesetBoundary = "change_" + Guid.NewGuid().ToString();
                Encoding changesetEncoding = changeset.ChangesetEncoding ?? testCase.BatchEncoding;

                // TODO: Batch reader does not support multi codepoint encodings
                unsupportedEncoding = unsupportedEncoding ?? AsUnsupportedEncoding(changesetEncoding);

                string changesetContentType = HttpUtilities.BuildContentType(
                    MimeTypes.MultipartMixed,
                    changeset.ChangesetEncoding == null ? string.Empty : changeset.ChangesetEncoding.WebName,
                    changesetBoundary);

                rawMessage.AddRange(
                    WriteMessagePart(
                        testCase.BatchEncoding,
                        (writer) =>
                {
                    writer.Write("--");
                    writer.WriteLine(batchBoundary);
                    writer.WriteLine(HttpHeaders.ContentType + ": " + changesetContentType);
                    writer.WriteLine();
                }));

                var mimeParts = new List <IMimePart>();
                int contentId = 0;

                foreach (var operation in changeset.Operations)
                {
                    ExceptionUtilities.Assert(operation.PayloadFormat == ODataFormat.Atom || operation.PayloadFormat == ODataFormat.Json, "Payload format must be ATOM or JSON.");
                    string   formatType         = MimeTypes.ApplicationAtomXml + ";type=entry";
                    Encoding payloadEncoding    = operation.OperationEncoding ?? changesetEncoding;
                    string   payloadContentType = HttpUtilities.BuildContentType(
                        formatType,
                        operation.OperationEncoding == null ? string.Empty : operation.OperationEncoding.WebName,
                        string.Empty);

                    string httpStatus = isRequest ? "POST " + payloadUriString + " HTTP/1.1" : "HTTP/1.1 201 Created";

                    rawMessage.AddRange(
                        WriteMessagePart(
                            changesetEncoding,
                            (writer) =>
                    {
                        writer.WriteLine();
                        writer.Write("--");
                        writer.WriteLine(changesetBoundary);
                        writer.WriteLine(HttpHeaders.ContentType + ": application/http");
                        writer.WriteLine(HttpHeaders.ContentTransferEncoding + ": binary");
                        writer.WriteLine(HttpHeaders.ContentId + ": " + (++contentId).ToString());
                        writer.WriteLine();
                        writer.WriteLine(httpStatus);
                        writer.WriteLine(HttpHeaders.ContentType + ": " + payloadContentType);
                        writer.WriteLine();
                    }));

                    IPayloadSerializer payloadSerializer =
                        operation.PayloadFormat == ODataFormat.Atom ?
                        (IPayloadSerializer) new XmlPayloadSerializer(this.PayloadElementToXmlConverter) :
                        (IPayloadSerializer) new JsonPayloadSerializer(this.PayloadElementToJsonConverter.ConvertToJson);

                    byte[] payloadBytes = payloadSerializer.SerializeToBinary(payload, payloadEncoding.WebName);
                    rawMessage.AddRange(payloadBytes.Skip(payloadEncoding.GetPreamble().Length));

                    if (isRequest)
                    {
                        var request = this.RequestManager.BuildRequest(payloadUri, HttpVerb.Post, new Dictionary <string, string> {
                            { HttpHeaders.ContentType, payloadContentType }
                        });
                        request.Body = new ODataPayloadBody(payloadBytes, payload);
                        mimeParts.Add(request);
                    }
                    else
                    {
                        var httpResponseData = new HttpResponseData {
                            StatusCode = HttpStatusCode.Created,
                        };
                        httpResponseData.Headers.Add(HttpHeaders.ContentType, payloadContentType);
                        var response = new ODataResponse(httpResponseData)
                        {
                            Body = payloadBytes, RootElement = payload
                        };
                        mimeParts.Add(response);
                    }
                }

                rawMessage.AddRange(
                    WriteMessagePart(
                        changesetEncoding,
                        (writer) =>
                {
                    writer.WriteLine();
                    writer.Write("--");
                    writer.Write(changesetBoundary);
                    writer.WriteLine("--");
                }));

                if (isRequest)
                {
                    ((BatchRequestPayload)batchPayload).Add(BatchPayloadBuilder.RequestChangeset(changesetBoundary, changesetEncoding.WebName, mimeParts.ToArray()));
                }
                else
                {
                    ((BatchResponsePayload)batchPayload).Add(BatchPayloadBuilder.ResponseChangeset(changesetBoundary, changesetEncoding.WebName, mimeParts.ToArray()));
                }
            }

            rawMessage.AddRange(
                WriteMessagePart(
                    testCase.BatchEncoding,
                    (writer) =>
            {
                writer.WriteLine();
                writer.Write("--");
                writer.Write(batchBoundary);
                writer.WriteLine("--");
            }));

            return(new BatchReaderMixedEncodingTestDescriptor(this.PayloadReaderSettings)
            {
                BatchContentTypeHeader = HttpUtilities.BuildContentType(MimeTypes.MultipartMixed, testCase.BatchEncoding.WebName, batchBoundary),
                RawMessage = rawMessage.ToArray(),
                PayloadElement = batchPayload,
                ExpectedException = unsupportedEncoding == null ? null : ODataExpectedExceptions.ODataException("ODataBatchReaderStream_MultiByteEncodingsNotSupported", unsupportedEncoding.WebName)
            });
        }
Exemplo n.º 3
0
 /// <summary>
 /// Serializes the given payload element into a form ready to be sent over HTTP using the default encoding.
 /// </summary>
 /// <param name="serializer">The serializer to extend</param>
 /// <param name="rootElement">The root payload element to serialize</param>
 /// <returns>The binary representation of the payload for this format, ready to be sent over HTTP</returns>
 public static byte[] SerializeToBinary(this IPayloadSerializer serializer, ODataPayloadElement rootElement)
 {
     ExceptionUtilities.CheckArgumentNotNull(serializer, "serializer");
     return(serializer.SerializeToBinary(rootElement, null));
 }