ua-parser / uap-csharp Goto Github PK
View Code? Open in Web Editor NEWC# implementation of ua-parser
License: Other
C# implementation of ua-parser
License: Other
Hello,
could you please add support for .NET core 2.0?
Changes to the submodule mean that the build it broken. Can you please re-run the build on the build server to confirm?
Is it possible to add a new field on the Device to indicate the type of device?
e.g. phone, table, desktop
Like this project does?
https://github.com/faisalman/ua-parser-js
Hello!
I've been working with UAParser NuGet package, but it seems not up-to-date when we compare with the latest uap-core. Basically, it's missing Windows 10. (detected as "Windows")
Is it possible to push the latest version to NuGet?
I did rebuild locally and it seems fine when we simply pull the yaml file.
Thanks :)
Matt
First thanks for the work! We are planning to use uap-csharp in Microsoft Cosmos's SCOPE, which has an early version .NET framework support (maybe 2.0 or even earlier). I found this code has used delegate like Func
return type, which is not supported by .NET framework 2.0 (see: https://docs.microsoft.com/en-us/dotnet/api/system.func-1?view=netframework-4.8#applies-to).
I don't know if such usage is necessary, however, I saw the uap-cpp (C++ version) and it doesn't use any such features. Can we refactor the code to remove those advanced features to make it support .NET framework 2.0 and earlier? Thanks.
Seems like your library takes a pointed opinion about what specific flavors of the .net ecosystem you do / don't want to support.
Is there a compelling reason you haven't targeted net452, net46, net461, net47, net471 in your .csproj?
Accounting to the Microsoft dotnet open-source library guide here
✔️ DO start with including a netstandard2.0 target.
Most general-purpose libraries should not need APIs outside of .NET Standard 2.0. .NET Standard 2.0 is supported by all modern platforms and is the recommended way to support multiple platforms with one target.
❌ AVOID including a netstandard1.x target.
.NET Standard 1.x is distributed as a granular set of NuGet packages, which creates a large package dependency graph and results in developers downloading a lot of packages when building. Modern .NET platforms, including .NET Framework 4.6.1, UWP and Xamarin, all support .NET Standard 2.0. You should only target .NET Standard 1.x if you specifically need to target an older platform.
✔️ DO include a netstandard2.0 target if you require a netstandard1.x target.
All platforms supporting .NET Standard 2.0 will use the netstandard2.0 target and benefit from having a smaller package graph while older platforms will still work and fall back to using the netstandard1.x target.
I checkout code on my local PC and opened in visual studio, file regexes.yaml is missing.
When i parse any Windows UA-string, i only get the Family field set, never any of the others.
When i look at www.whatsmyua.com, which uses the JS version, the version field is set as well.
Why is this?
Edge Chromium is currently showing up as Chrome. Would it be possible to add detection for it?
We are using the UAParser in my office to parse the user agent, and log browser, device, and OS information. However, when we added this to our system, we saw our CPU double. My suspicion is that this is because the regexes are not precompiled at startup. Could someone more familiar with the repo confirm?
.
really means [^\r\n]
or something similar to that. Executing that surely is more expensive.Are you interested in a pull request?
Related: #16
I installed the package on the .net core and has received other for os and browser and other properties
In uap-csharp there is the following comment:
// TODO: potentially allow parser to specify e.g. to use
// compiled regular expressions which are faster but increase
// startup time
return new Regex(pattern);
I found significant performance gains when changing this to
return new Regex(pattern, RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.Singleline);
I believe that Compiled
is responsible for the gains. I don't see why UA parsign should be culture-dependent so I added CultureInvariant
. Also, do any of the regular expressions depend on newline behavior (which means that .
does or does not match '\n')? I don't think so. Using Singleline
is faster because it speeds up the .
pattern element.
I request that RegexOptions.CultureInvariant | RegexOptions.Singleline
are always enabled and that Compiled
is either enabled as an option or always enabled. I have not measured startup time deterioration. If this is not highly significant, compiled expressions should be the default.
Thanks for providing such a useful library!
The ClientInfo class looks to have properties that hold the same values:
Are they both required or can 1 of these be removed to avoid confusion?
The JS version exposes the engine info as well. Any plan to implement this as well?
This is really odd, as it appears that uap-core is passing.
Maybe I'm doing something really dumb, but it would be so helpful if someone could check if it's just a problem with my own environment.
Using VS2017 and the latest version of uap-csharp and uap-core.
Failed tests: testcase 237: Major did not match. (expected:NT actual:$1) in Mozilla/5.0 (Windows U; Win NT 5.0; en-US; rv:1.8.0.2) Gecko/20060308 Firefox/1.5.0.2 testcase 238: Major did not match. (expected:NT actual:$1) in Mozilla/5.0 (Windows; N; WinNT; en-US; m14) Netscape6/6.0b1,gzip(gfe),gzip(gfe),gzip(gfe) testcase 242: Major did not match. (expected:3.1 actual:$1) in Mozilla/5.0 (Windows; U; Win3.1; en-US; rv:1.0.0) Gecko/20020530 testcase 243: Major did not match. (expected:3.1 actual:$1) in Mozilla/5.0 (Windows; U; Win3.11; en-US; rv:21.56.11.90) Gecko/20500230 Firefox/3.5 testcase 245: Major did not match. (expected:95 actual:$1) in Mozilla/5.0 (Windows; U; Win95; en-GB; rv:1.0.1) Gecko/20020823 Netscape/7.0 testcase 246: Major did not match. (expected:95 actual:$1) in Mozilla/5.0 (Windows; U; Win95; en-GB; rv:1.8.0.8) Gecko/20061025 Firefox/1.5.0.8 testcase 340: Major did not match. (expected:8.1 actual:$1) in Box Sync/4.0.7848;Windows/8.1;x86 Family 6 Model 158 Stepping 9, GenuineIntel/32bit testcase 341: Major did not match. (expected:10 actual:$1) in Box Sync/4.0.7848;Windows/10;Intel64 Family 6 Model 158 Stepping 9, GenuineIntel/64bit testcase 344: Major did not match. (expected:10 actual:$1) in Box/1.2.93;Windows/10;Intel64 Family 6 Model 158 Stepping 9, GenuineIntel/64bit
I noticed that part of the UserAgent generated by safari on the iPhone does not contain the version information of safari, so the version information of safari cannot be obtained during the parsing process. However, these UserAgents generally contain the version information of iPhone OS. I learned that because safari is a part of iOS, the version of safari is always the same as the version of iOS. Can we fill in the version information of safari by obtaining the version information of iOS when the version information of safari cannot be obtained directly?
E.g:Mozilla/5.0 (iPad; CPU OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 musical_ly_18.6.6 JsSdk/2.0 NetType/WIFI Channel/App Store ByteLocale/en Region/CH RevealType/Dialog isDarkMode/1 Safari/604.1 WKWebView/1
This UA character does not contain the version information of safari, but it does contain the version information of iOS. We can try to use the version information of iOS to fill in the version information of safari. From this we can know that this UA character comes from safari 14.4
Hi,
First, thank you for the work you put in providing this library.
Looking into the code I see that when creating the regexes there is no matchTimeout
parameter passed to the constructor. This means that in case of catastrophic backtracking there is no guarantee for the client of the library that the call will terminate (in a reasonable time). The recommended way to prevent this is to use the matchTimeout
parameter of the Regex constructor.
matchTimeout
?Thanks,
Frederic Jardon
Is there a way to get the device type? Like mobile
/tablet
/desktop
or something like that?
My goal is to understand if the client is a mobile phone.
Thanks.
There is no change log or updated read me with usages.. Even bigger you guys seem to have gotten rid of info.Device.IsSpider
Where has this moved to?
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.43
The family is reported as chrome instead of edge
Using the latest uap-core ua-parser/uap-core@eb8cf22
Trying to parse Menucast/1.52 CFNetwork/720.5.7 Darwin/14.5.0 (x86_64)
causes a null reference exception
Code
var parser = Parser.FromYaml(...);
var result = parser.Parse("Menucast/1.52 CFNetwork/720.5.7 Darwin/14.5.0 (x86_64)");
Exception
System.NullReferenceException : Object reference not set to an instance of an object.
at UAParser.Parser.Parsers.<Device>b__23(<>f__AnonymousType3`2 <>h__TransparentIdentifier1e, String model)
at UAParser.RegexBinderBuilder.<>c__DisplayClass1`3.<SelectMany>b__0(Match m, IEnumerator`1 num)
at UAParser.Parser.Parsers.<>c__DisplayClass48`1.<Create>b__46(String input)
at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
at UAParser.Parser.<>c__DisplayClass7`2.<CreateParser>b__4(String ua)
at UAParser.Parser.Parse(String uaString)
I'm not sure if this is the right place to ask this question since it affects multiple implementations, including this. I cross-posted to the uap-core project but sharing here just in case it is a bug with the specific implementation.
There are certain user-agents where it is not possible to derive or infer the device family, brand or model from the user-agent alone.
In our application, we want to explicitly distinguish between user-agents we recognise but we don't know of the device family (which we want to output as an empty string), and user-agents we don't recognise (fallback to the "Other" value as defined in the specification).
We've observed a difference between the uap-ref-impl
Javascript and uap-csharp
C# implementations of ua-parser.
Even though the Javascript is described as the "reference" implementation, we're not sure if this is a bug or the intention of the specification since it is vague about how to handle a replacement value that is an empty string ""
.
The specification writes,
In case that no replacement for a match is given, the first match defines the family and the model. If a *_replacement string is specified it shall overwrite or replace the match.
One could interpret "no replacement" to mean either
undefined
or null
undefined
or null
or empty stringThe regex YAML is defined as
device_parsers:
- regex: '(radiocomandroid)'
brand_replacement: ''
device_replacement: ''
model_replacement: ''
Testing with the user-agent string of radiocomandroid
The Javascript implementation outputs
{
"family": "radiocomandroid",
"brand": null,
"model": "radiocomandroid"
}
The C# implementation outputs
{
"IsSpider": false,
"Brand": "",
"Family": "",
"Model": ""
}
Side-by-side
Javascript | .NET | |
---|---|---|
Device family | "radiocomandroid" |
"" |
Device brand | null |
"" |
Device model | "radiocomandroid" |
"" |
The JavaScript implementation uses a conditional (ternary) operator which will treat an empty string ""
as false, which means it will fallback to the first match value.
The C# implementation uses a == null
condition which will use an empty string ""
as the final value.
https://github.com/ua-parser/uap-csharp/blob/master/UAParser/UAParser.cs#L523
Which of these implementations is the intent of the specification? Is an empty string considered "no replacement"?
Is uaparser thread safe?
Can I store the instance in static field?
For example:
private static readonly Parser UaParser = Parser.GetDefault();
Statement in usage section
Client c = uaParser.Parse(uaString);
should be
ClientInfo c = uaParser.Parse(uaString);
because When installed package (UAParser) through nuget this code doesn't work and after this edit it worked.
one more thing authors' githib links are not valid is missing : after http
Hello,
Where is the *.yaml files? I can't build projects in solution.
We would be very grateful if we could have a NuGet release targeting .NET Standard 2.0? Any chance?
On building the latest version, the following error now occurs:
error MSB4041: The default XML namespace of the project must be the MSBuild XML namespace. If the project is authored in the MSBuild 2003 format, please add xmlns="
http://schemas.microsoft.com/developer/msbuild/2003" to the element. If the project has been authored in the
old 1.0 or 1.2 format, please convert it to MSBuild 2003 format.
This occurs when running from Build.bat.
I believe this is due to changes to the .csproj file. I'm running visual studio 2015.
For the following user agent string sent using Chrome on a Pixel 3 XL the device family is returning "Generic Smartphone"
Mozilla/5.0 (Linux; Android 9; Pixel 3 XL) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.89 Mobile Safari/537.36
Last commit is over a year ago, no one watch issue, no on watch pull request.
I tried to contact the authors in many ways, but they don't answer,
You can still use this library forking this project and loading updated yaml files, but there are a lot of architecture issue that no one will ever be interested to handle.
A yaml database of user agent is not enough in any case to handle correctly the great amount and diversity of devices that access to web today.
If you want a good User Agent parser the only solution is to move forward, but what library use?
I searched a lot a library able to replace us-parser, I found some good Javascript libraries but they can't replace the job of a server side parser.
The only solution that I found to use now a good user agent parser is to depend on a cloud service, but they are not good, for several reasons:
So after a lot of search I found this awesome Server Side library: https://github.com/nielsbasjes/yauaa
The problems is that library is written in Java, so I decided to create a .NET porting: https://github.com/OrbintSoft/yauaa.netstandard
A lot of work is still needed to make this porting working, but the project is active, and if you contribute soon we can have our awesome .NET user agent parser and I plan to release our .nuget package.
Thank you
I want my application's and libraries to be as small as possible and the minimum amount of dependencies.
Additional dependencies are being added to my projects.
When the framework is able to natively provide a dependency ie System.* that should be utilised rather than an explicit dependency. This will be the case for the net standard 2.1
Accept the additional dependencies
No response
Even though this is included in regexes.yaml, ua-parser can't detect Chrome for IOS:
- regex: '(CriOS)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
family_replacement: 'Chrome Mobile iOS'
Here is the user agent string for Chrome on ios:
Mozilla/5.0(iPad; CPU OS 9_2_1 like Mac OS X) AppleWebKit/601.1(KHTML, like Gecko) Crios/55.0.2883.79 Mobile/13D15 Safari/601.1.46
Hello,
I would like to get the type of a device as seen in the official documentation:
Possible 'device.type':
console, mobile, tablet, smarttv, wearable, embedded
How to get the type of a device with uap-csharp?
Thanks
I have this user agent string
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
this should be parsed device as 'Mac' and
Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36 OPR/24.0.1558.61
this should be parsed device as 'PC' but it parsing as 'Other'. Is it OK or bug? because I require device PC and Mac also.
I’ve encountered a significant performance issue with UAParser when it’s used in a logger. The issue arises when Parser.GetDefault() is called repeatedly during large operations. Each call to the logger creates a new instance of the Parser, which leads to a significant performance penalty.
Here’s a simplified test case that demonstrates the issue:
C#
using System;
using System.Diagnostics;
using UAParser;
class Program
{
const int NumTests = 100;
static void Main()
{
string userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3";
var stopwatch = Stopwatch.StartNew();
for (int i = 0; i < NumTests; i++)
{
var parser = Parser.GetDefault();
var clientInfo = parser.Parse(userAgent);
}
stopwatch.Stop();
Console.WriteLine($"Test Case 1 elapsed time: {stopwatch.ElapsedMilliseconds} ms");
stopwatch.Restart();
var parserOutsideLoop = Parser.GetDefault();
for (int i = 0; i < NumTests; i++)
{
var clientInfo = parserOutsideLoop.Parse(userAgent);
}
stopwatch.Stop();
Console.WriteLine($"Test Case 2 elapsed time: {stopwatch.ElapsedMilliseconds} ms");
}
}
In Test Case 1, Parser.GetDefault() is called 100 times, leading to a total elapsed time of 4046 ms. In Test Case 2, Parser.GetDefault() is called only once, and the same instance is used for all iterations of the loop, resulting in a total elapsed time of 190 ms.
Test Case 1 elapsed time: 4046 ms
Test Case 2 elapsed time: 190 ms
This demonstrates that the time taken to instantiate the Parser object with Parser.GetDefault() is quite significant. It seems that the regex patterns are loaded from the assembly each time Parser.GetDefault() is called.
The actual fix was to instantiate the Parser as a member variable of the logger class, so it’s created only once and reused for all subsequent calls to the logger.
I couldn’t find any explicit warnings or notes about this in the UAParser documentation. It would be helpful if the documentation could provide some guidance or warning about this so others don't repeat the same bug.
With windows 8.1 ParseOS returns:
family: "Windows 8.1" instead of "Windows"
major: null
minor: null
patch:null
ParseUserAgent returns "Other" instead of Windows
Hi,
Will there be support for layout engine?
Thanks.
If device in user agent string has parentheses, then device model and family are cut by closing parenthesis
Examples:
"Dalvik/2.1.0 (Linux; U; Android 8.0.0; moto g(6) play Build/OPPS27.91-177-2)" - Device="moto g(6"
"Dalvik/2.1.0 (Linux; U; Android 8.1.0; LM-X210(G) Build/OPM1.171019.026)" - Device="LM-X210(G"
"Dalvik/2.1.0 (Linux; U; Android 8.1.0; LM-Q610(FGN) Build/OPM1.171019.019)" - Device="LM-Q610(FGN"
Are you planing to port the lib to .net core?
Android 9 userAgentStrings aren't able to parse the version codes. Below is an example of a string that doesn't work:
Mozilla/5.0 (Linux; Android 9; Pixel XL Build/PPP5.180610.010; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/68.0.3440.85 Mobile Safari/537.36
However, it does work if I modify the string to be:
Mozilla/5.0 (Linux; Android 9.0; Pixel XL Build/PPP5.180610.010; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/68.0.3440.85 Mobile Safari/537.36
Package version 3.1.40
Steps to reproduce:
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var items = new List<int>().FirstOrDefault();
}
}
}
error CS0121: The call is ambiguous between the following methods or properties: 'System.Linq.Enumerable.FirstOrDefault(System.Collections.Generic.IEnumerable)' and 'System.Linq.Enumerable.FirstOrDefault(System.Collections.Generic.IEnumerable)'
Exactly same issue occurs when targeting .net 4.7.2 or other frameworks with embedded Linq support.
Please, consider adding "net35" target platform without LinqBridge in addition to netstandard`s so that NuGet can select it instead of net20
I found something in the source code, not sure if it's a bug, it seemed the last one should be $9
other than $91
?
uap-csharp/UAParser/UAParser.cs
Lines 516 to 519 in 809de48
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.