StackExchange.Redis.Extensions error after updating nuget - asp.net-mvc

I have updated to the latest StackExchange.Redis.Extensions.Core package and I am getting the following error.
The previous version of StackExchange.Redis.Extensions.Core is - 2.3.0 and the updated new version is - 3.4.0
None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'StackExchange.Redis.Extensions.Core.StackExchangeRedisCacheClient' can be invoked with the available services and parameters:
Cannot resolve parameter 'StackExchange.Redis.Extensions.Core.Configuration.RedisConfiguration configuration' of constructor 'Void .ctor(StackExchange.Redis.Extensions.Core.ISerializer, StackExchange.Redis.Extensions.Core.Configuration.RedisConfiguration)'.
Cannot resolve parameter 'System.String connectionString' of constructor 'Void .ctor(StackExchange.Redis.Extensions.Core.ISerializer, System.String, System.String)'.
Cannot resolve parameter 'System.String connectionString' of constructor 'Void .ctor(StackExchange.Redis.Extensions.Core.ISerializer, System.String, Int32, System.String)'.
Cannot resolve parameter 'StackExchange.Redis.IConnectionMultiplexer connectionMultiplexer' of constructor 'Void .ctor(StackExchange.Redis.IConnectionMultiplexer, StackExchange.Redis.Extensions.Core.ISerializer, System.String)'.
Cannot resolve parameter 'StackExchange.Redis.IConnectionMultiplexer connectionMultiplexer' of constructor 'Void .ctor(StackExchange.Redis.IConnectionMultiplexer, StackExchange.Redis.Extensions.Core.ISerializer, StackExchange.Redis.Extensions.Core.Configuration.ServerEnumerationStrategy, System.String)'.
Cannot resolve parameter 'StackExchange.Redis.IConnectionMultiplexer connectionMultiplexer' of constructor 'Void .ctor(StackExchange.Redis.IConnectionMultiplexer, StackExchange.Redis.Extensions.Core.ISerializer, Int32, System.String)'.
Cannot resolve parameter 'StackExchange.Redis.IConnectionMultiplexer connectionMultiplexer' of constructor 'Void .ctor(StackExchange.Redis.IConnectionMultiplexer, StackExchange.Redis.Extensions.Core.ISerializer, StackExchange.Redis.Extensions.Core.Configuration.ServerEnumerationStrategy, Int32, System.String)'.
I have installed following nuget packages:
Microsoft.Web.RedisSessionStateProvider
StackExchange.Redis
StackExchange.Redis.StrongName
StackExchange.Redis.Extensions.Core
StackExchange.Redis.Extensions.LegacyConfiguration
StackExchange.Redis.Extensions.Newtonsoft
My web.config is as follows:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="redisCacheClient" type="StackExchange.Redis.Extensions.LegacyConfiguration.RedisCachingSectionHandler, StackExchange.Redis.Extensions.LegacyConfiguration" />
</configSections>
<redisCacheClient allowAdmin="true" ssl="True" connectTimeout="3000" database="15" password="IlQZ--------90=">
<serverEnumerationStrategy mode="Single" targetRole="PreferSlave" unreachableServerAction="IgnoreIfOtherAvailable" />
<hosts>
<add host="xxxxxx.redis.cache.windows.net" cachePort="6380" />
</hosts>
</redisCacheClient>
<connectionStrings>
<add name="RedisConnectionString" connectionString="xxxx.redis.cache.windows.net:6380,password=IlQZ--------90=,ssl=True,synctimeout=15000,abortConnect=False" />
</connectionStrings>
<appSettings>
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.6.1" />
<httpRuntime targetFramework="4.6.1" />
</system.web>
<runtime>
<assemblyBinding
xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.8.1.0" newVersion="4.8.1.0" />
</dependentAssembly>
<!-- more dependentAssembly -->
<dependentAssembly>
<assemblyIdentity name="StackExchange.Redis.Extensions.Core" publicKeyToken="d7d863643bcd13ef" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.4.0.0" newVersion="3.4.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
And my OWIN startup class with autofac is as follows :
public void Configuration(IAppBuilder app)
{
var builder = new ContainerBuilder();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterType<NewtonsoftSerializer>()
.AsSelf()
.AsImplementedInterfaces()
.SingleInstance();
builder.RegisterType<StackExchangeRedisCacheClient>()
.AsSelf()
.AsImplementedInterfaces()
.SingleInstance();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
app.UseAutofacMiddleware(container);
app.UseAutofacMvc();
}
What am i doing wrong here?

