Пример #1
0
        private HttpWebRequest createRequest(Uri location, bool forBundle)
        {
            Uri endpoint = location;

            if (UseFormatParam)
            {
                var rl = new ResourceLocation(location);
                rl.SetParam(Util.RESTPARAM_FORMAT, ContentType.BuildFormatParam(PreferredFormat));
                endpoint = rl.ToUri();
            }

            var req   = (HttpWebRequest)HttpWebRequest.Create(endpoint);
            var agent = "FhirClient for FHIR " + Model.ModelInfo.Version;

            req.Method = "GET";

#if NETFX_CORE
            req.Headers[HttpRequestHeader.UserAgent] = agent;
#else
            req.UserAgent = agent;
#endif

            if (!UseFormatParam)
            {
                req.Accept = ContentType.BuildContentType(PreferredFormat, forBundle);
            }

            return(req);
        }
Пример #2
0
        /// <summary>
        /// Send a Bundle to a path on the server
        /// </summary>
        /// <param name="bundle">The contents of the Bundle to be sent</param>
        /// <param name="path">A path on the server to send the Bundle to</param>
        /// <returns>True if the bundle was successfully delivered, false otherwise</returns>
        /// <remarks>This method differs from Batch, in that it can be used to deliver a Bundle
        /// at the endpoint for messages, documents or binaries, instead of the batched update
        /// REST endpoint.</remarks>
        public bool DeliverBundle(Bundle bundle, string path)
        {
            if (Endpoint == null)
            {
                throw new InvalidOperationException("Endpoint must be provided using either the Endpoint property or the FhirClient constructor");
            }

            byte[] data;
            string contentType = ContentType.BuildContentType(PreferredFormat, false);

            if (PreferredFormat == ContentType.ResourceFormat.Json)
            {
                data = FhirSerializer.SerializeBundleToJsonBytes(bundle);
            }
            else if (PreferredFormat == ContentType.ResourceFormat.Xml)
            {
                data = FhirSerializer.SerializeBundleToXmlBytes(bundle);
            }
            else
            {
                throw new ArgumentException("Cannot encode a batch into format " + PreferredFormat.ToString());
            }

            var req = createRequest(Endpoint, true);

            req.Method      = "POST";
            req.ContentType = contentType;
            prepareRequest(req, data);

            return(doRequest(req, HttpStatusCode.OK, () => true));
        }
Пример #3
0
        /// <summary>
        /// Update (or create) a resource at a given endpoint
        /// </summary>
        /// <param name="entry">A ResourceEntry containing the resource to update</param>
        /// <param name="versionAware">Whether or not version aware update is used.</param>
        /// <typeparam name="TResource">The type of resource that is being updated</typeparam>
        /// <returns>The resource as updated on the server. Throws an exception when the update failed,
        /// in particular may throw an exception when the server returns a 409 when a conflict is detected
        /// while using version-aware updates or 412 if the server requires version-aware updates.</returns>
        public ResourceEntry <TResource> Update <TResource>(ResourceEntry <TResource> entry, bool versionAware = false)
            where TResource : Resource, new()
        {
            if (entry == null)
            {
                throw new ArgumentNullException("entry");
            }
            if (entry.Resource == null)
            {
                throw new ArgumentException("Entry does not contain a Resource to update", "entry");
            }
            if (entry.Id == null)
            {
                throw new ArgumentException("Entry needs a non-null entry.id to send the update to", "entry");
            }
            if (versionAware && entry.SelfLink == null)
            {
                throw new ArgumentException("When requesting version-aware updates, Entry.SelfLink may not be null.", "entry");
            }

            string contentType = null;

            byte[] data = null;

            if (entry.Resource is Binary)
            {
                var bin = entry.Resource as Binary;
                data        = bin.Content;
                contentType = bin.ContentType;
            }
            else
            {
                data = PreferredFormat == ContentType.ResourceFormat.Xml ?
                       FhirSerializer.SerializeResourceToXmlBytes(entry.Resource) :
                       FhirSerializer.SerializeResourceToJsonBytes(entry.Resource);
                contentType = ContentType.BuildContentType(PreferredFormat, false);
            }

            var req = createRequest(entry.Id, false);

            req.Method      = "PUT";
            req.ContentType = contentType;
            prepareRequest(req, data, entry.Tags);

            // If a version id is given, post the data to a version-specific url
            if (versionAware)
            {
                req.Headers[HttpRequestHeader.ContentLocation] = entry.SelfLink.ToString();
            }

            return(doRequest(req, new HttpStatusCode[] { HttpStatusCode.Created, HttpStatusCode.OK },
                             () => resourceEntryFromResponse <TResource>()));
        }
