Hi Community,

 

We have this requirement, where we need to receive a complex json object and then store it in our database as a string, without using DataContracts.

 

To achieve this we though about using the "object" type and then serialize it into a string using JsonConvert.SerializeObject method. 

 

	  [OperationContract]
	  [WebInvoke(Method = "POST", UriTemplate = "/store", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
      public Response AddStore(object store) {
 
         Response response = new Response();
         response.MessageId = "1";
         response.Description = "Store Inserted!";
 
        string storeString = JsonConvert.SerializeObject(store, Formatting.Indented);
 
        var ins = new Insert(UserConnection)
        .Into("ImdStagingInArticle")
        .Set("ImdMessage", Column.Parameter(storeString))
        .Set("ImdStateId", Column.Parameter(new Guid("2d1dee23-058b-45fe-95a0-2e1612fc4261")));
 
        ins.Execute();
 
        return response;   
      }

 

However, the string is always empty. 

 

Since the json is to complex, the serializer cannot process the entire json data. 

 

We also tried to use WebOperationContext, but that doesn't work.

 

Can someone help us solve this issue? Did anyone have something similar?

 

Thank you.

Like 0

Like

7 comments

Hi,

 

First of all you need to make sure that you can convert the object into a string in general. Like create a Visual Studio project, add the logic to convert the object into a string using JsonSerializer like

 

string jsonString = JsonSerializer.Serialize(myObject); Console.WriteLine(jsonString);

 

And see the result. After the number of tests find the way when the data you pass is converted into the string and then start developing an additional logic of storing this data in the Creatio database using the insert query you used.

 

Alternatively find the way to make the object to have a constant set of keys so to be sure it will be converted to the string as needed.

Oleg Drobina,

 

After some changes I got it to work, by reading the raw body before the automatic parsing. However, this is working only on our Linux environment. As for for windows environment (Creatio Cloud), we are receiving some parse errors. 

 

      [OperationContract]
      [WebInvoke(Method = "POST", UriTemplate = "/article", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
      public Response AddArticle(string articleJson) {
 
        string result = "";
        Stream inputStream = HttpContext.Current.Request.Body;
 
        inputStream.Position = 0;
        using (StreamReader reader = new StreamReader(inputStream, Encoding.UTF8))
        {
            result = reader.ReadToEnd();
        }
 
        var parsedJson = JsonConvert.DeserializeObject(result);
        string jsonString = JsonConvert.SerializeObject(parsedJson, Formatting.Indented);
 
 
 
 
 
        Response response = new Response();
        response.MessageId = "1";
        response.Description = "Article Inserted!";
 
 
 
        var ins = new Insert(UserConnection)
        .Into("ImdStagingInArticle")
        .Set("ImdMessage", Column.Parameter(jsonString))
        .Set("ImdStateId", Column.Parameter(new Guid("2d1dee23-058b-45fe-95a0-2e1612fc4261")));
        ins.Execute();
 
        inputStream.Close();
 
        return response;  
      }

 

What could be the cause for such weird behaviour?

 

Thank you.
      

 

Pedro Pinheiro,

 

Well, it shouldn't happen. Maybe there is still some difference in the content we pass in the local machine and in the Windows machine?

Oleg Drobina,

 

The requests are the same for both local and cloud environments, except the address and credentials.

 

However, when I execute the request on the cloud environment I get this error:

 

 <p class="heading1">Request Error</p>
       <p>The server encountered an error processing the request. The exception message is 'This method or property is
           not supported after HttpRequest.GetBufferlessInputStream has been invoked.'. See server logs for more
           details. The exception stack trace is: </p>
       <p> at System.Web.HttpRequest.get_InputStream()
           at Terrasoft.Configuration.ImdArticleAPI.ArticleAPI.AddArticle(Object article)
           at SyncInvokeAddArticle(Object , Object[] , Object[] )
           at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]&amp;
           outputs)
           at Terrasoft.Web.Common.ServiceModel.ThreadContextInitializer.Invoke(Object instance, Object[] inputs,
           Object[]&amp; outputs)
           at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)
           at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)
           at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc)
           at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</p>

 

Have you encountered something similiar? What could be the cause for such error?

 

Thank you.

 

Pedro Pinheiro,

 

Creatio doesn’t know how to serialize/deserialize object. If you change object to string in Response AddStore(object store) you will be able to parse it with JsonParser of your choice.

Kirill Krylov CPA,

 

The problem is, if I change it to string I can only send strings to this endpoint (The Json must be converted to a string). Because, if I try to send a Json Object I get "400 Bad Request".

 

 

 

Hello everyone,

 

I managed to get it working by receiving the body as a Stream instead of a String.

 

With this solution, I don't get the "400 Bad request" and I can process any Json object.

 

I don't know if this is the best solution, but it's working for now.
 

	  [OperationContract]
      [WebInvoke(Method = "POST", UriTemplate = "/article", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
      public Response AddArticle(Stream requestBody) {
 
        string result = "";
 
        using (StreamReader reader = new StreamReader(requestBody, Encoding.UTF8))
        {
            result = reader.ReadToEnd();
        }
 
        var parsedJson = JsonConvert.DeserializeObject(result);
        string jsonString = JsonConvert.SerializeObject(parsedJson, Formatting.Indented);
 
        Response response = new Response();
        response.MessageId = "1";
        response.Description = "Article Inserted!";
 
        var ins = new Insert(UserConnection)
        .Into("ImdStagingInArticle")
        .Set("ImdMessage", Column.Parameter(jsonString))
        .Set("ImdStateId", Column.Parameter(new Guid("2d1dee23-058b-45fe-95a0-2e1612fc4261")));
        ins.Execute();
 
        return response;  
      }

 

Feel free to give any feedback on this solution.

 

Thank you.

 

Show all comments

Hello Community!

 

The documentation does not help much with respect when the "Serialize in DB" option in the Business process designer should be selected or not. The following is what is mentioned - 

 

[Serialize in DB] – saves parameter values for the running process in the database. Serialization is used for long processes. For example, if a new activity is created in the process and should be completed only after a certain time, all process parameters will be saved and the process can be resumed any time, even when you log out of the system.



1. Is the "Serialize in DB" option mandatory to be selected for all processes which involve user intervention? Eg I find that If I have a "User Dialog" element, the business process errors out if I don't select "Serialize in DB". 

2. What is the relation between execution of BPs and logging out of a user? How does it correlate to selection of "Serialize in DB"?? 



A few examples will help

Like 1

Like

3 comments
Best reply

Hello,

 

It is necessary to have this checkbox if the process should be stopped for some certain time, for example if you have any timer, activity that has to be performed as well as user dialog, etc.

This checkbox allows saving parameters data in the database. If it is not selected, the process data will be just saved in the browser cache. If it is long term process, the cached data might be cleared, especially if the user logged out,  so the process would not move forward. 

 

Regards,

Dean

Hello,

 

It is necessary to have this checkbox if the process should be stopped for some certain time, for example if you have any timer, activity that has to be performed as well as user dialog, etc.

This checkbox allows saving parameters data in the database. If it is not selected, the process data will be just saved in the browser cache. If it is long term process, the cached data might be cleared, especially if the user logged out,  so the process would not move forward. 

 

Regards,

Dean

dean parrett,

Thank you Dean

dean parrett,

 

What would be a good reason for not serializing in DB? Is it just a performance benefit from not having to write data to the DB? Are there other benefits? Thanks.

Show all comments