Autofac can't resolve anything you don't tell it about. You've told it about:
Your controllers.
NewtonsoftSerializer
StackExchangeRedisClient
But read the exception - there's no parameterless constructor for StackExchangeRedisClient and you didn't tell Autofac about anything else. Autofac doesn't just "read the web.config" or anything. You have to put that together. Read the exception again and register enough stuff that one of the constructors will match.
This is not real code but gives you an idea:
// THIS ISN'T TESTED, FOR IDEA PURPOSES ONLY
builder.Register(c => {
var config = ConfigurationManager.GetSection("RedisCacheClient");
var connectionString = config.ConnectionStrings[0];
return new StackExchangeRedisClient(connectionString);
}).AsSelf()
.AsImplementedInterfaces()
.SingleInstance();
Point being, you have to read the config, or register something in the container that will otherwise satisfy the parameters required to create the Redis client.

The problem is that Autofac does not have the proper information to build the object so I agree with #travis-illig. The way I resolved it was to register the required types first:
builder.RegisterType<JilSerializer>()
.As<ISerializer>()
.SingleInstance();
RedisConfiguration redisConfiguration = RedisUtil.GetConfig();
builder.RegisterInstance(redisConfiguration);
builder.RegisterType<StackExchangeRedisCacheClient>()
.As<ICacheClient>()
.SingleInstance();
Note I have got a Util class that constructs the Redisconfiguration.

Related

System.MissingMethodException from a class that has property of type byref<_>

I'm having difficulties using RBush from F#. The library requires me to define a class that implements the following interface.
public interface ISpatialData
{
ref readonly Envelope Envelope { get; }
}
Below is the code of a console application that compiles fine, where Point class implements the ISpatialData interface.
open RBush
type Point(minX, minY, maxX, maxY) =
let mutable envelope = Envelope(minX, minY, maxX, maxY)
interface ISpatialData with
member __.Envelope = &envelope
[<EntryPoint>]
let main _ =
let tree = RBush<Point>()
0
However, when the application is run it throws: System.MissingMethodException: 'Method not found: 'RBush.Envelope ByRef RBush.ISpatialData.get_Envelope()'.'
If I send the Point class definition to F# Interactive I get the following error: error FS0193: internal error: Signature of the body and declaration in a method implementation do not match. Type: 'Point'. Assembly: 'FSI-ASSEMBLY, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
Any ideas what I'm doing wrong?
This usually indication of you using different FSharp.Core than used for the library. Modify app.config to have following:
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=_Your .Net Version_" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-_Your FSharp.Core Version_" newVersion="_Your FSharp.Core Version_" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

why connection string is not found from my class library to another class library?

I am having the architecture like this :
Where MVC layer is the presentation layer. EF is class library and Repository is another class library.I am trying to insert data to database from repository by creating the EF context object. Added EF reference into Repository class library. EF having the edmx file. its app.config having the connection string generated by EF.
code is :
public bool CreateUser(User _user)
{
context.Users.Add(_user);
context.SaveChanges();
return true;
}
but while executing this I am getting following exception :
No connection string named 'MyEntitiesConnection' could be found in the application config file.
I tried to add same connection string with same name in repository app.config. but not working. anyone have solution ?
Edited:
connection string is :
<add name="MyEntitiesConnection" connectionString="metadata=res://*/EF.Entities.csdl|res://*/EF.Entities.ssdl|res://*/EF.Entities.msl;provider=System.Data.SqlClient;provider connection string="data source=Servername\MSSQL2008R2;initial catalog=MyDBName;persist security info=True;user id=sa;MultipleActiveResultSets=True;App=EntityFramework;" providerName="System.Data.EntityClient" />
app.config:
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<connectionStrings>
<add name="MyEntitiesConnection" connectionString="metadata=res://*/EF.Entities.csdl|res://*/EF.Entities.ssdl|res://*/EF.Entities.msl;provider=System.Data.SqlClient;provider connection string="data source=Servername\MSSQL2008R2;initial catalog=MyDBName;persist security info=True;user id=sa;MultipleActiveResultSets=True;App=EntityFramework;" providerName="System.Data.EntityClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
</entityFramework>
</configuration>
In any .NET application, only one config file is the natural starting point for looking for configuration information. For web applications, that's the web.config file at the root of the application1.
Whilst you may have a file called app.config in your repository project (and, indeed, some VS tooling may have added one) or your EF project, it's not used when you try to read configuration information.
The connection string section needs to exist in the web.config of your MVC app.
1For non-web applications, it's the app.config for the project that produces the .exe file and that gets automatically copied as XXX.exe.config during the build.

