These docs are for v20.3.44. Click to read the latest docs for v20.3.186.

Discussions

Ask a Question
Back to All

Putting Event Functions via REST

Hey Jeremy,

We have been testing this solution, but we noticed that we were not seeing any functions in Staff site under the Event when we are trying to create the event. End goal is to create events and its functions. Is there something we are missing? Are we POSTing in the wrong order? etc. Also, we'd like to share the entire project solution as well. What's the best way to get that to you?

Post from here that we are using for reference: https://developer.imis.com/discuss/5b9987be463cea00036dffe3
"Hey Jack,

Jeremy here, just wanted to give you a verbose update on your attempt to create and tie event functions to an existing event. Admittedly, it's a bit cumbersome relative to other entity updates due to the amount of structure inherent to it, but hopefully I can put you on the right path as much as possible.

For event functions in particular, we'll need to chain a few calls to iMIS to ensure we've got every bit of data filled out for the application to utilize it safely throughout the various scenarios that entity might find itself in. This involves POSTing to both the Product and Product_Function endpoints prior to PUTting to the Event endpoint. You can take advantage of of the GenericEntityData contract with iMIS for the first two calls, which I'll demonstrate below as two simple REST calls to their respective endpoints -

POST to /api/Product with a payload much like the one here. The important fields here to keep in mind would be the initial identity value (in this case, ANNCONF/DINNER, our new function tied to the Annual Conference event), as well as the _PRODUCTCODE, _PRODUCTMAJOR, and _PRODUCTMINOR fields, as varying representations of the aforementioned ID. Programatically, we'll also have to ensure ProductKey is a unique GUID.

POST to _/api/ProductFunction/[Event ID here, such as ANNCONF] with a payload much like one here. Much like before, we'll tie this to the previously made product with the ANNCONF/DINNER identity value being passed in, as well as the _PRODUCTCODE with the same value.

I've then merged a bit of the boilerplate code I mentioned prior along with some of the code you had written out utilizing our client library to create the following class that you can find here. The pertinent method begins at line 71. I've set some of the event function fields to newer values to showcase the PUT working as intended. I've neglected to add the first two POSTS as code within this class, although if you'd like me to look into some recipes or best practices when working with that kind of data, please let me know. "

Current project code:

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Asi.Soa.Membership.DataContracts;
using Newtonsoft.Json;
using Asi.Soa.Core.DataContracts;
using Asi.Soa.Events.DataContracts;

namespace Ascension.Utilities.iMIS.EventCreator
{
public static class Program
{
public static HttpClient Client;

    static Program()
    {
        // set HTTP Client's base address to target iMIS instance scheduler/service
        Client = new HttpClient
        {

            //BaseAddress = new Uri("https://testapi.imis.com/Asi.Scheduler_SDKDemo/")
            BaseAddress = new Uri("https://customer.uspta.org/asi.scheduler_imis/")

        };

        // address client's certificate and header values

        // NOTE: This causes all Server Certificates for https to be accepted without validation.
        // This is convenient during development with self-signed certificates or mismatched hostnames.
        // In production, you should use only certificates signed by a trusted CA and delete this line.              

        ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

        Client.DefaultRequestHeaders.Accept.Clear();
        Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        // POST to the iMIS token endpoint with form-encoded data set, which should be modified to
        // correspond to your iMIS instance's MANAGER/RemoteService user
        var response = Client.PostAsync("token", new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("grant_type", "password"),
            new KeyValuePair<string, string>("username", "MANAGER"),
            new KeyValuePair<string, string>("password", "!pele1958")
        })).Result;

        // deserialize incoming JSON to Token object specified below, attach token to client's authorization
        // header with the 'Bearer' prefix to being making authenticated requests to iMIS
        Token token = JsonConvert.DeserializeObject<Token>(response.Content.ReadAsStringAsync().Result);

