Writing Code is fun, see here :)


Some really nice comments I have picked during a peer review.

// Server Side Validation Functions 
private bool ValidateGeneralDOB(object fieldValue) 
  DateTime dt;

    return false; // are you kidding me, you should be born :( 

  else if (!DateTime.TryParse(fieldValue.ToString(),out dt)) 
    return false; // you should be born on a valid date 

  else if(dt>DateTime.Now.AddYears(-20)) // to little :) 
   return false; 

  else if (dt < DateTime.Now.AddYears(-90)) // to old :| 
   return false;

 // your are the one we are looking for 
  return true; 




About CAE Solutions

Web: http://www.caesolutions.com/

Linkedin: https://www.linkedin.com/company/301183/

Sally Verrilli post on how CAE Solutions helped UnitedHealth Group with a system that is dying or dead: https://lnkd.in/eecCsuu

An extract from her post:

Who’s been here?

You work in a big company.

You lead a department that has a system that is dying or dead.
You don’t need the space shuttle.
You need something to keep you in orbit for a year or two.
Your system need isn’t big enough to merit capital.

This was my situation last year.  I had to have a system that worked within 1 year or I was screwed. My internal team was in transition and I didn’t know if they would be stable enough or able enough to get this done after I announced the death of the legacy system. (Back then, we were new to each other.  Now I know they CAN.)

My budget wasn’t big but I knew I had to do something.
I needed to up my odds of success.

The vendor that helped build my new, interim system is CAE Solutions. It wasn’t easy;  but it got done and done on time and on budget.  The new system has been up and running with great success for 11 months now, and we are headed into our second busy season with it.

I have no vested interest in CAE, and this is not a sales pitch.  I took a chance and it worked out.  System builds rarely have happy endings for many reasons.  This one did.  Call Anil Gupta at CAE solutions if you need help. It worked for me.

Calling an oData Batch using .net HttpClient class

You have full code here, no theory!

Private Async Function SaveEntityAsBatch() As Threading.Tasks.Task
Using Client As New HttpClient()
Dim APIhostUri As String = “http://localhost:2025/&#8221;
Dim APIResponse As HttpResponseMessage
Client.BaseAddress = New Uri(APIhostUri)
Dim content As HttpContent

‘Required if you need dates serialization

Dim microsoftDateFormatSettings As JsonSerializerSettings = New JsonSerializerSettings With {
.DateFormatHandling = DateFormatHandling.IsoDateFormat,
.DateParseHandling = DateParseHandling.DateTimeOffset, .DateTimeZoneHandling = DateTimeZoneHandling.Utc

‘ Batch Process
Dim boundary As String = “–changeset_Data—”
Dim batchContent As New MultipartContent(“mixed”, “–batch” & boundary)

Dim RqP As New HttpRequestMessage(HttpMethod.Put, “URL(id)/”)
RqP.Content = New StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(projectRequest, microsoftDateFormatSettings))
If RqP.Content.Headers.Contains(“Content-Type”) Then RqP.Content.Headers.Remove(“Content-Type”)
RqP.Content.Headers.Add(“Content-Type”, “application/json”)
Dim ReqContent As New HttpMessageContent(RqP)
If ReqContent.Headers.Contains(“Content-Type”) Then ProjectContent.Headers.Remove(“Content-Type”)
ReqContent.Headers.Add(“Content-Type”, “application/http”)
ReqContent.Headers.Add(“Content-Transfer-Encoding”, “binary”)
ReqContent.Headers.Add(“client-request-id”, “12345678”)
ReqContent.Headers.Add(“return-client-request-id”, “True”)
ReqContent.Headers.Add(“Content-ID”, “1”)
ReqContent.Headers.Add(“DataServiceVersion”, “3.0”)
If ReqContent.Headers.Contains(“contentTypeMime-Part”) Then ReqContent.Headers.Remove(“contentTypeMime-Part”)
ReqContent.Headers.Add(“contentTypeMime-Part”, “Content-Type:application/http;”)