Debugging MVC3 Source code with Ninject error

I am trying to understand how the Html Helpers are built inside MVC 3. So i downloaded MVC 3 source and added as another project in same solution to debug it.
I followed this steps.
Removed System.web.Mvc reference from my MVC Application
Added a System.web.Mvc Source code project reference for debugging.
In Web.config System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35 to System.Web.Mvc
However i have other NInject(NInject, NInject.web.common, WebActivator, Microsoft.web.infrastructure) references added in my MVC 3 application for dependency injection.
Now i am getting an error in System.Web.MVC Source saying 'An error occurred when trying to create a controller of type 'MVCApp.Controllers.HomeController'. Make sure that the controller has a parameterless public constructor. in below MVC Source code of
public IController Create(RequestContext requestContext, Type controllerType)
{
try
{
return (IController)(_resolverThunk().GetService(controllerType)
?? Activator.CreateInstance(controllerType));
}
catch (Exception ex)
{
throw new InvalidOperationException(
String.Format(CultureInfo.CurrentCulture,
MvcResources.DefaultControllerFactory_ErrorCreatingController, controllerType),
ex);
}
}
Checking DependencyResolver.Current property says
DependencyResolver.Current The type
'System.Web.Mvc.DependencyResolver' exists in both
'System.Web.Mvc.dll' and 'System.Web.Mvc.dll'
What more needs to be done in order to debug my MVC3App with MVC3 source code? how can i avoid this error?
Take a look on this solution: Ninject + MVC3 is not injecting into controller
Add this to the Web.config
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0" newVersion="4.0.0.0" />
<bindingRedirect oldVersion="2.0.0.0" newVersion="4.0.0.0" />
<!-- The following line was missing -->
<bindingRedirect oldVersion="3.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
It solved this problem:
Checking DependencyResolver.Current property says
DependencyResolver.Current The type
'System.Web.Mvc.DependencyResolver' exists in both
'System.Web.Mvc.dll' and 'System.Web.Mvc.dll'
Cheers.

Deploy WebSharper 2.4 sitelet on IIS7.5

I created a websharper sitelet project from Visual Studio 2012, which I called SiteletTest.
I compiled this project.
Then I copied SiteletTest/Web to inetpub/wwwroot.
Then I go to localhost/SiteletTest, localhost/SiteletTest/Home and localhost/SiteletTest/home but in each case I get http 404.
If I go to localhost/Main.html then I get a page, so going to this directory seems to work, but websharper doesn't appear to be working.
My web.config is below, and I have no idea what else to do. I already set the application pool to use .net 4:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<authentication mode="Forms" />
<pages>
<controls>
<add tagPrefix="WebSharper" namespace="IntelliFactory.WebSharper.Web" assembly="IntelliFactory.WebSharper.Web" />
<add tagPrefix="ws" namespace="Website" assembly="Website" />
</controls>
</pages>
<httpModules>
<add name="WebSharper.Remoting" type="IntelliFactory.WebSharper.Web.RpcModule, IntelliFactory.WebSharper.Web" />
<add name="WebSharper.Sitelets" type="IntelliFactory.WebSharper.Sitelets.HttpModule, IntelliFactory.WebSharper.Sitelets" />
</httpModules>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules>
<add name="WebSharper.Remoting" type="IntelliFactory.WebSharper.Web.RpcModule, IntelliFactory.WebSharper.Web" />
<add name="WebSharper.Sitelets" type="IntelliFactory.WebSharper.Sitelets.HttpModule, IntelliFactory.WebSharper.Sitelets" />
</modules>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
<assemblyBinding appliesTo="v4.0.30319" xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="2.0.0.0" newVersion="4.3.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
I am not going to be paying for a license until I get an idea if this may work for my needs, so, how do I get this to work?
I don't want to copy the sitelet code, but here are some fragments:
type Action =
| Home
| Contact
| Protected
| Login of option<Action>
| Logout
| Echo of string
and another fragment:
module Pages =
/// The home page.
let HomePage : Content<Action> =
Skin.WithTemplate "Home" <| fun ctx ->
[
H1 [Text "Welcome to our site!"]
"Let us know how we can contact you" => ctx.Link Action.Contact
]
I'm pretty sure you are missing 1 of three things:
1- Your sitelet/router isn't defined... something like this:
type Site() =
interface IWebsite<Action> with
member x.Sitelet =
Sitelet.Infer
<| function
| Home -> Pages.HomePage
...
member x.Actions = []
This maps each of the action cases to the correct page. There are many ways to define it but the above Sitelet.Infer will simply map the route by name.
2- You did not specify a Website assembly attribute... something like this:
[<assembly : Website(typeof<Site>)>]
do ()
I think this tells ASP.NET to load the above Sitelet as your site.
3- A third option is to automatically load a client-side JavaScript control from a Default.aspx page in the C# Web Project. If you use the Web Application (ASP.NET) template, you will see an example of that... but with that I do not think you can control the URL Path in a REST-full manner.