        Client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Bearer", token.AccessToken);
    }

    /// <summary>
    /// C# class representation of iMIS Bearer Token, used to authenticate additional requests 
    /// </summary>
    internal class Token
    {
        [JsonProperty("access_token")] public string AccessToken { get; set; }

        [JsonProperty("token_type")] public string TokenType { get; set; }

        [JsonProperty("expires_in")] public int ExpiresIn { get; set; }

        [JsonProperty("userName")] public string UserName { get; set; }

        [JsonProperty(".issued")] public string Issued { get; set; }

        [JsonProperty(".expires")] public string Expires { get; set; }
    }

    /// <summary>
    /// Small example utilizing the above created and authenticated HTTP client
    /// </summary>
    /// <param name="args"></param>
    static void Main(string[] args)
    {
        MainAsync().GetAwaiter().GetResult();
    }

    static async Task MainAsync()
    {
        //TEST PUT
        //const string id = "72492";  // known party Id
        //var response = await Update(id);

        //Console.WriteLine(response.IsSuccessStatusCode
        //    ? $"Response: {response.Content.ReadAsStringAsync().Result}"
        //    : $"Response: {response.StatusCode}");
        //Console.ReadKey();

        //CREATE PRODUCT FIRST WORKS!
        const string id2 = "ANNCONF/DINNER";
        var response2 = await createProduct(id2);
        Console.WriteLine(response2.IsSuccessStatusCode
            ? $"Response: {response2.Content.ReadAsStringAsync().Result}"
            : $"Response: {response2.StatusCode}");
        Console.ReadKey();

        //Create EVENT WROKS!!!
        var responseCreate = await CreateEvent("ANNCONF");

        if (responseCreate.IsSuccessStatusCode)
        {
            //CREATE EVENT WITH FUNCTIONS
            var response = await CreateEventFunction("ANNCONF", "DINNER");
            if (response.IsSuccessStatusCode)
            {
                Console.WriteLine("Response: {0}", response.Content.ReadAsStringAsync().Result);
            }
        }



    }

    static async Task<HttpResponseMessage> Update(string id)
    {
        PersonData existingParty;
        var responseItem = await Client.GetAsync($"api/party/{id}");
        if (responseItem.IsSuccessStatusCode)
        {
            // deserialize response to DataContract
            existingParty = JsonConvert.DeserializeObject<PersonData>(await responseItem.Content.ReadAsStringAsync());
        }
        else return responseItem;

        // make minor update to the party
        existingParty.WebsiteUrl = Guid.NewGuid().ToString();

        // serialize person data
        var serializedParty = JsonConvert.SerializeObject(existingParty, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All });
        HttpContent httpContent = new StringContent(serializedParty, Encoding.UTF8, "application/json");

        var response = await Client.PutAsync($"api/party/{id}", httpContent);
        return response;
    }

    static async Task<HttpResponseMessage> createProduct(string id)
    {
        GenericEntityData product = new GenericEntityData() ;
        product.EntityTypeName = "Product";
        IdentityData function= new IdentityData();            
        function.EntityTypeName = "Product";
        function.IdentityElements = new System.Collections.ObjectModel.Collection<string>();           
        function.IdentityElements.Add("ANNCONF/DINNER");
        product.Identity = function;

        var functionCode = "ANNCONF/DINNER";
        var functionMajor = "ANNCONF";
        var functionMinor = "DINNER";
        var productKey = new Guid("9eba2370-71eb-4876-b9e2-ea7b020d6b3c");

        GenericPropertyData propertyData1 = new GenericPropertyData("PRODUCT_CODE", functionCode);
        GenericPropertyData propertyData2 = new GenericPropertyData("PRODUCT_MAJOR", functionMajor);
        GenericPropertyData propertyData3 = new GenericPropertyData("PRODUCT_MINOR", functionMinor);
        GenericPropertyData propertyData4 = new GenericPropertyData("ProductKey", productKey);
        product.Properties.Add(propertyData1);
        product.Properties.Add(propertyData2);
        product.Properties.Add(propertyData3);
        product.Properties.Add(propertyData4);

        var serializedGenericEntityData = JsonConvert.SerializeObject(product, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All });
        HttpContent httpContent = new StringContent(serializedGenericEntityData, Encoding.UTF8, "application/json");


        var response = await Client.PostAsync($"api/Product",httpContent);
        return response;

    }


    /// <summary>
    /// Async task to create event functions under a specified event
    /// </summary>
    /// <param name="eventId"></param>
    /// <param name="functionId"></param>
    /// <returns></returns>
    static async Task<HttpResponseMessage> CreateEvent(string eventId)
    {
        EventData newEvent = new EventData();

        newEvent.Name = "ANNCONF";
        newEvent.EventCode = "ANNCONF";
        newEvent.EventId = "ANNCONF";

        var serializedEventData = JsonConvert.SerializeObject(newEvent, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All });
        HttpContent httpContent = new StringContent(serializedEventData, Encoding.UTF8, "application/json");

        var responseEvent = await Client.PostAsync($"api/event",httpContent);
        if (responseEvent.IsSuccessStatusCode)
        {
            // deserialize response to DataContract
            newEvent =
                JsonConvert.DeserializeObject<EventData>(await responseEvent.Content.ReadAsStringAsync());
        }

        if (responseEvent.IsSuccessStatusCode)
        {
            return responseEvent;
        }

        return new HttpResponseMessage
        {
            StatusCode = HttpStatusCode.BadRequest
        };
    }


    /// <summary>
    /// Async task to create event functions under a specified event
    /// </summary>
    /// <param name="eventId"></param>
    /// <param name="functionId"></param>
    /// <returns></returns>
    static async Task<HttpResponseMessage> CreateEventFunction(string eventId, string functionId)
    {
        EventData existingEvent = new EventData();

        var responseEvent = await Client.GetAsync($"api/event/{eventId}");
        if (responseEvent.IsSuccessStatusCode)
        {
            // deserialize response to DataContract
            existingEvent =
                JsonConvert.DeserializeObject<EventData>(await responseEvent.Content.ReadAsStringAsync());
        }

        // create new event function and add to existing event
        EventFunctionData newEventFunction = new EventFunctionData
        {
            Name = "Welcome Dinner",
            Description = "A welcome dinner for all attendees.",
            StartDateTime = new DateTime(2019, 5, 21, 19, 0, 0),
            EndDateTime = new DateTime(2019, 5, 21, 21, 0, 0),
            RegistrationType = RegistrationTypeData.FeeRegistrationRequired,
            EventFunctionId = eventId + '/' + functionId,
            EventFunctionCode = functionId,
            Status = "A"
        };

        EventFunctionDataCollection eventFunctionDataCollection = new EventFunctionDataCollection();
        eventFunctionDataCollection.Add(newEventFunction);
        existingEvent.Functions = eventFunctionDataCollection;
        
        
        //existingEvent.Functions.Add(newEventFunction);
        existingEvent.AdditionalAttributes = new GenericPropertyDataCollection();

        // serialize event data with added function, coalesce to necessary type and update
        var serializedEventData = JsonConvert.SerializeObject(existingEvent, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All });
        HttpContent httpContent = new StringContent(serializedEventData, Encoding.UTF8, "application/json");

        var response = Client.PutAsync($"api/event/{eventId}", httpContent).Result;
        if (response.IsSuccessStatusCode)
        {
            return response;
        }

        return new HttpResponseMessage
        {
            StatusCode = HttpStatusCode.BadRequest
        };
    }

}

}

Thanks,

Julie