Пример #4
0
        /// <summary>
        /// Validates whether the contents of the resource would be acceptable as an update
        /// </summary>
        /// <param name="entry">The entry containing the updated Resource to validate</param>
        /// <returns>null if validation succeeded, otherwise returns OperationOutcome detailing the validation errors.
        /// If the server returned an error, but did not return an OperationOutcome resource, an exception will be
        /// thrown.</returns>
        public OperationOutcome Validate <TResource>(ResourceEntry <TResource> entry) where TResource : Resource, new()
        {
            if (entry == null)
            {
                throw new ArgumentNullException("entry");
            }
            if (entry.Resource == null)
            {
                throw new ArgumentException("Entry does not contain a Resource to validate", "entry");
            }
            if (entry.Id == null)
            {
                throw new ArgumentException("Entry needs a non-null entry.id to use for validation", "entry");
            }

            string contentType = ContentType.BuildContentType(PreferredFormat, false);

            byte[] data = PreferredFormat == ContentType.ResourceFormat.Xml ?
                          FhirSerializer.SerializeResourceToXmlBytes(entry.Resource) :
                          FhirSerializer.SerializeResourceToJsonBytes(entry.Resource);

            var rl = new ResourceLocation(entry.Id);

            rl.Operation = ResourceLocation.RESTOPER_VALIDATE;
            var req = createRequest(rl.ToUri(), false);

            req.Method      = "POST";
            req.ContentType = contentType;
            prepareRequest(req, data, entry.Tags);

            try
            {
                doRequest(req, HttpStatusCode.OK, () => true);
                return(null);
            }
            catch (FhirOperationException foe)
            {
                if (foe.Outcome != null)
                {
                    return(foe.Outcome);
                }
                else
                {
                    throw foe;
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Create a resource
        /// </summary>
        /// <param name="collectionEndpoint">Endpoint where the resource is sent to be created</param>
        /// <param name="resource">The resource instance to create</param>
        /// <param name="tags">Optional. List of Tags to add to the created instance.</param>
        /// <returns>The resource as created on the server, or an exception if the create failed.</returns>
        /// <typeparam name="TResource">The type of resource to create</typeparam>
        /// <remarks><para>The returned resource need not be the same as the resources passed as a parameter,
        /// since the server may have updated or changed part of the data because of business rules.</para>
        /// </remarks>
        public ResourceEntry <TResource> Create <TResource>(Uri collectionEndpoint, TResource resource, IEnumerable <Tag> tags = null) where TResource : Resource, new()
        {
            if (collectionEndpoint == null)
            {
                throw new ArgumentNullException("collectionEndpoint");
            }
            if (resource == null)
            {
                throw new ArgumentNullException("resource");
            }

            string contentType = null;

            byte[] data = null;

            if (resource is Binary)
            {
                var bin = resource as Binary;
                data        = bin.Content;
                contentType = bin.ContentType;
            }
            else
            {
                data = PreferredFormat == ContentType.ResourceFormat.Xml ?
                       FhirSerializer.SerializeResourceToXmlBytes(resource) :
                       FhirSerializer.SerializeResourceToJsonBytes(resource);
                contentType = ContentType.BuildContentType(PreferredFormat, false);
            }

            var req = createRequest(collectionEndpoint, false);

            req.Method      = "POST";
            req.ContentType = contentType;
            prepareRequest(req, data, tags);

            return(doRequest(req, HttpStatusCode.Created, () => resourceEntryFromResponse <TResource>()));
        }