Dim RqR As New HttpRequestMessage(HttpMethod.Put, “URL2/”, PtsAPIhostUri)
RqR.Content = New StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(report, microsoftDateFormatSettings))
If RqR.Content.Headers.Contains(“Content-Type”) Then RqR.Content.Headers.Remove(“Content-Type”)
RqR.Content.Headers.Add(“Content-Type”, “application/json”)
Dim ReqContent2 As New HttpMessageContent(RqR)

If ReqContent2.Headers.Contains(“Content-Type”) Then ReportContent.Headers.Remove(“Content-Type”)
ReqContent2.Headers.Add(“Content-Type”, “application/http”)
ReqContent2.Headers.Add(“Content-Transfer-Encoding”, “binary”)
ReqContent2.Headers.Add(“client-request-id”, “99999”)
ReqContent2.Headers.Add(“return-client-request-id”, “True”)
ReqContent2.Headers.Add(“Content-ID”, “2”)
ReqContent2.Headers.Add(“DataServiceVersion”, “3.0”)

If ReqContent2.Headers.Contains(“contentTypeMime-Part”) Then ReqContent2.Headers.Remove(“contentTypeMime-Part”)
ReqContent2.Headers.Add(“contentTypeMime-Part”, “Content-Type:application/http;”)
Dim batchRequest As HttpRequestMessage = New HttpRequestMessage(HttpMethod.Post, APIhostUri & “/$batch/”)
batchRequest.Content = batchContent
Dim APIResponseBatch = Await Client.SendAsync(batchRequest)
Dim streamProvider = APIResponseBatch.Content.ReadAsMultipartAsync().Result()

For Each cnt As HttpContent In streamProvider.Contents

End Using
End Function

I got following errors in given sequences and I continued to add the header and finally I was able to two PUT request in Batch.

Error #1

The ‘Content-Type’ header value ‘application/http; msgtype=request’ is invalid. When this is the start of the change set, the value must be ‘multipart/mixed’; otherwise it must be ‘application/http’.

Error #2

The content type ‘multipart/mixed’ specifies a batch payload; however, the payload either does not include a batch boundary or includes more than one boundary. In OData, batch payload content types must specify exactly one batch boundary in the ‘boundary’ parameter of the content type.

Error #3

Nested change sets in a batch payload are not supported.

Error #3 took most of the time to find out this URL https://msdn.microsoft.com/en-us/library/azure/dn878159.aspx from MSDN, which speaks about adding following Header Content Types

ReqContent2.Headers.Add(“client-request-id”, “99999”)
ReqContent2.Headers.Add(“return-client-request-id”, “True”)
ReqContent2.Headers.Add(“Content-ID”, “2”)
ReqContent2.Headers.Add(“DataServiceVersion”, “3.0”)

After adding above four types to header Error #3 was gone and my Batch was working.

The URL from MSDN says;

Add Tasks requests in Batch service support the following concepts:

  • Each request must contain a unique Content-ID MIME part header. This header is returned with the result of the operation in the response, and can be used to match an individual request with its response.
  • The Batch service returns a HTTP Status Code 400 (Bad Request) if any request contains an invalid set of headers or contains operations which are not supported in the batch.
  • The Batch service returns a HTTP Status Code 202 (Accepted) for a valid Add Tasks request. The server will then stream the results of individual operations.
  • The Batch service can re-order the responses of these Add Task requests. The Content-Id MIME part header needs to be used by the Client to match the request corresponding to the response. The response contains the results and error information for each operation.If the server times out or the connection is closed during an Add Tasks request, the request may have been partially or fully processed, or not at all. In such cases, the user should re-issue the request. Note that it is up to the users to correctly deal with failures when re-issuing a request. For example, the users should use the same task names during retry, so that if the prior operation succeeded, the retry will not create extra tasks unexpectedly.
  • An Add Tasks request can include at most 100 operations.
  • All the tasks in an Add Tasks request must belong to the same workitem and job.