I have following NLog 2.0 code to log exceptions:
Dim theEvent = NLog.LogEventInfo.Create(NLog.LogLevel.Error, loggerName, message, ex)
After upgrading to NLog 4.1 I see following warning:
Function Create(logLevel As LogLevel, loggerName As String, message As String, exception As Exception) As LogEventInfo' is obsolete: 'use Create(LogLevel logLevel, string loggerName, Exception exception, IFormatProvider formatProvider, string message)'
... it asks me to add IFormatProvider formatProvider as parameter. What should I add there?
Dim theEvent = NLog.LogEventInfo.Create(NLog.LogLevel.Error, loggerName, ex, ???, message)
You can safely use null, one from the System.Globalization.CultureInfo members (a good guide can be found here) or create your own custom format provider depending on your needs.
The current implementation (as of v.4.1.2 on GitHub) will simply use CultureInfo.CurrentCulture if the FormatProvider property is null.
Related
I am trying to set up connection to the PowerBI service with the pyadomd library.
Here is the connection string:
"Provider=MSOLAP;Data Source=powerbi://api.powerbi.com/v1.0/myorg/workspace_name;User ID=user_email;Password=user_passw;Initial Catalog=dataset_name"
I get the error:
AdomdConnectionException: The connection string is not valid. ---> System.FormatException: Input string was not in a correct format.
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
at Microsoft.AnalysisServices.AdomdClient.XmlaClient.GetInstancePort(ConnectionInfo connectionInfo)
--- End of inner exception stack trace ---
at Microsoft.AnalysisServices.AdomdClient.XmlaClient.GetInstancePort(ConnectionInfo connectionInfo)
at Microsoft.AnalysisServices.AdomdClient.XmlaClient.GetTcpClient(ConnectionInfo connectionInfo)
at Microsoft.AnalysisServices.AdomdClient.XmlaClient.OpenTcpConnection(ConnectionInfo connectionInfo)
at Microsoft.AnalysisServices.AdomdClient.XmlaClient.OpenConnection(ConnectionInfo connectionInfo, Boolean& isSessionTokenNeeded)
at Microsoft.AnalysisServices.AdomdClient.XmlaClient.Connect(ConnectionInfo connectionInfo, Boolean beginSession)
at Microsoft.AnalysisServices.AdomdClient.AdomdConnection.XmlaClientProvider.Connect(Boolean toIXMLA)
at Microsoft.AnalysisServices.AdomdClient.AdomdConnection.ConnectToXMLA(Boolean createSession, Boolean isHTTP)
at Microsoft.AnalysisServices.AdomdClient.AdomdConnection.Open()
Does anyone know what is wrong?
I don't want to use the other library like "adodbapi" in this case as I have another unresolved error with it.
The documentation at Spotiy API_NET for ResumePlayback
gives the following example:
ErrorResponse error = _spotify.ResumePlayback(uris: new List<string> { "spotify:track:4iV5W9uYEdYUVa79Axb7Rh" });
When I try that code in C#, I get the following code error which prevents me building:
Error CS0121 The call is ambiguous between the following methods or properties: 'SpotifyWebAPI.ResumePlayback(string, string, List, int?)' and 'SpotifyWebAPI.ResumePlayback(string, string, List, string)'
Can anyone tell me what is wrong with this?
Also, what is the simplest way to simply resume the existing player at the point where it was paused?
Edit
#rene answered the first part of my question.
In regard to the second part, how to resume the existing player at the point where it was paused, I got the answer through the library's Github site, it's simply:
_spotify.ResumePlayback(offset: "")
The ResumePlayback method has two overloads that take these parameters:
ErrorResponse ResumePlayback(string deviceId = "",
string contextUri = "",
List<string> uris = null,
int? offset = null)
and
ErrorResponse ResumePlayback(string deviceId = "",
string contextUri = "",
List<string> uris = null,
string offset = "")
When the compiler comes across this line
ErrorResponse error = _spotify.ResumePlayback(
uris: new List<string> { "spotify:track:4iV5W9uYEdYUVa79Axb7Rh" });
it has to decide which ResumePlayback it is going to call and it doesn't want to take a guess or roll a dice.
It looks at which parameters are going to be provided and you only give it uris (that is the third parameter). It will assume the defaults for the other parameters. For both methods these defaults (null for strings or for the Nullable<int> (int?)) apply so the compiler can't decide which method it should bind to. It shows you an error.
Provide more parameters so the compiler can pick an unique overload.
ErrorResponse error = _spotify.ResumePlayback(
uris: new List<string> { "spotify:track:4iV5W9uYEdYUVa79Axb7Rh" }
,
offset: 0
);
Adding that named parameter offset and setting it to the int value of 0 is enough for the compiler to pick this overload to bind to:
ResumePlayback(string deviceId, string contextUri, List<string> uris, int? offset)
My groovy code is bellow:
String start
String startParam
String end
String endParam
String rule
Period period
String exDates
PeriodList expected = new PeriodList(true)
// init variables...
VEvent event = new ContentBuilder().vevent {
dtstart(start, parameters: parameters() { value(startParam) })
dtend(end, parameters: parameters() { value(endParam) })
rrule(rule)
exdate(exDates)
}
It works correctly in general, but if some of parameters were not defined with non null value I get an exception:
java.lang.RuntimeException: Failed to create component for 'exdate' reason: java.lang.reflect.InvocationTargetException
at groovy.util.FactoryBuilderSupport.createNode(FactoryBuilderSupport.java:719)
at groovy.util.FactoryBuilderSupport.dispatchNodeCall(FactoryBuilderSupport.java:855)
at groovy.util.FactoryBuilderSupport.doInvokeMethod(FactoryBuilderSupport.java:779)
at groovy.util.FactoryBuilderSupport.invokeMethod(FactoryBuilderSupport.java:499)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeOnDelegationObjects(ClosureMetaClass.java:423)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:346)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:909)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:66)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
at net.fortuna.ical4j.model.VEventRecurrenceParametrizedTest$_test_closure2.doCall(VEventRecurrenceTest.groovy:79)
Is it possible to protect the property call (ignore one if variable is null)? I checked documentation, there is null-safe-operator. How could I use one for this case for example?
exdate(exDates)
exdate should not be called if exDates is null.
if I try
exdate(this.?exDates)
it won't help because null safe operator will not protect method call if value is null, beside that this code exdate(this.?exDates) has compile error.
Just check for it being null or empty before making the call:
VEvent event = new ContentBuilder().vevent {
dtstart(start, parameters: parameters() { value(startParam) })
dtend(end, parameters: parameters() { value(endParam) })
rrule(rule)
if (exDates) exdate(exDates)
}
I'm using an Azure function to pick up messages from an event hub and send out notifications via the Azure notification hub. Works great! Now I wanted to see whether I could add tags to those messages in order to allow user targeting via those tags.
The output for the notification hub has a "tag expression" parameter which you can configure. But this seems to be a static text. I need to dynamically set these tags based on the message received from the event hub instead. I'm not sure whether you can somehow put dynamic content in there?
I also found that the constructor of the GcmNotification object that I'm using has an overload which allows a tag string to be used. But when I try that I get a warning on compile time stating this is deprecated and when the function fires it shows an error because the Tag property should be empty.
So I'm not clear on a) whether this is at all possible and b) how to do it when it is. Any ideas?
Update: as suggested I tried creating a POCO object to map to my input string. The string is as follows:
[{"deviceid":"repsaj-neptune-win10pi","readingtype":"temperature1","reading":22.031614503139451,"threshold":23.0,"time":"2016-06-22T09:38:54.1900000Z"}]
The POCO object:
public class RuleMessage
{
public string deviceid;
public string readingtype;
public object reading;
public double threshold;
public DateTime time;
}
For the function I now tried both RuleMessage[] and List<RuleMessage> as parameter types, but the function complains it cannot convert the input:
2016-06-24T18:25:16.830 Exception while executing function: Functions.submerged-function-ruleout. Microsoft.Azure.WebJobs.Host: Exception binding parameter 'inputMessage'. Microsoft.Azure.WebJobs.Host: Binding parameters to complex objects (such as 'RuleMessage') uses Json.NET serialization.
1. Bind the parameter type as 'string' instead of 'RuleMessage' to get the raw values and avoid JSON deserialization, or
2. Change the queue payload to be valid json. The JSON parser failed: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Submission#0+RuleMessage' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Function code:
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Microsoft.Azure.NotificationHubs;
public static void Run(List<RuleMessage> inputEventMessage, string inputBlob, out Notification notification, out string outputBlob, TraceWriter log)
{
if (inputEventMessage == null || inputEventMessage.Count != 1)
{
log.Info($"The inputEventMessage array was null or didn't contain exactly one item.");
notification = null;
outputBlob = inputBlob;
return;
}
log.Info($"C# Event Hub trigger function processed a message: {inputEventMessage[0]}");
if (String.IsNullOrEmpty(inputBlob))
inputBlob = DateTime.MinValue.ToString();
DateTime lastEvent = DateTime.Parse(inputBlob);
TimeSpan duration = DateTime.Now - lastEvent;
if (duration.TotalMinutes >= 0) {
notification = GetGcmMessage(inputMessage.First());
log.Info($"Sending notification message: {notification.Body}");
outputBlob = DateTime.Now.ToString();
}
else {
log.Info($"Not sending notification message because of timer ({(int)duration.TotalMinutes} minutes ago).");
notification = null;
outputBlob = inputBlob;
}
}
private static Notification GetGcmMessage(RuleMessage input)
{
string message;
if (input.readingtype == "leakage")
message = String.Format("[FUNCTION GCM] Leakage detected! Sensor {0} has detected a possible leak.", input.reading);
else
message = String.Format("[FUNCTION GCM] Sensor {0} is reading {1:0.0}, threshold is {2:0.0}.", input.readingtype, input.reading, input.threshold);
message = "{\"data\":{\"message\":\""+message+"\"}}";
return new GcmNotification(message);
}
public class RuleMessage
{
public string deviceid;
public string readingtype;
public object reading;
public double threshold;
public DateTime time;
}
Update 28-6-2016: I've not managed to get it working by switching ASA output to line seperated to that it doesn't generate a JSON array any more. This is a temp. fix because the Function binding now fails as soon as there is more than one line in the output (which can happen).
Anyways, I now proceeded to set the tagExpression, as per instruction I changed it to:
{
"type": "notificationHub",
"name": "notification",
"hubName": "repsaj-neptune-notifications",
"connection": "repsaj-neptune-notifications_NOTIFICATIONHUB",
"direction": "out",
"tagExpression": "deviceId:{deviceid}"
}
Where {deviceid} equals the deviceid property on my RuleMessage POCO. Unfortunately this doesn't work, when I call the function it outputs:
Exception while executing function: Functions.submerged-function-ruleout. Microsoft.Azure.WebJobs.Host: Exception binding parameter 'notification'. Microsoft.Azure.WebJobs.Host: No value for named parameter 'deviceid'.
Which is not true, I know for sure the property has been set as I've logged it to the ouput window. I also tried something like {inputEventMessage.deviceid}, but that doesn't work either (as I didn't get how the runtime would map {deviceid} to the correct input object when there's more than one.
The tagExpression binding property supports binding parameters coming from trigger input properties. For example, assume your incoming Event Hub event has properties A and B. You can use these properties in your tagExpression using the parens syntax, e.g.: My Tag {A}-{B}.
In general, most of the properties across all the binding types support binding parameters in this way.
I'm getting an exception when I run a unit test on a controller in web project (ASP.NET web api). The exception is thrown when LogManager.GetCurrentClassLogger() of the controller is executed:
System.MethodAccessException: Attempt by method 'Castle.Proxies.ClaimsPrincipalProxy.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)' to access method 'Castle.DynamicProxy.Internal.TypeUtil.Sort(System.Reflection.MemberInfo[])' failed
It results in TypeInitializationException in LogManager.GetCurrentClassLogger().
here is the call stack:
at Castle.Proxies.ClaimsPrincipalProxy.GetObjectData(SerializationInfo, StreamingContext)
at System.Runtime.Serialization.ObjectCloneHelper.GetObjectData(Object serObj, String& typeName, String& assemName, String[]& fieldNames, Object[]& fieldValues)
at System.AppDomain.get_Evidence()
at System.AppDomain.get_Evidence()
at System.Configuration.ClientConfigPaths.GetEvidenceInfo(AppDomain appDomain, String exePath, ref String typeName)
at System.Configuration.ClientConfigPaths.GetTypeAndHashSuffix(AppDomain appDomain, String exePath)
at System.Configuration.ClientConfigPaths..ctor(String exePath, Boolean includeUserConfig)
at System.Configuration.ClientConfigPaths.GetPaths(String exePath, Boolean includeUserConfig)
at System.Configuration.ClientConfigurationHost.RequireCompleteInit(IInternalConfigRecord record)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, ref Object result, ref Object resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
at System.Configuration.ConfigurationManager.GetSection(String sectionName)
at NLog.Config.XmlLoggingConfiguration.get_AppConfig()
at NLog.LogFactory.get_Configuration()
at NLog.LogFactory.GetLogger(LoggerCacheKey cacheKey)
at NLog.LogFactory.GetLogger(String name)
at NLog.LogManager.GetCurrentClassLogger()
Update:
The issue happens when the unit test project references NSubstitute. So, it seems like there some dangerous combination of Web API, NSubstitute and NLog.
Update 2:
Found what upsets Nlog in Controller.
Before calling controller method I set mocked principal for Thread.CurrentPrincipal:
var principal = Substitute.For<ClaimsPrincipal>();
principal.Identity.Returns(...);
Thread.CurrentPrincipal = principal;
How could this be fixed?
The Castle assembly may be marked with the AllowPartiallyTrustedCallersAttribute, and that uses the level 2 security transparency model.
Level 2 transparency causes all methods in AllowPartiallyTrustedCallers assemblies to become security transparent by default, which may be the cause of this exception.
Can you try annotating your unit test (and Class) with the following attribute - [SecuritySafeCritical]