and this is my code
ProductServiceDbContext .cs
using Microsoft.EntityFrameworkCore;
using XTC.BaaSo.ProductService.Products;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.CmsKit.EntityFrameworkCore;
using Volo.CmsKit.Newsletters;
using Volo.CmsKit.UrlShorting;
using Volo.CmsKit.Polls;
using Volo.CmsKit.Comments;
using Volo.CmsKit.Users;
using Volo.CmsKit.Reactions;
using Volo.CmsKit.Ratings;
using Volo.CmsKit.Tags;
using Volo.CmsKit.Pages;
using Volo.CmsKit.Blogs;
using Volo.CmsKit.MediaDescriptors;
using Volo.CmsKit.Menus;
using Volo.CmsKit.GlobalResources;
namespace XTC.BaaSo.ProductService.EntityFrameworkCore;
[ConnectionStringName(ProductServiceDbProperties.ConnectionStringName)]
public class ProductServiceDbContext : AbpDbContext<ProductServiceDbContext>, ICmsKitProDbContext, ICmsKitDbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<NewsletterRecord> NewsletterRecords { get; set; }
public DbSet<NewsletterPreference> NewsletterPreferences { get; set; }
public DbSet<ShortenedUrl> ShortenedUrls { get; set; }
public DbSet<Poll> Polls { get; set; }
public DbSet<PollUserVote> PollUserVotes { get; set; }
public DbSet<PollOption> PollOptions { get; set; }
public DbSet<Comment> Comments { get; set; }
public DbSet<CmsUser> User { get; set; }
public DbSet<UserReaction> Reactions { get; set; }
public DbSet<Rating> Ratings { get; set; }
public DbSet<Tag> Tags { get; set; }
public DbSet<EntityTag> EntityTags { get; set; }
public DbSet<Page> Pages { get; set; }
public DbSet<Blog> Blogs { get; set; }
public DbSet<BlogPost> BlogPosts { get; set; }
public DbSet<BlogFeature> BlogFeatures { get; set; }
public DbSet<MediaDescriptor> MediaDescriptors { get; set; }
public DbSet<MenuItem> MenuItems { get; set; }
public DbSet<GlobalResource> GlobalResources { get; set; }
public ProductServiceDbContext(DbContextOptions<ProductServiceDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.ConfigureProductService();
builder.ConfigureCmsKitPro();
builder.ConfigureCmsKit();
}
}
ProductServiceEntityFrameworkCoreModule.cs
using Microsoft.Extensions.DependencyInjection;
using XTC.BaaSo.ProductService.Products;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore.MySQL;
using Volo.Abp.Modularity;
using Volo.CmsKit.EntityFrameworkCore;
namespace XTC.BaaSo.ProductService.EntityFrameworkCore;
[DependsOn(
typeof(AbpEntityFrameworkCoreMySQLModule),
typeof(AbpEntityFrameworkCoreModule),
typeof(ProductServiceDomainModule)
)]
[DependsOn(typeof(CmsKitProEntityFrameworkCoreModule))]
public class ProductServiceEntityFrameworkCoreModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
ProductServiceEfCoreEntityExtensionMappings.Configure();
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddAbpDbContext<ProductServiceDbContext>(options =>
{
options.ReplaceDbContext<ICmsKitDbContext>();
options.ReplaceDbContext<ICmsKitProDbContext>();
/* Remove "includeAllEntities: true" to create
* default repositories only for aggregate roots */
options.AddDefaultRepositories(includeAllEntities: true);
options.AddRepository<Product, EfCoreProductRepository>();
});
Configure<AbpDbContextOptions>(options =>
{
options.Configure<ProductServiceDbContext>(c =>
{
c.UseMySQL(b =>
{
b.MigrationsHistoryTable("__ProductService_Migrations");
});
});
});
}
}
I saw the code of migrations, but not found nothing about CmsBlogs
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace XTC.BaaSo.ProductService.Migrations
{
/// <inheritdoc />
public partial class CMSKit : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "NewsletterRecords",
columns: table => new
{
...
},
constraints: table =>
{
...
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "Polls",
columns: table => new
{
...
},
constraints: table =>
{
...
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "PollUserVotes",
columns: table => new
{
...
},
constraints: table =>
{
...
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "ShortenedUrls",
columns: table => new
{
...
},
constraints: table =>
{
...
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "NewsletterPreferences",
columns: table => new
{
...
},
constraints: table =>
{
...
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "PollOptions",
columns: table => new
{
...
},
constraints: table =>
{
...
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "IX_NewsletterPreferences_NewsletterRecordId",
table: "NewsletterPreferences",
column: "NewsletterRecordId");
migrationBuilder.CreateIndex(
name: "IX_PollOptions_PollId",
table: "PollOptions",
column: "PollId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "NewsletterPreferences");
migrationBuilder.DropTable(
name: "PollOptions");
migrationBuilder.DropTable(
name: "PollUserVotes");
migrationBuilder.DropTable(
name: "ShortenedUrls");
migrationBuilder.DropTable(
name: "NewsletterRecords");
migrationBuilder.DropTable(
name: "Polls");
}
}
}
Hi, liangshiwei
dotnet ef migrations add CMSKit
at ProductService.EntityFrameworkCore[12:16:23 ERR] An exception occurred while iterating over the results of a query for context type 'XTC.BaaSo.ProductService.EntityFrameworkCore.ProductServiceDbContext'. MySqlConnector.MySqlException (0x80004005): Table 'BaaSo_Product.CmsBlogs' doesn't exist at MySqlConnector.Core.ServerSession.ReceiveReplyAsyncAwaited(ValueTask`1 task) in
Hi Anjali_Musmade,
I succeeded :)
Is like this?
$.ajax({
type: "POST", // Or "GET" depending on your scenario
url: "/ToDo1s?handler=Handle¶m1=hello¶m2=world", // Add URL of your handler method
success: function (data) {
console.log(data);
},
error: function (error) {
console.error(error);
}
});
public class IndexModel : ProdutServicePageModel
{
public string NameFilter { get; set; }
public async Task<IActionResult> OnPostHandleAsync(string param1, string param2)
{
Console.WriteLine($"{param1} {param2}");
return NoContent();
}
}
need OnPostHandlerAsync method
Hi Anjali_Musmade,
I tried your codes, but failed.
The url of ajax has parameter 'handler', Will it be handled automatically by the abp framework , or it needs to be handled manually? like this:
namespace XTC.BaaSo.ProductService.Web.Pages.Products;
public class IndexModel : ProductServicePageModel
{
public string NameFilter { get; set; }
public float? PriceFilterMin { get; set; }
public float? PriceFilterMax { get; set; }
// Parse Url?
public async Task<ActionResult> OnGet()
{
string? handler= null;
Microsoft.Extensions.Primitives.StringValues handlerParam;
if (Request.Query.TryGetValue("handler", out handlerParam))
{
if (handlerParam.Count > 0)
handler = handlerParam[0];
if(handler == "Handle")
Handle();
}
return Page();
}
//TODO invoke this method in javascript
public void Handle()
{
}
}
if needs to be handled manually, how to pass the parameters?
like this?
$.ajax({
type: "POST", // Or "GET" depending on your scenario
url: "/ToDo1s?handler=Handle¶m1=hello¶m2=world", // Add URL of your handler method
success: function (data) {
console.log(data);
},
error: function (error) {
console.error(error);
}
});
public class IndexModel : ProductServicePageModel
{
public string NameFilter { get; set; }
public float? PriceFilterMin { get; set; }
public float? PriceFilterMax { get; set; }
// Parse Url?
public async Task<ActionResult> OnGet()
{
string? handler= null;
string? param1 = null;
string? param2 = null;
Microsoft.Extensions.Primitives.StringValues strParam;
if (Request.Query.TryGetValue("param1", out strParam))
{
if (strParam.Count > 0)
handler = strParam[0];
}
if (Request.Query.TryGetValue("param1", out strParam))
{
if (strParam.Count > 0)
param1= strParam[0];
}
if (Request.Query.TryGetValue("param2", out strParam))
{
if (strParam.Count > 0)
param2 = strParam[0];
}
if(handler == "Handle")
Handle(param1, param2);
return Page();
}
//TODO invoke this method in javascript
public void Handle(string _param1, string _param2)
{
Console.WriteLine($"{_param1} {_param2}");
}
}
Hi Anjali_Musmade,
Thanks for your reply, it is useful, the event of button works fine now.
But how to invoke method of IndexModel.Handle(Index.cshtml.cs) from index.js?
OK, there are my codes
Index.cshtml
@page
@using Microsoft.AspNetCore.Authorization
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using XTC.BaaSo.ProductService.Localization
@using XTC.BaaSo.ProductService.Web.Menus
@using XTC.BaaSo.ProductService.Web.Pages.Products
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Table
@using Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar
@inject IHtmlLocalizer<ProductServiceResource> L
@inject IAuthorizationService Authorization
@model XTC.BaaSo.ProductService.Web.Pages.Products.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = L["Products"].Value;
PageLayout.Content.MenuItemName = ProductServiceMenus.Products;
}
@section scripts
{
<abp-script src="/Pages/Products/index.js" />
}
@section content_toolbar {
@await Component.InvokeAsync(typeof(AbpPageToolbarViewComponent), new { pageName = typeof(IndexModel).FullName })
}
<abp-card>
<abp-card-body>
<abp-row class="mb-3">
<abp-column size-md="_12">
<form id="SearchForm" autocomplete="off">
<div class="input-group">
<input class="form-control" id="FilterText" placeholder="@L["Search"]"/>
<abp-button button-type="Primary" type="submit" icon="search"/>
</div>
</form>
</abp-column>
<abp-column size-md="_12" class="mt-3">
<a href="javascript:;" id="AdvancedFilterSectionToggler">@L["SeeAdvancedFilters"]</a>
</abp-column>
</abp-row>
<abp-row id="AdvancedFilterSection" style="display: none;">
<abp-column size="_3">
<abp-input asp-for="NameFilter" label="@L["Name"].Value" />
</abp-column>
<abp-column size="_3">
<abp-input asp-for="PriceFilterMin" label="@L["MinPrice"].Value" />
</abp-column>
<abp-column size="_3">
<abp-input asp-for="PriceFilterMax" label="@L["MaxPrice"].Value" />
</abp-column>
</abp-row>
<abp-table striped-rows="true" id="ProductsTable">
<thead>
<tr>
<th>@L["Name"]</th>
<th>@L["Price"]</th>
<th></th>
<th>@L["Actions"]</th>
</tr>
</thead>
</abp-table>
</abp-card-body>
</abp-card>
Index.cshtml.cs
namespace XTC.BaaSo.ProductService.Web.Pages.Products;
public class IndexModel : ProductServicePageModel
{
public string NameFilter { get; set; }
public float? PriceFilterMin { get; set; }
public float? PriceFilterMax { get; set; }
//TODO invoke this method in javascript
public void Handle()
{
}
}
index.js
$(function () {
var l = abp.localization.getResource("ProductService");
var productService = window.xTC.baaSo.productService.products.product;
var createModal = new abp.ModalManager({
viewUrl: abp.appPath + "Products/CreateModal"
});
var editModal = new abp.ModalManager({
viewUrl: abp.appPath + "Products/EditModal"
});
var getFilter = function() {
return {
filterText: $("#FilterText").val(),
name: $("#NameFilter").val(),
priceMin: $("#PriceFilterMin").val(),
priceMax: $("#PriceFilterMax").val()
};
};
var dataTable = $("#ProductsTable").DataTable(abp.libs.datatables.normalizeConfiguration({
processing: true,
serverSide: true,
paging: true,
searching: false,
scrollX: true,
autoWidth: false,
scrollCollapse: true,
order: [[1, "asc"]],
ajax: abp.libs.datatables.createAjax(productService.getList, getFilter),
columnDefs: [
{
{ data: "name" },
{ data: "price" },
{
//TODO 1
render: function (data) {
return '<button type="button" class="btn btn-outline-primary"></button>';
}
},
rowAction: {
items:
[
{
text: l("Browse"),
visible: true,
action: function (data) {
console.log(data.record.id);
//TODO 2
}
},
{
text: l("Edit"),
visible: abp.auth.isGranted('ProductService.Products.Edit'),
action: function (data) {
editModal.open({
id: data.record.id
});
}
},
{
text: l("Delete"),
visible: abp.auth.isGranted('ProductService.Products.Delete'),
confirmMessage: function () {
return l("DeleteConfirmationMessage");
},
action: function (data) {
productService.delete(data.record.id)
.then(function () {
abp.notify.info(l("SuccessfullyDeleted"));
dataTable.ajax.reloadEx();
});
}
}
]
}
}
]
}));
createModal.onResult(function () {
dataTable.ajax.reloadEx();
});
editModal.onResult(function () {
dataTable.ajax.reloadEx();
});
$('#AbpContentToolbar button[name=CreateProduct]').click(function (e) {
e.preventDefault();
createModal.open();
});
$("#SearchForm").submit(function (e) {
e.preventDefault();
dataTable.ajax.reloadEx();
});
$('#AdvancedFilterSectionToggler').on('click', function (e) {
$('#AdvancedFilterSection').toggle();
});
$('#AdvancedFilterSection').on('keypress', function (e) {
if (e.which === 13) {
dataTable.ajax.reloadEx();
}
});
$('#AdvancedFilterSection select').change(function() {
dataTable.ajax.reloadEx();
});
});
By the way, I use the microservice-pro, this is my command:
abp new XTC.MyTest -t microservice-pro -u mvc --version 7.3.2
Our main users are school students, In the teaching phase, the number of users is very large, I noticed the Team/Business/Enterprise only include 3 developer seats. So it's a bit impractical to make each student purchase a license or allocate our developer seats.
We love the many features of abp commercial and include them in our platform. We hope that students will also have the opportunity to use them in their practice.
Whether client can use LeptonX-Lite to develop libraries without login into abp account, auto upgrade it to LeptonX when building and integration in our platform? Or do you have any good suggestions?
Hi maliming,
Thanks for reply, Around your prompt, I resolved this issue.
abp generate-proxy -t csharp -u https://localhost:44361/ -m vendorService
, and delete files that differ from the ProductService sample and manual modify the VendorService-generate-proxy.json.
resolve: add --without-contracts
and don't make any modifications.context.Services.AddStaticHttpClientProxies
,but the new project, use the context.Services.AddHttpClientProxies
resolve: manual modify context.Services.AddHttpClientProxies
to context.Services.AddStaticHttpClientProxies
in my new service