I'm trying out Entity Framework Code First. I can't seem to find the assembly/namespace to use for RecreateDatabaseIfModelChanges in WPF 4.0. Is this an ASP.NET-only feature? If not, what assembly should I reference?
Here's my code:
using System;
using System.Data.Entity;
using System.Windows;
using CodeFirstTester.Models;
namespace CodeFirstTester
{
public partial class App : Application
{
static App()
{
// this fails:
Database.SetInitializer(new RecreateDatabaseIfModelChanges<NerdDinners>());
// The type or namespace name 'RecreateDatabaseIfModelChanges'
// could not be found (are you missing a using directive or
// an assembly reference?)
using (var nerdDinners = new NerdDinners())
{
var dinner = new Dinner()
{
Title = "Party at Scott's House",
EventDate = DateTime.Parse("12/31/2010"),
Address = "Building 40",
HostedBy = "scottgu#microsoft.com"
};
nerdDinners.Dinners.Add(dinner);
nerdDinners.SaveChanges();
}
}
}
}
The initializer is called DropCreateDatabaseIfModelChanges. It can be found in EntityFramework.dll (EF 4.1) in System.Data.Entity namespace.
Related
I'm trying to create a wizard using Catel 5.4.0.0 and Orc.Wizard 2.0.0.0
I followed the example on https://opensource.wildgums.com/orc.wizard/ but when I call the wizard it returns the error "The view model of the view 'QuotationWizardPageView' could not be resolved.
Here is some code
using Orc.Wizard
using System
namespace ZMAdmin.ASWizard
{
public class QuotationWizardPage : WizardPageBase
{
public QuotationWizardPage()
{
Title = "Offerte";
Description = "Offerte";
}
}
}
using Orc.Wizard;
using System;
namespace ZMAdmin.ASWizard
{
public class QuotationWizardPageViewModel : WizardPageViewModelBase<QuotationWizardPage>
{
public QuotationWizardPageViewModel(QuotationWizardPage wizardPage)
: base(wizardPage)
{
}
}
}
using Catel.Ioc;
using Orc.Wizard;
namespace ZMAdmin.ASWizard : WizardBase
{
public ASWizard(ITypeFactory typeFactory)
: base (typeFactory)
{
Tittle = "Bedrijfsnaam";
this.AddPage<QuotationWizardPage>();
}
}
<catel.UserControl x:Class="ZMAdmin.Views.QuotationWizardPageView"
xmlns:catel="http://schemas.catelproject.com"
>
</catel.UserControl>
in the app.xaml.cs I've
var MyViewLocator = ServiceLocator.Default.ResolveType<IViewLocator>();
MyViewLocator.Register(typeof(QuotationWizardPageViewModel), typeof(QuotationWizardPageView));
And last I call the wizard using:
private async void OnAddQuotation()
{
await _wizardService.ShowWizardAsync<ASWizard.ASWizard>();
}
The wizard displays, but returns the error, not displaying the quotationView.
What am I overlooking?
If the code you posted is correct (but I see another issue where a namespace is inheriting from a base class), it's probably caused of namespace conflicts.
The view is located in ZMAdmin.Views
The view model is located in ZMAdmin.ASWizard
My recommendation is to use:
View models: ZMAdmin.ASWizard.ViewModels
Views: ZMAdmin.ASWizard.Views
I am not sure how to configure an mvc client running on .Net Framework 4.7.1 to Authenticate with IdentityServer4 (3.1) running on .Net Core.
I have successfully authenticated clients running on .net core against IdentityServer4 before but not a client running on .Net Framework. I can't upgrade this client to .net core unfortunately.
Basically, I am not sure how to do this on the mvc client:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
services.AddAuthentication(options =>
{
options.DefaultScheme = "Cookies";
options.DefaultChallengeScheme = "oidc";
})
.AddCookie("Cookies")
.AddOpenIdConnect("oidc", options =>
{
options.Authority = "https://myIdentityServer:4532";
options.ClientId = "MVC_Net_Framework";
options.ClientSecret = "mysecret";
options.ResponseType = "code";
options.Scope.Add("myScope");
options.SaveTokens = true;
});
}
you need to use OwinStartup class . add partial class Startup in root of your project as
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using Microsoft.Owin;
using Owin;
using Microsoft.Owin.Cors;
using System.Web.Http;
using System.Web.Mvc;
using System.Configuration;
[assembly: OwinStartup(typeof(MCVAppNet7.Startup))]
namespace MCVAppNet7
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
var services = new ServiceCollection();
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
ConfigureAuth(app);
// For Access-Control-Allow-Origin
app.UseCors(CorsOptions.AllowAll);
}
}
}
after this create a new file "Startup.Auth.cs" in "App_Start" folder and inside this create partial Startup class
using System.Configuration;
using Owin;
using Microsoft.Owin.Security.Cookies;
using IdentityServer3.AccessTokenValidation;
using System;
namespace MCVAppNet7
{
public partial class Startup
{
public void ConfigureAuth(IAppBuilder app)
{
try
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Cookies"
});
app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
{
Authority = "",
ClientId = "",
AuthenticationType = "Bearer",
RequiredScopes = new[] { "" },
ValidationMode = "",
PreserveAccessToken = true,
RequireHttps = ""
});
}
catch (Exception ex)
{
throw ex;
}
}
}
}
install these package from from NuGet
Microsoft.Owin
Microsoft.Owin.Security.OAuth
Microsoft.Owin.Host.SystemWeb
IdentityModel
IdentityServer3.Contrib.AccessTokenValidation
I'm using IdentityServer3.Contrib.AccessTokenValidation and it's working for me but it might work with IdentityServer4.AccessTokenValidation and more info here
https://learn.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/owin-startup-class-detection
ASP.NET Web Api - Startup.cs doesn't exist
https://github.com/IdentityServer/IdentityServer4/issues/4188
Authenticating WASM Blazor against Azure Active Directory is covered nicely by Microsoft in their walkthroughs. What they don't cover is the development workflow afterwards. Being a compiled application, every change to the UI is a painful stop-recompile-start process, which is then compounded by an AAD login process.
How do we streamline this and set a fake set of credentials during development?
This approach works for me, for now, but I am keen to see what others do. Note this is primarily for development, but I could look to extend this for integration tests (which is next on my list).
In the client, make yourself a fake AuthenticationStateProvider to replace the Remote authentication one you normally use.
using System;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
namespace Blah.Client
{
public class FakeAuthStateProvider : AuthenticationStateProvider, IAccessTokenProvider
{
public override Task<AuthenticationState> GetAuthenticationStateAsync()
{
var identity = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, ">> TEST USER <<"),
new Claim("directoryGroup","abc4567-890-1234-abcd-1234567890abc") //Should match your group you use to determine a policy
}, "Fake authentication type");
var user = new ClaimsPrincipal(identity);
return Task.FromResult(new AuthenticationState(user));
}
public async ValueTask<AccessTokenResult> RequestAccessToken()
{
return new AccessTokenResult(AccessTokenResultStatus.Success, new AccessToken() { Expires = DateTime.Now + new TimeSpan(365,0,0,0) }, "");
}
public async ValueTask<AccessTokenResult> RequestAccessToken(AccessTokenRequestOptions options)
{
return new AccessTokenResult(AccessTokenResultStatus.Success, new AccessToken() { Expires = DateTime.Now + new TimeSpan(365, 0, 0, 0) }, "");
}
}
}
In the client program.cs, switch out the auth when in debug:
#if DEBUG
SetupFakeAuth(builder.Services);
#else
builder.Services.AddMsalAuthentication<RemoteAuthenticationState, CustomUserAccount>(options =>
{
builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add("api://1234567-890-1234-abcd-1234567890abc/API.Access");
})
.AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, CustomUserAccount, CustomAccountFactory>();
#endif
.....
private static void SetupFakeAuth(IServiceCollection services)
{
//https://github.com/dotnet/aspnetcore/blob/c925f99cddac0df90ed0bc4a07ecda6b054a0b02/src/Components/WebAssembly/WebAssembly.Authentication/src/WebAssemblyAuthenticationServiceCollectionExtensions.cs#L28
services.AddOptions();
services.AddAuthorizationCore();
services.TryAddScoped<AuthenticationStateProvider, FakeAuthStateProvider>();
services.TryAddTransient<BaseAddressAuthorizationMessageHandler>();
services.TryAddTransient<AuthorizationMessageHandler>();
services.TryAddScoped(sp =>
{
return (IAccessTokenProvider)sp.GetRequiredService<AuthenticationStateProvider>();
});
services.TryAddScoped<IAccessTokenProviderAccessor, FakeAccessTokenProviderAccessor>();
services.TryAddScoped<SignOutSessionStateManager>();
}
...
And define the FakeAuthState provider, which is just a copy of the internal class Microsoft register:
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Components.WebAssembly.Authentication.Internal
{
internal class FakeAccessTokenProviderAccessor : IAccessTokenProviderAccessor
{
private readonly IServiceProvider _provider;
private IAccessTokenProvider _tokenProvider;
public FakeAccessTokenProviderAccessor(IServiceProvider provider) => _provider = provider;
public IAccessTokenProvider TokenProvider => _tokenProvider ??= _provider.GetRequiredService<IAccessTokenProvider>();
}
}
This should result in a logged in user on the client that has a name and Scopes as usual.
Server side:
in Startup.cs
#if DEBUG
services.AddSingleton<IPolicyEvaluator, FakePolicyEvaluator>();
#else
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"));
#endif
and a new class:
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization.Policy;
using Microsoft.AspNetCore.Http;
namespace Blah.Server
{
public class FakePolicyEvaluator : IPolicyEvaluator
{
public virtual async Task<AuthenticateResult> AuthenticateAsync(AuthorizationPolicy policy, HttpContext context)
{
const string testScheme = "FakeScheme";
var principal = new ClaimsPrincipal();
principal.AddIdentity(new ClaimsIdentity(new[] {
new Claim("Permission", "CanViewPage"),
new Claim("Manager", "yes"),
new Claim(ClaimTypes.Role, "Administrator"),
new Claim(ClaimTypes.NameIdentifier, "John")
}, testScheme));
return await Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(principal,
new AuthenticationProperties(), testScheme)));
}
public virtual async Task<PolicyAuthorizationResult> AuthorizeAsync(AuthorizationPolicy policy,
AuthenticateResult authenticationResult, HttpContext context, object resource)
{
return await Task.FromResult(PolicyAuthorizationResult.Success());
}
}
}
Hope that helps someone. I'll now look to improve this and make it work in testing scenarios.
I am trying to create a simple web-api in DNN,
Here are my codes :
1st Register RouteMapper (I set a break-point it is being called without problem)
namespace Commission7.Controllers
{
public class RouteMapper : IServiceRouteMapper
{
public void RegisterRoutes(IMapRoute mapRouteManager)
{
mapRouteManager.MapHttpRoute("Commission7", "default", "{controller}/{action}/{id}", new { id = RouteParameter.Optional }, new[] { "Commission7.Controllers" });
}
}
}
2nd The Controller :
namespace Commission7.Controllers
{
[AllowAnonymous]
class SubmitController : DnnApiController
{
private readonly Commision7Context _dbContext = new Commision7Context();
[AllowAnonymous]
[HttpGet]
public bool SaveVisits()
{
return true;
}
}
}
And when I call it through Ajax or Direct hit from Browser with this:
http://localhost/dnn/DesktopModules/Commission7/api/Submit/SaveVisits
I get :
Unable to locate a controller for http://localhost/dnn/DesktopModules/Commission7/api/Submit/SaveVisits. Searched in namespaces: Commission7.Controllers.
note that the Module folder is named Commission 7 and it is in the DesktopModules folder. Can anyone help me with this? Is there any config that I forgot?
If anyone else comes across this, also check whether you have the attribute...
optimizeCompilations="true"
...set in your web.config file's <compilation> tag. I kept getting the error...
dnn unable to locate a controller XXX searched in namespaces XXX
...until I set it to false.. Then the error went away so I could set it back to true.
I found the problem , class SubmitController was private class , it should be public to be available for ajax and direct call.
This works:
XamlReader.Parse("<Pig xmlns=\"clr-namespace:Farm;assembly=Farm\"/>");
This throws The tag 'Pig' does not exist in XML namespace 'clr-namespace:Farm;assembly=Farm':
var context = new ParserContext();
context.XmlnsDictionary.Add("", "clr-namespace:Farm;assembly=Farm");
XamlReader.Parse("<Pig/>", context);
Why?
Farm is the calling application.
What you have will work in .NET 4.0, but unfortunately not in .NET 3.5. Try using XamlTypeMapper instead:
var context = new ParserContext();
context.XamlTypeMapper = new XamlTypeMapper(new string[] { });
context.XamlTypeMapper.AddMappingProcessingInstruction("", "Farm", "Farm");
XamlReader.Parse("<Pig/>", context);
If you wanted to use a namespace prefix, you could declare a clr namespace to xml namespace mapping with the XamlTypeMapper and then declare a namespace prefix for the xml namespace.
var context = new ParserContext();
context.XamlTypeMapper = new XamlTypeMapper(new string[] { });
context.XamlTypeMapper.AddMappingProcessingInstruction("Foo", "Farm", "Farm");
context.XmlnsDictionary.Add("a", "Foo");
XamlReader.Parse("<a:Pig/>", context);