PostgresException return null from GCP when call function have an error by constraint FK - npgsql

I am using Google Cloud Platform to host my database postgres 9.6.
I have sent data to force error in FK for an update, in filas = cmd.ExecuteNonQuery() the result is 0 rows, as I hoped. But catch (PostgresException msg_exception) does not recognize the exception and PostgresNotice msg_notice = new PostgresNotice() returns NULL too when try to use the msg_notice.
using(var conn = new NpgsqlConnection(connString)) {
conn.Open();
conn.TypeMapper.MapComposite < DTO_Usuario > ("t_usuario");
using(var transaction = conn.BeginTransaction(IsolationLevel.ReadCommitted)) {
try {
using(NpgsqlCommand cmd = new NpgsqlCommand(# "SELECT ent_usuario_update(#p)", conn)) {
cmd.Parameters.Add(new NpgsqlParameter {
ParameterName = "p",
Value = row_usuario
});
PostgresNotice msg_notice = new PostgresNotice();
try {
filas = cmd.ExecuteNonQuery();
transaction.Commit();
if (filas > 0) {
row_usuario.Nom_usuario = msg_notice.MessageText;
} else {
row_usuario.Nom_usuario = msg_notice.MessageText;
}
} catch (PostgresException msg_exception) {
transaction.Rollback();
row_usuario.Des_cargo = msg_exception.SqlState;
}
return Ok(row_usuario);
}
} catch (NpgsqlException) {
transaction.Rollback();
return NoContent();
}
}
}
My function in Postgres:
CREATE OR REPLACE FUNCTION public.ent_usuario_update(
p_usuario t_usuario)
RETURNS void
update usuario
set des_cargo=p_usuario.des_cargo,
nom_usuario = p_usuario.nom_usuario,
id_organizacion = p_usuario.id_organizacion
where id_instancia = p_usuario.id_instancia
and id_mandante = p_usuario.id_mandante
and id_usuario=p_usuario.id_usuario;
GET DIAGNOSTICS filas = ROW_COUNT;
IF filas == 0 THEN
RAISE INFO 'No se actualizo usuario % en instancia %', p_usuario.id_usuario, p_usuario.id_instancia
using message = 'No actualizo';
ELSE
RAISE INFO 'ActualizaciĆ³n Realizada'
using message = 'No actualizo';
END IF;
RETURN;
END;

PostgreSQL notices aren't raised as exceptions, because they're not errors - so try/catch won't yield anything. It's also not possible to simply instantiate a PostgresNotice and expect it to get automatically filled in when you execute a command.
To receive a PostgreSQL notice, simply subscribe to the Notice event on your connection:
conn.Notice += (sender, args) => Console.WriteLine(args.Notice.MessageText);

Related

How to resolve MetadataAPI giving 'System.CalloutException: IO Exception: Read timed out' error on setting recordType to lookupfield value

I am using metadata API to add picklist value('custom') in a field.I have a record type (AAM_T) created which has to be associated with value I have added to picklist, but as on running :
service.updateMetadata( new MetadataService.Metadata[] { recordType });
causing an error 'System.CalloutException: IO Exception: Read timed out'.
MetadataService.PickListValue objPickListValue = new MetadataService.PickListValue();
objPickListValue.fullName = 'custom';
objPickListValue.default_x = false;
MetadataService.RecordType recordType = (MetadataService.RecordType)
service.readMetadata('RecordType',
new String[] { 'Account.AAM_T'}).getRecords()[0];
MetadataService.RecordTypePicklistValue[] recordPickListType = recordType.picklistValues;
if(recordPickListType.size() > 0){
for(MetadataService.RecordTypePicklistValue rpk : recordPickListType) {
if(rpk.picklist == picklistToUpdate){
rpk.values.add(objPickListValue);
break;
}
}
try{
service.updateMetadata( new MetadataService.Metadata[] { recordType });
} catch(Exception ex){
system.debug('###getStackTraceString : '+ex.getStackTraceString());
//Result: System.CalloutException: IO Exception: Read timed out -- null
system.debug('###getMessage : '+ex.getTypeName()
+ ': ' + ex.getMessage() + ' -- ' + ex.getCause());
}
}
You can try this like any other webservice. worked to me
MetadataService.MetadataPort service = new MetadataService.MetadataPort();
service.timeout_x=120000;

Uploading to SQL Server database offline

I'm trying to achieve a method whereby when a user upload a PDF document to a SQL Server database. The data would be uploaded instantly if network is available, but if there is no internet connection - the data would be stored somewhere else and be uploaded when internet connection is back. Please any idea how to achieve this?
Here is my code for the upload:
//CheckIfNetworkConnected( ) ;
Ping p = new Ping();
try
{
string host = "www.google.com";
//bool result = false;
PingReply reply = p.Send(host, 3000);
if (reply.Status == IPStatus.Success)
{
// Display form modelessly
pleaseWait.Show();
// Allow main UI thread to properly display please wait form.
Application.DoEvents();
using (SqlConnection con = new SqlConnection("Server=tcp:mycompany.database.windows.net,1433;Initial Catalog=DBmycompany;Persist Security Info=False;User ID=abubakarkabiru;Password=wordpass123#;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30"))
{
FileStream fStream = File.OpenRead(filepath);
byte[] contents = new byte[fStream.Length];
fStream.Read(contents, 0, (int)fStream.Length);
fStream.Close();
con.Open();
cmd = new SqlCommand("Insert into document values(#Staffname, #unit, #sites, #docname, #dateofreciept, #descriptions, #doc, #category, #housetype)", con);
if (textBox1.Visible == true)
{
cmd.Parameters.AddWithValue("#Unit", textBox1.Text);
cmd.Parameters.AddWithValue("#Staffname", textBox2.Text);
}
else
{
cmd.Parameters.AddWithValue("#Staffname", comboDesigner.SelectedItem.ToString());
cmd.Parameters.AddWithValue("#unit", comboUnit.SelectedItem.ToString());
}
cmd.Parameters.AddWithValue("#category", comboCategory.SelectedItem.ToString());
if (string.IsNullOrWhiteSpace(txtdocname.Text))
{
errorProvider1.SetError(txtdocname, "Compulsory");
}
else
{
cmd.Parameters.AddWithValue("#docname", string.IsNullOrWhiteSpace(txtdocname.Text));
}
cmd.Parameters.AddWithValue("#dateofreciept", dateTimePicker1.Value.ToShortDateString());
cmd.Parameters.AddWithValue("#doc", contents);
cmd.Parameters.AddWithValue("#sites", string.IsNullOrWhiteSpace(comboSites.ToString())
? (Object)comboSites.SelectedItem.ToString()
: (Object)DBNull.Value);
cmd.Parameters.AddWithValue("#housetype", string.IsNullOrWhiteSpace(comboHouseType.ToString())
? (Object)comboHouseType.SelectedItem.ToString()
: (Object)DBNull.Value);
cmd.Parameters.AddWithValue("#descriptions", string.IsNullOrWhiteSpace(txtDesc.Text)
? (object)txtDesc.Text
: (object)DBNull.Value);
var i = cmd.ExecuteNonQuery();
if (i > 0)
{
MessageBox.Show("Successful");
this.notifyIcon1.Icon = this.Icon;
this.notifyIcon1.ShowBalloonTip(600, "Upload Notice", "New Document has been Uploaded", ToolTipIcon.Info);
//notifyUpload();
}
con.Close();
}
pleaseWait.Hide();
cleaBoxes();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

ErrorIrresolvableConflict while creating an event

I am getting a lot of errors related to ErrorIrresolvableConflict response code when trying to create an event
Stack Trace - at Microsoft.OData.ProxyExtensions.DataServiceContextWrapper.<SaveChangesAsync>d__5e.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Office365CalendarProviderBL.<>c__DisplayClass7_0.<<CreateCalendarEvent>b__0>d.MoveNext() - Inner Exception - Microsoft.OData.Client.DataServiceRequestException: An error occurred while processing this request. ---> Microsoft.OData.Client.DataServiceClientException: {"error":{"code":"ErrorIrresolvableConflict","message":"The send or update operation could not be performed because the change key passed in the request does not match the current change key for the item."}}
--- End of inner exception stack trace ---
at Microsoft.OData.Client.SaveResult.HandleResponse()
at Microsoft.OData.Client.BaseSaveResult.EndRequest()
at Microsoft.OData.Client.DataServiceContext.EndSaveChanges(IAsyncResult asyncResult)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.OData.ProxyExtensions.DataServiceContextWrapper.<SaveChangesAsync>d__5e.MoveNext()
I am getting this message with this exception - The send or update operation could not be performed because the change key passed in the request does not match the current change key for the item.
Please explain what is a change key and how it works ?
I am getting these exceptions only from yesterday and hasn't changed any code. Do I need to update anything at my end or am I missing anything ?
I am using V1 DLL - https://api.office.com/discovery/v1.0/me/
ProxyExtension Version - 23
Code:-
// In this method, we are populating event properties later used to create event on calendar. Please verify if I am missing any important property here
private Event CreateCalEventObj(CalendarMeetingBL meeting, string location, meetingAdditionalDataBL data)
{
Event calEvent = new Event();
try
{
calEvent.Subject = WEB.HttpUtility.HtmlDecode(meeting.MeetingName);
calEvent.ShowAs = FreeBusyStatus.Busy;
if (meeting.EventAlarmInMinutes == -1)
meeting.EventAlarmInMinutes = null;
calEvent.Reminder = meeting.EventAlarmInMinutes;
calEvent.Start = meeting.StartTime;
calEvent.End = meeting.EndTime;
calEvent.StartTimeZone = meeting.TimeZoneString;
calEvent.EndTimeZone = meeting.TimeZoneString;
if (!string.IsNullOrEmpty(location) && location.Length <= 500)
{
calEvent.Location = new Microsoft.Office365.OutlookServices.Location()
{
DisplayName = CommonBL.FixLineBreakForGooglelocation(WEB.HttpUtility.HtmlDecode(location.Replace("\n", " ")))
};
}
else if (!string.IsNullOrEmpty(data.Phone))
{
calEvent.Location = new Microsoft.Office365.OutlookServices.Location()
{
DisplayName = "Phone: " + CommonBL.FixLineBreakForGooglelocation(WEB.HttpUtility.HtmlDecode(data.Phone))
};
}
else if (!string.IsNullOrEmpty(data.MobileNumber))
{
calEvent.Location = new Microsoft.Office365.OutlookServices.Location()
{
DisplayName = "Mobile: " + CommonBL.FixLineBreakForGooglelocation(WEB.HttpUtility.HtmlDecode(data.MobileNumber))
};
}
calEvent.Body = new ItemBody()
{
Content = CommonBL.RevertLineBreakPlaceHolder((WEB.HttpUtility.HtmlDecode(meeting.MeetingDetails.Replace(#"\\\", "\\"))))
};
}
catch (Exception ex)
{
BLFactory.CurrentInstance.LoggingBLObj.InsertLog("Insert logging here");
calEvent = null;
}
return calEvent;
}
// In this method we are creating event on calendar.
private string CreateCalendarEvent(CalendarMeetingBL meeting, List<ParticipantBL> invitees, string username, string calendarId, OutlookServicesClient service, string location, meetingAdditionalDataBL data, string meetingId = "-1")
{
var taskCreateMeeting = Task<string>.Run(
async () =>
{
Event calEvent = CreateCalEventObj(meeting, location, data);
if (calEvent != null)
{
try
{
//Add invitees to the event
foreach (ParticipantBL inviteeItem in invitees)
{
if (!inviteeItem.IsAdditional)
{
calEvent.Attendees.Add(new Attendee()
{
EmailAddress = new EmailAddress()
{
Address = inviteeItem.Email.Replace("'", "'"),
Name = inviteeItem.Name
},
Type = AttendeeType.Required,
Status = new ResponseStatus()
{
Response = ResponseType.Accepted,
Time = DateTime.Now
}
});
}
}
}
catch (Exception ex)
{
BLFactory.CurrentInstance.LoggingBLObj.InsertLog(meeting.MeetingId, username, "Locally User ID is Meeting id AND email is username - Scheduling Logging Exception 3 - Stack Trace - " + ex.StackTrace + " - Inner Exception - " + ex.InnerException + " - meetingObjValues - " + meetingObjValues + " - meetingAdditionalDataObjValues - " + meetingAdditionalDataObjValues + " - username - " + username + " - calendarId - " + calendarId + " - location - " + location + " - meetingId - " + meetingId, meeting.MeetingId);
return "-1";
}
try
{
var providerDefault = (String.IsNullOrEmpty(calendarId) ? service.Me.Events : service.Me.Calendars[calendarId].Events);
await providerDefault.AddEventAsync(calEvent); // We are getting Exception here but Event is created in calendar
return calEvent.Id; // Event object is not updated after exception
}
catch (Exception ex)
{
BLFactory.CurrentInstance.LoggingBLObj.InsertLog("Insert exception logging here");
return "-1";
}
}
else
return "-1";
}
);
Task.WaitAll(taskCreateMeeting);
string id = taskCreateMeeting.Result;
return id;
}
The exception we are getting is of type Microsoft.OData.Client.DataServiceRequestException but it is not caught under the dedicated catch block
catch (Microsoft.OData.Client.DataServiceRequestException ex)
{
BLFactory.CurrentInstance.LoggingBLObj.InsertLog("Insert logging here");
return "-1";
}
Let me know if anything else is required
Thanks in Advance.
This is not directly related to OData - we have seen the same thing with EWS. We just found the underlying race condition inside of Exchange code that was causing this and one of our devs just checked in a fix for this. As such, it should start rolling out in production soon.
There is nothing wrong with your code that would be causing this for a new item.

Message.Payload is always null for all messages. How do I get this data?

It is returning the correct number of message, but the only fields that are populated are Id and ThreadId. Everything else is null
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
ListMessagesResponse response = service.Users.Messages.List(emailAddress).Execute();
IList<Google.Apis.Gmail.v1.Data.Message> messages = response.Messages;
Console.WriteLine("Messages:");
if (messages != null && messages.Count > 0)
{
foreach (var message in messages)
{
Console.WriteLine("{0}", message.Payload.Body);
Console.WriteLine();
}
}
else
{
Console.WriteLine("No Messages found.");
}
Messages.List() only returns message and thread ids. To retrieve message contents, you need to invoke Get() for each message you are interested in. Updated version of your foreach loop example:
foreach (var message in messages)
{
Message m = service.Users.Messages.Get("me", message.Id).Execute();
// m.Payload is populated now.
foreach (var part in m.Payload.Parts)
{
byte[] data = Convert.FromBase64String(part.Body.Data);
string decodedString = Encoding.UTF8.GetString(data);
Console.WriteLine(decodedString);
}
}
Note: You may need to run a string replace on the part.Body.Data string. See this post for instructions.

Get Unread emails from Google API

I'm trying to get the count of unread email using google API, but not able. ANy help is highly appreciated. I'm not getting any error, but the count doesnt match the actual number shown in gmail.
try
{
String serviceAccountEmail = "xxx#developer.gserviceaccount.com";
var certificate = new X509Certificate2(#"C:\Projects\xxx\xyz\API Project-xxxxx.p12", "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
User = "xxx#gmail.com",
Scopes = new[] { Google.Apis.Gmail.v1.GmailService.Scope.GmailReadonly }
}.FromCertificate(certificate));
var gmailservice = new Google.Apis.Gmail.v1.GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "GoogleApi3",
});
try
{
List<Message> lst = ListMessages(gmailservice, "xxx#gmail.com", "IN:INBOX IS:UNREAD");
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
}
catch (Exception ex)
{
}
Just do: labels.get(id="INBOX") and it has those types of stats (how many messages in that label, how many are unread, and same for threads).
https://developers.google.com/gmail/api/v1/reference/users/labels/get
You can use the ListMessages method from the API example (included for completeness) for searching:
private static List<Message> ListMessages(GmailService service, String userId, String query)
{
List<Message> result = new List<Message>();
UsersResource.MessagesResource.ListRequest request = service.Users.Messages.List(userId);
request.Q = query;
do
{
try
{
ListMessagesResponse response = request.Execute();
result.AddRange(response.Messages);
request.PageToken = response.NextPageToken;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
} while (!String.IsNullOrEmpty(request.PageToken));
return result;
}
You can use this search method to find unread messages, for example like this:
List<Message> unreadMessageIDs = ListMessages(service, "me", "is:unread");
The q parameter (query) can be all kinds of stuff (it is the same as the gmail search bar on the top of the web interface), as documented here: https://support.google.com/mail/answer/7190?hl=en.
Note that you only a few parameters of the Message objects are set. If you want to retreive the messages you'll have to use GetMessage method from the api:
public static Message GetMessage(GmailService service, String userId, String messageId)
{
try
{
return service.Users.Messages.Get(userId, messageId).Execute();
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
return null;
}
I agree that the API is not straight forward and misses a lot of functionality.
Solution for .Net:
// Get UNREAD messages
public void getUnreadEmails(GmailService service)
{
UsersResource.MessagesResource.ListRequest Req_messages = service.Users.Messages.List("me");
// Filter by labels
Req_messages.LabelIds = new List<String>() { "INBOX", "UNREAD" };
// Get message list
IList<Message> messages = Req_messages.Execute().Messages;
if ((messages != null) && (messages.Count > 0))
{
foreach (Message List_msg in messages)
{
// Get message content
UsersResource.MessagesResource.GetRequest MsgReq = service.Users.Messages.Get("me", List_msg.Id);
Message msg = MsgReq.Execute();
Console.WriteLine(msg.Snippet);
Console.WriteLine("----------------------");
}
}
Console.Read();
}

Resources