Microsoft Unit Testing with ASP.NET membership provider

Is anyone else frustrated with the built in ASP.NET unit testing framework? The problem I am having is connecting and testing against the Membership provider for ASP.NET in a MVC3 application. It looks like the database connection has not been established or that there is a different set of rules in place then when I run the application normally. Here are the two scenarios.
1) Attempting to find an existing user by name:
Unit Test -
[TestMethod]
public void RegisterTest()
{
AccountController target = new AccountController();
RegisterModel model = new RegisterModel() { UserName = "existinguser", Email = "email#test.com", Password = "Password", ConfirmPassword = "Password" };
actual = target.Register(model);
}
Code chunk from the AccountController -
MembershipCreateStatus createStatus;
MembershipUserCollection members = Membership.FindUsersByName(model.UserName);
MembershipUser user = null;
if (members.Count > 0)
createStatus = MembershipCreateStatus.DuplicateUserName;
Result -
When I step into this code the members array is empty even though I know this user to be in the system. Is there some trick to establishing a connection to the membership store in the unit testing application? I have attempted using the datasource attribute with no success.
2) Attempting to create a new membership account:
The unit test is the same as above however I am passing a new user that is not already in the system. When I step into the controller and get to the following line it gives me a membershipCreateStatus of 'InvalidQuestion'. This seems odd since when running this live I don't have that problem and can create accounts with the line as it is.
user = Membership.CreateUser(model.UserName, model.Password, model.Email, string.Empty, string.Empty, true, null, out createStatus);
Thanks in advance for your help. I am really trying to do this test first method but it's making it harder using the built in testing framework. Certainly there is a way to connect to the DB for all the unit tests (not providing a connection for each test) and simulate the same actions I would through a browser.
When you run your unit tests it will effectively run as a new application and will therefore use its own config file - in other words not web.config that your MVC app uses. So what I would guess you are missing without more information is an entry in the app.config file in your test project, for the connection string to the database that holds your membership information (you may also be missing app.config).
If you are trying to take a TDD approach you should be writing unit tests and if you need to connect to a database for the unit tests to run, they are probably integration tests rather than unit tests. Because the Membership classes use static methods this makes things difficult. What I would recommend is wrapping the membership functionality up in it's own service with a corresponding interface (IMembershipService for example) which can then be injected by your IoC container. For the purposes of your unit tests, you can then simply mock the IMembershipService interface that you created with no need to connect to your database.
I had the same problem. And yes it looks like my unit tests are more like integration tests but I just needed to test the controllers and speed wasn't a concern at this point in the project. I basically added all the sql memberbership config and connection string from the MVC 3 project's web.config to test project's app.config and the membership provider worked when the unit tests ran. Below is my test project's app.config in it's entiriety.
<?xml version="1.0" encoding="utf-8"?>
<!--
Note: Add entries to the App.config file for configuration settings
that apply only to the Test project.
-->
<configuration>
<appSettings></appSettings>
<connectionStrings>
<add name="ApplicationServices" connectionString="mySqlServer;initial catalog=mySqlMembershipDB;persist security info=True;user id=mySqlUser;password=mySqlPassword;" providerName="System.Data.SqlClient" />
</connectionStrings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.5.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.web>
<membership defaultProvider="AspNetSqlMembershipProvider">
<providers>
<clear />
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
<profile defaultProvider="AspNetSqlProfileProvider">
<providers>
<clear />
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" />
</providers>
</profile>
<roleManager enabled="false" defaultProvider="AspNetSqlRoleProvider">
<providers>
<clear />
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
</providers>
</roleManager>
</system.web>
</configuration>

Resources