.Net serializer is serializing DateTime in different precisions - json.net

My Code: I have an API currently, once I get a request from the client, we save the information along with the time of the request which is DateTime.UtcNow()(this is not received from the client, we do it in my code). and save it in the couchbase.
Problem:
Sometimes the DateTime field is saved with different precisions, ideally I would like to save this field with a precision upto 7 decimal points(e.g:2020-12-28T18:45:24.6901637Z) but sometimes .net is saving this time with different precisions(2020-12-28T18:49:10.02396Z).
Can someone please help me figure out why is this happening randomly. I am using .net core 3.1.
Code Sample:
var obj = new obj{empId = 111, empType = 'Contractor', status = 'Ontime', lastUpdatedTime = DateTime.UtcNow}; var id = 111;
var response = await _bucket.InsertAsync<dynamic>(id, obj);
response in couchbase: { empId : 111, empType : Contractor, status : 'OnTime', lastUpdatedTime : '2020-12-28T18:45:24.6901637Z', }, { empId : 222, empType : Contractor, status : 'Delayed', lastUpdatedTime : '2020-12-28T18:50:19.12345Z', }
I apologize for any kind of vague information i provided. please let me know if i need to put any other information which will make more sense

Related

Put Method To Update A 'Hotel' Object Ends With System.Text.Json.JsonException

Put request is handled very well as far as I have observed but something goes wrong after an updated hotel object is passed to HotelManager layer from HotelRepository.
That's the error: System.Text.Json.JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32.
here is the code in HotelRepository:
public async Task<int> UpdateHotel(Hotel hotel)
{
var sql = "UPDATE Hotels " +
"SET name = #name, city = #city " +
"WHERE Id = #id";
var updatedHotel = new Hotel()
{
Name = hotel.Name,
City = hotel.City,
Id = hotel.Id
};
using (var connection = new SqlConnection(CONNECTION_STRING))
{
return await connection.ExecuteAsync(sql, updatedHotel);
}
}
At first I though it was about the spaces in the sql commands. I realized I did not add any spaces after the ends of the lines so I fixed that but I guess that's not the issue since I still get the same error.
The other routes work well.
Hotel object in the request contains id, name, and city.
Do you know what's wrong?
That's the error: System.Text.Json.JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32.
You can try to install the Microsoft.AspNetCore.Mvc.NewtonsoftJson NuGet package to add support for Newtonsoft.Json based features, and check if it can help fix above issue.
services.AddControllersWithViews().AddNewtonsoftJson(options =>
{
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});

CreateEnvelopeFromTemplates - Guid should contain 32 digits with 4 dashes

