I'm using Visual Studio 2015 to develop a website using web forms and Visual Basic. My problem is the error BC36645 has occured, preventing me from building the solution. It is described as "Data type(s) of the type parameter(s) in method 'Public Shared Overloads Function FromResult(Of TResult)(result As TResult) As Task(Of TResult)' cannot be inferred from these arguments. Specifying the data type(s) explicitly might correct this error."
Which I understand the basic meaning of. However, it's stated to be in a file that I have not touched, it's autogenerated. The file is IdentityModels.vb located in the Models folder.
I got the same error in another project in the same solution, which I solved by deleting, re-creating the project and rebuilding. But this is not really a convenient way to solve the problem.
Does someone have the same problem, can explain what it is about, or even have a proper solution?
//Eva-Lotta
EDIT:
This is the contents of the file the error points to (with the error in " Return Task.FromResult(GenerateUserIdentity(manager))":
Imports System
Imports System.Threading.Tasks
Imports System.Security.Claims
Imports Microsoft.AspNet.Identity
Imports Microsoft.AspNet.Identity.EntityFramework
Imports Microsoft.AspNet.Identity.Owin
Imports Microsoft.Owin.Security
Public Class ApplicationUser
Inherits IdentityUser
Public Function GenerateUserIdentity(manager As ApplicationUserManager) As
Dim userIdentity = manager.CreateIdentity(Me, DefaultAuthenticationTypes.ApplicationCookie)
Return userIdentity
End Function
Public Function GenerateUserIdentityAsync(manager As ApplicationUserManager)
As Task(Of ClaimsIdentity)
Return Task.FromResult(GenerateUserIdentity(manager))
End Function
End Class
Public Class ApplicationDbContext
Inherits IdentityDbContext(Of ApplicationUser)
Public Sub New()
MyBase.New("DefaultConnection", throwIfV1Schema:=False)
End Sub
Public Shared Function Create As ApplicationDbContext
Return New ApplicationDbContext()
End Function
End Class
#Region "Helpers"
Public Class
Public Const XsrfKey As String = "xsrfKey"
Public Const ProviderNameKey As String = "providerName"
Public Shared Function GetProviderNameFromRequest(request As HttpRequest) As String
Return request.QueryString(ProviderNameKey)
End Function
Public Const CodeKey As String = "code"
Public Shared Function GetCodeFromRequest(request As HttpRequest) As String
Return request.QueryString(CodeKey)
End Function
Public Const UserIdKey As String = "userId"
Public Shared Function GetUserIdFromRequest(request As HttpRequest) As String
Return HttpUtility.UrlDecode(request.QueryString(UserIdKey))
End Function
Public Shared Function GetResetPasswordRedirectUrl(code As String, request As HttpRequest) As String
Dim absoluteUri = "/Account/ResetPassword?" + CodeKey + "=" + HttpUtility.UrlEncode(code)
Return New Uri(request.Url, absoluteUri).AbsoluteUri.ToString()
End Function
Public Shared Function GetUserConfirmationRedirectUrl(code As String, userId As String, request As HttpRequest) As String
Dim absoluteUri = "/Account/Confirm?" + CodeKey + "=" + HttpUtility.UrlEncode(code) + "&" + UserIdKey + "=" + HttpUtility.UrlEncode(userId)
Return New Uri(request.Url, absoluteUri).AbsoluteUri.ToString()
End Function
Private Shared Function IsLocalUrl(url As String) As Boolean
Return Not String.IsNullOrEmpty(url) AndAlso ((url(0) = "/"c AndAlso (url.Length = 1 OrElse (url(1) <> "/"c AndAlso url(1) <> "\"c))) OrElse (url.Length > 1 AndAlso url(0) = "~"c AndAlso url(1) = "/"c))
End Function
Public Shared Sub RedirectToReturnUrl(returnUrl As String, response As HttpResponse)
If Not [String].IsNullOrEmpty(returnUrl) AndAlso IsLocalUrl(returnUrl) Then
response.Redirect(returnUrl)
Else
response.Redirect("~/")
End If
End Sub
End Class
#End Region
To resolve this error You may be able to specify a data type for the type parameter or parameters instead of relying on type inference.
Related
I have the next Code in EF Core 3.1 in language VB.NET
Dim supplierID as string="1545464"
Dim results = (From pa In DC.product.AsNoTracking()
Where pa.supplierID = supplierID
Select pa)
The exception throw is:
The LINQ expression 'DbSet<product>
.Where(p => Operators.CompareString(
Left: p.supplierID,
Right: __$VB$Local_supplierID_0,
TextCompare: False) == 0)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync().
I found the following solution:
Dim supplierID as string="1545464"
Dim results = (From pa In DC.product.AsNoTracking()
Where pa.supplierID.Equals(supplierID)
Select pa)
Is my solution correct, using .Equals()? In C# language if it works with the operator "=="
I have created a small solution with which you can reproduce the error.
The solution has 4 projects:
Sup.Entities (C#)
Sup.DAL (C#)
Sup.ConsoleApp1 (C#)
Sup.consoleAppVB (VB.NET)
This is the error that occurs in Sup.ConsoleAppVB (VB.NET)
This is the result in Sup.ConsoleApp1 (C#)
Attached solution Download that includes projects and an SQL file to create the database and 1 table with 3 rows.
Please change connectionstring for UseSqlServer("...") in OnConfiguring Context
I just ran into this issue but since I have developed my own LINQ to SQL evaluator before I knew how to solve the problem. VB.NET transforms the = operator for strings into a call to Microsoft.VisualBasic.CompilerServices.Operators.CompareString(). So when the expression tree is evaluated this method must be handled. I suspect the reason for this is because VB handles string comparisons to null ((text = Nothing) = True).
I didn't download your sample but I fixed it in an ASP.NET Core application.
If you were using LINQ, this would be handled inside an ExpressionVisitor but for Entity Framework Core 3.1, I found that you can implement an IMethodCallTranslator.
However, Entity Framework uses SqlExpression expressions so an ISqlExpressionFactory is needed to create them. Fortunately, dependency injection can be used to get an implementation from IServiceCollection.
Public Class VbCompareStringMethodCallTranslator : Implements IMethodCallTranslator
Private mExpressionFactory As ISqlExpressionFactory
Public Sub New(expressionFactory As ISqlExpressionFactory)
Me.mExpressionFactory = expressionFactory
End Sub
Public Function Translate(instance As SqlExpression, method As MethodInfo, arguments As IReadOnlyList(Of SqlExpression)) As SqlExpression Implements IMethodCallTranslator.Translate
If method IsNot Nothing Then
If method.Name = "CompareString" AndAlso method.DeclaringType?.Name = "Operators" AndAlso
method.DeclaringType?.Namespace = "Microsoft.VisualBasic.CompilerServices" Then
Dim left = arguments(0)
Dim right = arguments(1)
If method.Name Is NameOf(String.Compare) AndAlso arguments.Count = 2 AndAlso
arguments(0).Type.UnwrapNullableType Is arguments(1).Type.UnwrapNullableType Then
left = arguments(0)
right = arguments(1)
ElseIf method.Name Is NameOf(String.CompareTo) AndAlso arguments.Count = 1 AndAlso
instance IsNot Nothing AndAlso instance.Type.UnwrapNullableType Is arguments(0).Type.UnwrapNullableType Then
left = instance
right = arguments(0)
End If
If left IsNot Nothing AndAlso right IsNot Nothing Then
Return Me.mExpressionFactory.[Case]({New CaseWhenClause(Me.mExpressionFactory.Equal(left, right), Me.mExpressionFactory.Constant(0)),
New CaseWhenClause(Me.mExpressionFactory.GreaterThan(left, right), Me.mExpressionFactory.Constant(1)),
New CaseWhenClause(Me.mExpressionFactory.LessThan(left, right), Me.mExpressionFactory.Constant(-1))},
Nothing)
End If
End If
End If
Return Nothing
End Function
End Class
Making use of the following extension method
Public Module SharedTypeExtensions
<Extension()>
Public Function UnwrapNullableType(type As Type) As Type
Return If(Nullable.GetUnderlyingType(type), type)
End Function
End Module
You can see that this is the code used by Entity Framework to handle string comparisons here https://github.com/dotnet/efcore/blob/3656e9daa9b81398d8c065a702fd5dca91979f49/src/EFCore.Relational/Query/Internal/ComparisonTranslator.cs
So now this needs to be hooked up and the following plumbing code can be used
Public Class VbMethodCallTranslatorPlugin : Implements IMethodCallTranslatorPlugin
Public Sub New(expressionFactory As ISqlExpressionFactory)
Me.Translators = {New VbCompareStringMethodCallTranslator(expressionFactory)}
End Sub
Public ReadOnly Property Translators As IEnumerable(Of IMethodCallTranslator) Implements IMethodCallTranslatorPlugin.Translators
End Class
Public Class VbDbContextOptionsExtension : Implements IDbContextOptionsExtension
Public Sub ApplyServices(services As IServiceCollection) Implements IDbContextOptionsExtension.ApplyServices
services.AddSingleton(Of IMethodCallTranslatorPlugin, VbMethodCallTranslatorPlugin)
End Sub
Public Sub Validate(options As IDbContextOptions) Implements IDbContextOptionsExtension.Validate
End Sub
Public ReadOnly Property Info As DbContextOptionsExtensionInfo Implements IDbContextOptionsExtension.Info
Get
Return New VbDbContextOptionsExtensionInfo(Me)
End Get
End Property
End Class
Public Class VbDbContextOptionsExtensionInfo : Inherits DbContextOptionsExtensionInfo
Public Sub New(extension As IDbContextOptionsExtension)
MyBase.New(extension)
End Sub
Public Overrides Function GetServiceProviderHashCode() As Long
Return Me.Extension.GetHashCode
End Function
Public Overrides Sub PopulateDebugInfo(<NotNullAttribute> debugInfo As IDictionary(Of String, String))
debugInfo("VB:TranslateMethods") = True.ToString
End Sub
Public Overrides ReadOnly Property IsDatabaseProvider As Boolean
Get
Return False
End Get
End Property
Public Overrides ReadOnly Property LogFragment As String
Get
Return "VbMethodSupport=true"
End Get
End Property
End Class
Now this can hooked up using the DbContextOptionsBuilder, but the following extension method will make this easier
Public Module VbDbContextOptionsBuilderExtensions
<Extension>
Public Function AddVbSupport(optionsBuilder As DbContextOptionsBuilder) As DbContextOptionsBuilder
Dim builder = CType(optionsBuilder, IDbContextOptionsBuilderInfrastructure)
Dim extension = If(optionsBuilder.Options.FindExtension(Of VbDbContextOptionsExtension), New VbDbContextOptionsExtension)
builder.AddOrUpdateExtension(extension)
Return optionsBuilder
End Function
End Module
Now you can hook this up while setting up your DbContext
services.AddDbContext(Of ApplicationDbContext)(Sub(options)
options.UseSqlServer(Me.Configuration.GetConnectionString("ConnectionString"),
Sub(dbOptions)
dbOptions.MigrationsAssembly("Database.Migrations")
End Sub)
options.AddVbSupport
End Sub)
Additional Info
This appears to be a bug in Entity Framework rather than VB.NET just not being supported. You can find this code in the dotnet efcore repository.
https://github.com/dotnet/efcore/blob/7cb52b388a2d9fd8f9c2c499ef3ffb9753d9932a/src/EFCore/Query/Internal/QueryOptimizingExpressionVisitor.cs#L113-L132
I submitted a bug report here
https://github.com/dotnet/efcore/issues/20889
Vote it up so the devs will fix the issue!
Update 1
Looks like this will be fixed in .NET 5
Update 2
The above solution was causing issues after refreshing the page a bunch of times. I would get an error something to the effect of "more than 20 IService instances have been created"
In order to fix this I just added the expression transform into a different part of the pipeline.
Imports System.Linq.Expressions
Imports System.Runtime.CompilerServices
Imports Microsoft.EntityFrameworkCore
Imports Microsoft.EntityFrameworkCore.Query
Public Class VbRelationalQueryTranslationPreprocessorFactory : Implements IQueryTranslationPreprocessorFactory
Private ReadOnly mDependencies As QueryTranslationPreprocessorDependencies
Private ReadOnly mRelationalDependencies As RelationalQueryTranslationPreprocessorDependencies
Public Sub New(dependencies As QueryTranslationPreprocessorDependencies, relationalDependencies As RelationalQueryTranslationPreprocessorDependencies)
Me.mDependencies = dependencies
Me.mRelationalDependencies = relationalDependencies
End Sub
Public Overridable Function Create(queryCompilationContext As QueryCompilationContext) As QueryTranslationPreprocessor Implements IQueryTranslationPreprocessorFactory.Create
Return New VbRelationalQueryTranslationPreprocessor(Me.mDependencies, Me.mRelationalDependencies, queryCompilationContext)
End Function
End Class
Public Class VbRelationalQueryTranslationPreprocessor : Inherits RelationalQueryTranslationPreprocessor
Public Sub New(dependencies As QueryTranslationPreprocessorDependencies, relationalDependencies As RelationalQueryTranslationPreprocessorDependencies, queryCompilationContext As QueryCompilationContext)
MyBase.New(dependencies, relationalDependencies, queryCompilationContext)
End Sub
Public Overrides Function Process(query As Expression) As Expression
query = New LanguageNormalizingExpressionVisitor().Visit(query)
Return MyBase.Process(query)
End Function
End Class
Public Class LanguageNormalizingExpressionVisitor : Inherits ExpressionVisitor
Protected Overrides Function VisitBinary(node As BinaryExpression) As Expression
Dim methodCall = TryCast(node.Left, MethodCallExpression)
If methodCall IsNot Nothing Then
' Replace calls to comparestring with a binary equals on the operands
If methodCall.Method.Name = "CompareString" AndAlso methodCall.Method.DeclaringType?.Name = "Operators" AndAlso methodCall.Method.DeclaringType?.Namespace = "Microsoft.VisualBasic.CompilerServices" Then
Dim left = Me.Visit(methodCall.Arguments(0))
Dim right = Me.Visit(methodCall.Arguments(1))
Return Expression.MakeBinary(node.NodeType, left, right)
End If
End If
Return MyBase.VisitBinary(node)
End Function
End Class
Public Module VbDbContextOptionsBuilderExtensions
<Extension>
Public Function AddVbSupport(optionsBuilder As DbContextOptionsBuilder) As DbContextOptionsBuilder
optionsBuilder.ReplaceService(Of IQueryTranslationPreprocessorFactory, VbRelationalQueryTranslationPreprocessorFactory)()
Return optionsBuilder
End Function
End Module
I am trying to build a new leg in a WebAPI that I have written in visual basic. The code I am trying to execute is this:
Public Class getDatabaseDataController
Inherits ApiController
Private product_information As getDatabaseData() = New getDatabaseData() _
{New getDatabaseData() With {
.return_response = "return response"
}}
Public Function GetCars(<FromUri> ByVal dbRequest As String) As IEnumerable(Of getDatabaseData)
Dim return_string As String = ""
Dim passedData As String = dbRequest
return_string = passedData
Dim mqResponse As getDatabaseData() = New getDatabaseData() _
{New getDatabaseData() With {
.return_response = Str(return_string)
}}
'Return product_information
Return mqResponse
End Function
End Class
I have a public class called getDatabaseData defined as follows:
Public Class getDatabaseData
Private _Return_Response As String
Public Property return_response() As String
Get
Return _Return_Response
End Get
Set(value As String)
_Return_Response = value
End Set
End Property
End Class
I call the API with this call:
http://localhost:12976/api/getDatabaseData?dbRequest=A
All I am trying to do at this point is have the API return the value A. When I debug the API and send in the request, this is what is returned:
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Argument 'Number' cannot be converted to a numeric value.
</ExceptionMessage>
<ExceptionType>System.InvalidCastException</ExceptionType>
I dont see anything in the code that would indicate a 'Numeric'. What am I missing?
Thanks in advance for any assistance.
I'd like to know if there is a way to create a module of Extensions methods for all the new projects in Visual Studio 2013.
For example, this is my Module :
Imports System.Runtime.CompilerServices
Imports System.IO
Module Extensions
<Extension> Public Function ReplaceFirst(value As String, oldValue As String, newValue As String) As String
Dim position As Integer = value.IndexOf(oldValue)
If position = -1 Then
Return value
Else
Return value.Substring(0, position) + newValue + value.Substring(position + oldValue.Length)
End If
End Function
<Extension> Public Function ReadAllLines(value As String) As List(Of String)
If value Is Nothing Then
Return Nothing
End If
Dim lines As New List(Of String)
Using StringRdr As New StringReader(value)
While StringRdr.Peek() <> -1
Dim line As String = StringRdr.ReadLine
If Not String.IsNullOrWhiteSpace(line) Then
lines.Add(line)
End If
End While
End Using
Return lines
End Function
<Extension> Public Function UppercaseFirstLetter(value As String) As String
If String.IsNullOrEmpty(value) Then
Return value
End If
Dim Chars() As Char = value.ToCharArray
Chars(0) = Char.ToUpper(Chars(0))
Return New String(Chars)
End Function
<Extension> Public Function ZeroBased(value) As Integer
Return value - 1
End Function
End Module
How can I use this Extensions methods in all my projects without adding the module in all of them ?
Regards, Drarig29.
Make it a library (DLL) and add a reference to the library in each project.
I get the following error Class 'PropGenie_WebService.Branch' cannot be indexed because it has no default property. And I am not sure why. I have googled but don't get a proper explanation or fix. C# help welcome.
My code in the branch.vb class:
Public Function Update() As Branch
Return Update(Me, Path) 'error at update.
End Function
And in my Base class (Resources.vb) I have:
Public Shared Function Update(Of T As {Resources, New})(resource As T, path As String) As T
Dim request = CreateRequest(path & "/{id}", Method.PATCH)
request.AddUrlSegment("id", resource.Id.ToString(CultureInfo.InvariantCulture))
request.AddBody(resource)
Dim Client = CreateClient()
Dim responce = Client.Execute(Of T)(request)
If responce.StatusCode <> HttpStatusCode.OK Then
Throw New InvalidOperationException("Update Failed" & Convert.ToString(responce.StatusCode))
End If
Return responce.Data
End Function
You need to specify the class in which the shared function is also, or it will try to use the Update function in the object you are in.
Public Function Update() As Branch
Return Resources.Update(Me, Path)
End Function
I'm having a heck of a time trying to add fields like department and title.
I'm using this to create a user account:
Dim ctx As New PrincipalContext(ContextType.Domain, "domain.name.pvt", "OU=Users,DC=global,DC=pvt")
Dim usr As UserPrincipal = New UserPrincipal(ctx)
I have no problem creating the account but can't add simple things like Department and Title. I read about using extensions but its in C++ and have no clue on how to do it.
Any help would be great!!! Thanks!
If you're on .NET 3.5 and up, you should check out the System.DirectoryServices.AccountManagement (S.DS.AM) namespace. Read all about it here:
Managing Directory Security Principals in the .NET Framework 3.5
MSDN docs on System.DirectoryServices.AccountManagement
To extend the UserPrincipal class, you don't need much - something like this will suffice (I wrote this in C# originally and just converted it to VB.NET on the 'net - I hope there's no issues with the VB.NET code!)
Imports System.DirectoryServices.AccountManagement
Namespace ADExtended
<DirectoryRdnPrefix("CN")> _
<DirectoryObjectClass("Person")> _
Public Class UserPrincipalEx
Inherits UserPrincipal
' Inplement the constructor using the base class constructor.
Public Sub New(context As PrincipalContext)
MyBase.New(context)
End Sub
' Implement the constructor with initialization parameters.
Public Sub New(context As PrincipalContext, samAccountName As String, password As String, enabled As Boolean)
MyBase.New(context, samAccountName, password, enabled)
End Sub
' Create the "Department" property.
<DirectoryProperty("department")> _
Public Property Department() As String
Get
If ExtensionGet("department").Length <> 1 Then
Return String.Empty
End If
Return DirectCast(ExtensionGet("department")(0), String)
End Get
Set
ExtensionSet("department", value)
End Set
End Property
' Create the "Title" property.
<DirectoryProperty("title")> _
Public Property Title() As String
Get
If ExtensionGet("title").Length <> 1 Then
Return String.Empty
End If
Return DirectCast(ExtensionGet("title")(0), String)
End Get
Set
ExtensionSet("title", value)
End Set
End Property
' Implement the overloaded search method FindByIdentity.
Public Shared Shadows Function FindByIdentity(context As PrincipalContext, identityValue As String) As UserPrincipalEx
Return DirectCast(FindByIdentityWithType(context, GetType(UserPrincipalEx), identityValue), UserPrincipalEx)
End Function
' Implement the overloaded search method FindByIdentity.
Public Shared Shadows Function FindByIdentity(context As PrincipalContext, identityType As IdentityType, identityValue As String) As UserPrincipalEx
Return DirectCast(FindByIdentityWithType(context, GetType(UserPrincipalEx), identityType, identityValue), UserPrincipalEx)
End Function
End Class
End Namespace
Now, you just use the UserPrincipalEx class:
Dim ctx As New PrincipalContext(ContextType.Domain, "domain.name.pvt", "OU=Users,DC=global,DC=pvt")
Dim usr As UserPrincipalEx = New UserPrincipalEx(ctx)
usr.Title = "......."
usr.Department = "......."
The new S.DS.AM makes it really easy to play around with users and groups in AD!