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
Related
i am trying to configure new data filter for IMayHaveCreator. I saw example for ISoftDelete and did the same thing.
in MyAppEntityFrameworkCoreModule ive added another configure method for Filter but it does not work
public class SimplyAirEntityFrameworkCoreModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
SimplyAirEfCoreEntityExtensionMappings.Configure();
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<SimplyAirDbContext>(options =>
{
/* Remove "includeAllEntities: true" to create
* default repositories only for aggregate roots */
options.AddDefaultRepositories(includeAllEntities: true);
});
Configure<AbpDbContextOptions>(options =>
{
/* The main point to change your DBMS.
* See also SimplyAirMigrationsDbContextFactory for EF Core tooling. */
options.UseNpgsql();
});
Configure<AbpDataFilterOptions>(options =>
{
options.DefaultStates[typeof(IMayHaveCreator)] = new DataFilterState(isEnabled: true);
});
}
}
am i doing something wrong
I've managed to implement it. solution was to add override for CreateFilterExpression and ShouldFilterEntity methods in dbContext for that interface
trying to setup a multi-tenant site using ABP.io framework 3.1.
I am trying to set the <meta keywords (amongst other tags) in the page html head. I am attempting to get the values from a database field for the current tenant so the meta keywords will be specific for the tenant.
I tried to follow the sample that is available here: https://docs.abp.io/en/abp/latest/UI/AspNetCore/Customization-User-Interface#layout-hooks where they inject a google analytics script code into the head tag.
this is fine, as it is static text, but when i try to load the partial page with a model it throws an error of expecting a different model to that which is passed in.
So far i have the Notification View Componet
Public class MetaKeywordViewComponent : AbpViewComponent
{
public async Task<IViewComponentResult> InvokeAsync() {
return View("/Pages/Shared/Components/Head/MetaKeyword.cshtml"); //, meta);
}
}
and the cshtml page
#using MyCompany.MyProduct.Web.Pages.Shared.Components.Head
#model MetaKeywordModel
#if (Model.SiteData.Keywords.Length > 0)
{
<meta content="#Model.SiteData.Keywords" name="keywords" />
}
and the cshtml.cs file as
public class MetaKeywordModel : MyProductPageModel
{
private readonly ITenantSiteDataAppService _tenantSiteDataAppService;
public TenantSiteDataDto SiteData { get; private set; }
public MetaKeywordModel(ITenantSiteDataAppService tenantSiteDataAppService)
{
_tenantSiteDataAppService = tenantSiteDataAppService;
}
public virtual async Task<ActionResult> OnGetAsync()
{
if (CurrentTenant != null)
{
SiteData = await _tenantSiteDataAppService.GetSiteDataAsync();
}
return Page();
}
}
but when i run the program i get the following error.
An unhandled exception has occurred while executing the request.
System.InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'Volo.Abp.AspNetCore.Mvc.UI.Components.LayoutHook.LayoutHookViewModel', but this ViewDataDictionary instance requires a model item of type 'MyCompany.MyProduct.TenantData.Dtos.TenantSiteDataDto'.
How do i pass the data from my database into the page to be rendered if i can't use my model?
Any help tips or tricks would be greatly appreciated.
Regards
Matty
ViewComponent is different from the razor page.
See https://learn.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-3.1#view-components
You should inject the service in view component class directly. like:
public class MetaKeywordViewComponent : AbpViewComponent
{
private readonly ITenantSiteDataAppService _tenantSiteDataAppService;
public MetaKeywordViewComponent(ITenantSiteDataAppService tenantSiteDataAppService)
{
_tenantSiteDataAppService = tenantSiteDataAppService;
}
public async Task<IViewComponentResult> InvokeAsync()
{
return View("/Pages/Shared/Components/Head/MetaKeyword.cshtml",
await _tenantSiteDataAppService.GetSiteDataAsync());
}
}
In addition, you can refer https://github.com/abpframework/abp/blob/42f37c5ff01ad853a5425d15539d4222cd0dab69/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/PageAlerts/PageAlertsViewComponent.cs
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.
I'm trying to test that the model returned from my Nancy application is as expected. I have followed the docs here but whenever I call the GetModel<T> extension method it throws a KeyNotFoundException.
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
I know what the error means but I'm failing to see why it's being thrown.
Here's my module
public class SanityModule : NancyModule
{
public SanityModule()
{
Get["sanity-check"] = _ => Negotiate.WithModel(new SanityViewModel { Id = 1 })
.WithStatusCode(HttpStatusCode.OK);
}
}
my view model
public class SanityViewModel
{
public int Id { get; set; }
}
and here's my test
[TestFixture]
public class SanityModuleTests
{
[Test]
public void Sanity_Check()
{
// Arrange
var browser = new Browser(with =>
{
with.Module<SanityModule>();
with.ViewFactory<TestingViewFactory>();
});
// Act
var result = browser.Get("/sanity-check", with =>
{
with.HttpRequest();
with.Header("accept", "application/json");
});
var model = result.GetModel<SanityViewModel>();
// Asset
model.Id.ShouldBeEquivalentTo(1);
}
}
Debugging this test shows that the module is hit and completes just fine. Running the application shows that the response is as expected.
Can anyone shed some light on this?
Thanks to the lovely guys, albertjan and the.fringe.ninja, in the Nancy Jabbr room we've got an explanation as to what's going on here.
TL;DR It makes sense for this to not work but the error message should be more descriptive. There is a workaround below.
The issue here is that I am requesting the response as application/json whilst using TestingViewFactory.
Let's take a look at the implementation of GetModel<T>();
public static TType GetModel<TType>(this BrowserResponse response)
{
return (TType)response.Context.Items[TestingViewContextKeys.VIEWMODEL];
}
This is simply grabbing the view model from the NancyContext and casting it to your type. This is where the error is thrown, as there is no view model in NancyContext. This is because the view model is added to NancyContext in the RenderView method of TestingViewFactory.
public Response RenderView(string viewName, dynamic model, ViewLocationContext viewLocationContext)
{
// Intercept and store interesting stuff
viewLocationContext.Context.Items[TestingViewContextKeys.VIEWMODEL] = model;
viewLocationContext.Context.Items[TestingViewContextKeys.VIEWNAME] = viewName;
viewLocationContext.Context.Items[TestingViewContextKeys.MODULENAME] = viewLocationContext.ModuleName;
viewLocationContext.Context.Items[TestingViewContextKeys.MODULEPATH] = viewLocationContext.ModulePath;
return this.decoratedViewFactory.RenderView(viewName, model, viewLocationContext);
}
My test is requesting json so RenderView will not be called. This means you can only use GetModel<T> if you use a html request.
Workaround
My application is an api so I do not have any views so changing the line
with.Header("accept", "application/json");
to
with.Header("accept", "text/html");
will throw a ViewNotFoundException. To avoid this I need to implement my own IViewFactory. (this comes from the.fringe.ninja)
public class TestViewFactory : IViewFactory
{
#region IViewFactory Members
public Nancy.Response RenderView(string viewName, dynamic model, ViewLocationContext viewLocationContext)
{
viewLocationContext.Context.Items[Fixtures.SystemUnderTest.ViewModelKey] = model;
return new HtmlResponse();
}
#endregion
}
Then it is simply a case of updating
with.ViewFactory<TestingViewFactory>();
to
with.ViewFactory<TestViewFactory>();
Now GetModel<T> should work without needing a view.
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.