I am attempting to create a DocuSign envelope from a template document using the CreateEnvelopeFromTemplates method, available within their v3 SOAP API web service. This is being instantiated from a asp.NET v4.0 web site.
Upon calling the method armed with the required parameter objects being passed in. I am recieving an exception from the web service, basically telling me that the Template ID is not a valid GUID.
669393: Guid should contain 32 digits with 4 dashes (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
Line 14889:
Line 14890: public DocuSignDSAPI.EnvelopeStatus CreateEnvelopeFromTemplates(DocuSignDSAPI.TemplateReference[] TemplateReferences, DocuSignDSAPI.Recipient[] Recipients, DocuSignDSAPI.EnvelopeInformation EnvelopeInformation, bool ActivateEnvelope) {
Line 14891: return base.Channel.CreateEnvelopeFromTemplates(TemplateReferences, Recipients, EnvelopeInformation, ActivateEnvelope);
Line 14892: }
Line 14893:
The template reference, a guid. Must be specified as the "Template" string property against TemplateReference object. This is then added to a dynamic array of TemplateReferences, which is one of the input parameters of the CreateEnvelopeFromTemplates method.
Actual template GUID: f37b4d64-54e3-4723-a6f1-a4120f0e9695
I am building up my template reference object using the following function that i wrote to try and make the functionality reusable:
Private Function GetTemplateReference(ByVal TemplateID As String) As TemplateReference
Dim templateReference As New TemplateReference
Dim guidTemplateID As Guid
With TemplateReference
.TemplateLocation = TemplateLocationCode.Server
If Guid.TryParse(TemplateID, guidTemplateID) Then
.Template = guidTemplateID.ToString
End If
End With
Return TemplateReference
End Function
The TemplateID is being passed in from a appSetting configuration value at the time of the TemplateReferences array instantiation like so...
templateReferences = New TemplateReference() {GetTemplateReference(ConfigurationManager.AppSettings("DocuSignTemplate_Reference"))}
recipients = New Recipient() {AddRecipient("myself#work.email", "My Name")}
envelopeInformation = CreateEnvelopeInformation()
envelopeStatus = client.CreateEnvelopeFromTemplates(templateReferences, recipients, envelopeInformation, True)
As you can see from my GetTemplateReference function I am also parsing the GUID before setting it back as a string so i know its valid. The template is managed and stored at the DocuSign end, hence specifying the document location.
I am referring to their own documentation:
CreateEnvelopeFromTemplates
Why oh why is the method not liking my Template ID? I can successfully use their REST API to call the same method, using their own code samples. Worst case I can make use of this but would rather interact with the web service as I would need to construct all the relevent requests in either XML or JSON.
I would really appreciate if someone could perhaps shed some light on this problem.
Thanks for taking the time to read my question!
Andrew might be spot on with the AccountId mention - are you setting the AccountId in the envelope information object? Also, have you seen the DocuSign SOAP SDK up on Github? That has 5 sample SOAP projects including one MS.NET project. The .NET project is in C# not Visual Basic, but still I think it will be helpful to you. Check out the SOAP SDK here:
https://github.com/docusign/DocuSign-eSignature-SDK
For instance, here is the test function for the CreateEnvelopeFromTemplates() function:
public void CreateEnvelopeFromTemplatesTest()
{
// Construct all the recipient information
DocuSignWeb.Recipient[] recipients = HeartbeatTests.CreateOneSigner();
DocuSignWeb.TemplateReferenceRoleAssignment[] finalRoleAssignments = new DocuSignWeb.TemplateReferenceRoleAssignment[1];
finalRoleAssignments[0] = new DocuSignWeb.TemplateReferenceRoleAssignment();
finalRoleAssignments[0].RoleName = recipients[0].RoleName;
finalRoleAssignments[0].RecipientID = recipients[0].ID;
// Use a server-side template -- you could make more than one of these
DocuSignWeb.TemplateReference templateReference = new DocuSignWeb.TemplateReference();
templateReference.TemplateLocation = DocuSignWeb.TemplateLocationCode.Server;
// TODO: replace with template ID from your account
templateReference.Template = "server template ID";
templateReference.RoleAssignments = finalRoleAssignments;
// Construct the envelope information
DocuSignWeb.EnvelopeInformation envelopeInfo = new DocuSignWeb.EnvelopeInformation();
envelopeInfo.AccountId = _accountId;
envelopeInfo.Subject = "create envelope from templates test";
envelopeInfo.EmailBlurb = "testing docusign creation services";
// Create draft with all the template information
DocuSignWeb.EnvelopeStatus status = _apiClient.CreateEnvelopeFromTemplates(new DocuSignWeb.TemplateReference[] { templateReference },
recipients, envelopeInfo, false);
// Confirm that the envelope has been assigned an ID
Assert.IsNotNullOrEmpty(status.EnvelopeID);
Console.WriteLine("Status for envelope {0} is {1}", status.EnvelopeID, status.Status);
}
This code calls other sample functions in the SDK which I have not included, but hopefully this helps shed some light on what you're doing wrong...
This problem arises when you don't set up the field AccountId. This field can be retrieved from your account. In Docusign's console go to Preferences / API and look here
Where to find AccountID Guid in Docusign's Console
Use API Account ID (which is in GUID format) and you should be OK.

Not getting WeChat Follow response

I have a Debugging Official Account with WeChat. I have entered my public URL and Token into the field provided http://admin.wechat.com/debug/sandbox and also attempted debugging the request with http://admin.wechat.com/debug/
My ASP.Net [.Net4.5] Web API application's POST Method looks like the following :
public HttpResponseMessage PostMessage([FromBody]Strikemedia.Api.WeChat.TextMessage value)
{
if (value == null)
{
var richMediaMessage = new RichMediaMessage();
richMediaMessage.touser = value.FromuserName;
//Create Article
var item = new Article()
{
title = "Didn't receive anything back",
description = "Mind entering 'test'",
picurl = "URL",
url = "URL"
};
var articles = new List<Article>();
articles.Add(item);
richMediaMessage.articles = articles;
richMediaMessage.articleCount = articles.Count;
return Request.CreateResponse(HttpStatusCode.OK, richMediaMessage, "application/json");
}
var exploded = value.Content.Split(' ')[0];
var richMedia = new RichMediaMessage();
richMedia.touser = value.FromuserName;
//Create Article
var article = new Article() {
title = response.KeywordDescription,
description = response.Response,
picurl = "URL",
url = "URL"
};
var _articles = new List<Article>();
_articles.Add(article);
richMedia.articles = _articles;
richMedia.articleCount = _articles.Count;
//Return response
var resp = Request.CreateResponse(HttpStatusCode.OK, richMedia, "application/json");
//resp.RequestMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
return resp;
}
It needs to respond with a RichMessageType in JSON format and is received in XML format
Am i missing something or have i overlooked something?
Can you confirm that you have submitted the URL and token into admin.wechat.com and that the URL and token was accepted?
Also note you get XML and you respond with XML no json response.
Have you had a look at: http://youtu.be/kB20Zf51QWU
And then this
http://youtu.be/_2FSzD2B2F0
This is the documentation for the XML can be found when you google "wechat guide to message api"
So if you still not receiving a success message when submitting your app on admin.wechat.com then you can send me your test URL here. To find this URL check your access logs to see exactly what URL wechat is calling. Then post it here. Please note that when you hit the URL as wechat will you should only see the "echostr" printed on the screen (when viewing the source in your browser). No XML no HTML just the echostr.
Also make sure there are no spaces or newlines after or before the "echostr". When you view the source it should only be one line which is the echostr GET param's value.
The XML response only comes in later when you actually start responding to messages from users. For now Wechat is just confirming if your security is setup correctly.
Also note if your server is load balanced you will have to skip the signature validation and build your own validation when a echostr GET parameter gets passed through and only echo the "echostr" param to screen.

Asp.net add multiply rows to CRM 2011 (2+ clients/User)

I've extended the customer portal from MS for 2011 with functionality to add an order.
Now i came across a problem when 2 or more user try to create an order at the same time.
first I created the SalesOrder with:
order = new SalesOrder();
order.SalesOrderId = OrderID;
order.Name = string.Format("Order {0}", DateTime.Now);
order.CustomerId = parentCustomer;
order.PriceLevelId = priceLevel.ToEntityReference();
OrderID = XrmContext.Create(order);
and after this i added products(SalesOrderDetail) with a foreach:
foreach (var product in OrdredProducts)
{
productToAdd = new SalesOrderDetail
{
SalesOrderId = new CrmEntityReference(SalesOrder.EntityLogicalName,
OrderID),
ProductId = new EntityReference(Product.EntityLogicalName,
product.ProductID),
Quantity = product.Quantity
};
XrmContext.Create(productToAdd);
}
this works fine when just one user orders something. But if 2+ users I get error for both user.
so I changed the code to this:
order = new SalesOrder();
OrderID = Guid.NewGuid();
order.SalesOrderId = OrderID;
order.Name = string.Format("Order {0}", DateTime.Now); //:d
order.CustomerId = parentCustomer;
order.PriceLevelId = priceLevel.ToEntityReference();
XrmContext.AddObject(order);
foreach (var product in OrdredProducts)
{
productToAdd = new SalesOrderDetail
{
SalesOrderId = new CrmEntityReference(SalesOrder.EntityLogicalName,
OrderID),
ProductId = new EntityReference(Product.EntityLogicalName,
product.ProductID),
Quantity = product.Quantity
};
XrmContext.AddObject(productToAdd);
}
XrmContext.SaveChanges();
Now if 2+ Users orders something, just one User fails not both like the first try.
the Errors I've got as far(every time an other one):
ValidateOpen - Encountered disposed CrmDbConnection when it should not be disposed
SQL timeout expired.
An unexpected error occurred.
Error retrieving next number (currentordernumber) for organization {guid): return value is empty
System.InvalidOperationException: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #F60BF6A2
does anyone have some suggestion where the problem could be? is it the SQL Server/CRM Server/IIS/my code or something different?
Additional Information
SQL Server and CRM Server are not on same machine
I get the same error when i test in VS2012 server(back-end is the same SQL/CRM server)
i get the same error when one user runs over IIS and one over VS2012(debugg)
edit
XrmContext is a XrmServiceContext type and this is derived from CrmOrganizationServiceContext and this one is generated with the crmsvcutil
if someone gets the same problem i solved it following:
first i created the SalesOrder and added it to the CRM:
public void AddToCrm(Entity entity)
{
XrmContext.AddObject(entity);
}
then I created all Orders(SalesOrderDetail) and added them to the CRM(same function as above).
And finally i saved it:
public void SaveToCrm()
{
XrmContext.SaveChanges();
}
this behaviour is like a transaction in the database.
so all other Order have to wait till this one is done.

ADO.NET Data Services: Non-Asynch Calls?

I have a question that I'm struggling with in ADO.NET Data Services:
When assembling an Entity for storage I need to get a related value from a lookup file. For example a person has a status code assigned of 'Pending' which is in a table called StatusCodes.
In Entity Framework, I'd need to set the value of person.StatusCode equal to an instance of the StatusCode. In the Entity Framework or in LINQ2Sql I'd so something like this:
var person = Person.CreatePerson(stuff);
var statCode = myContext.StatusCodeSet.Where(sc => sc.Description == "Pending").FirstOrDefault();
person.StatusCode = statCode;
// ...more code here...
myContext.BeginSaveChanges(SaveChangesOptions.Batch,
new AsyncCallback(OnSaveAllComplete),
null);
The query for the statCode won't work in ADO.NET Data Services and I get a runtime error saying the function is not supported. I assume it's because the statCode lookup is not an Async call.
However,
var person = Person.CreatePerson(stuff);
var query = from stat in myContext.StatusCodeSet
where stat.Description == "Pending"
select stat;
var dsQuery = (DataServiceQuery<StatusCode>)query;
dsQuery.BeginExecute(
result => tutorApplication.StatusCode = dsQuery.EndExecute(result).FirstOrDefault(), null);
// ...more code here...
myContext.BeginSaveChanges(SaveChangesOptions.Batch,
new AsyncCallback(OnSaveAllComplete),
null);
doesn't work either due to the Async nature of the query, the result won't be back before the person save happens.
Am I approaching this correctly?
Thanks
After sleeping on this I came up with the following:
var person = Person.CreatePerson(stuff);
var appStatPending = new StatusCode()
{
StatusCodeId = (int)StatusCodes.Pending,
Code = "Pending",
Description = "Pending",
EffectiveDate = DateTime.Now,
EnteredBy = "",
EnteredDate = DateTime.Now
};
myContext.AttachTo("StatusCodeSet", appStatPending);
person.StatusCode = appStatPending;
myContext.SetLink(tutorApplication, "StatusCode", appStatPending);
// ...more code here...
myContext.BeginSaveChanges(SaveChangesOptions.Batch,
new AsyncCallback(OnSaveAllComplete),
null);
I can create a local copy of the status code and link it into the context. It's important to new up the appStatPending rather than doing a StatusCode.CreateStatusCode() since doing that will add a new StatusCode to the database when the person graph persisted. For the same reason it's important to do the AttachTo("StatusCodeSet", appStatPending) since doing myContext.AddToStatusCodeSet() will also add a new entry to the StatusCodes table in the database.

Resources