باسلام. اگر بخواهیم متدهای اعتبارسنجی را از مدل بگیرد و بصورت جاوااسکریپتی و قبل از مراجعه مجدد به سرور اعتبارسنجی را انجام دهد چکار باید بکنیم؟
[Required] public string Title { get; set; }
[Required] public string Title { get; set; }
[RegularExpression("^[a-zA-Z0-9_]*$", ErrorMessage = "لطفا تنها از اعداد و حروف انگلیسی استفاده نمائید")] public string Username { get; set; }
[MaxLength(2), Required(ErrorMessage = "طول فیلد بیش از حد مجاز است")] public string ProductName { get; set; }
query OwnersQuery { owners { name account { type } } }
{ "data": { "owners": [ { "name": "John Doe", "accounts": [ { "type": "Cash" }, { "type": "Savings" } ] } ] } }
dotnet new api -n ASPCoreGraphQL
پوشه Contracts شامل واسطهای مورد نیاز برای repository logic میباشد:
namespace ASPCoreGraphQL.Contracts { public interface IOwnerRepository { } }
namespace ASPCoreGraphQL.Contracts { public interface IAccountRepository { } }
public class Owner { [Key] public Guid Id { get; set; } [Required(ErrorMessage = "Name is required")] public string Name { get; set; } public string Address { get; set; } public ICollection<Account> Accounts { get; set; } } public class Account { [Key] public Guid Id { get; set; } [Required(ErrorMessage = "Type is required")] public TypeOfAccount Type { get; set; } public string Description { get; set; } [ForeignKey("OwnerId")] public Guid OwnerId { get; set; } public Owner Owner { get; set; } } public enum TypeOfAccount { Cash, Savings, Expense, Income }
public class ApplicationContext : DbContext { public ApplicationContext(DbContextOptions options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { } public DbSet<Owner> Owners { get; set; } public DbSet<Account> Accounts { get; set; } }
public class OwnerRepository : IOwnerRepository { private readonly ApplicationContext _context; public OwnerRepository(ApplicationContext context) { _context = context; } }
public class AccountRepository : IAccountRepository { private readonly ApplicationContext _context; public AccountRepository(ApplicationContext context) { _context = context; } }
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<ApplicationContext>(opt => opt.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddScoped<IOwnerRepository, OwnerRepository>(); services.AddScoped<IAccountRepository, AccountRepository>(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2) .AddJsonOptions(options => options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore); }
dotnet add package GraphQL
dotnet add package GraphQL.Server.Transports.AspNetCore
dotnet add package GraphQL.Server.Ui.Playground
public class AppSchema : Schema { public AppSchema(IDependencyResolver resolver) :base(resolver) { } }
public class OwnerType : ObjectGraphType<Owner> { public OwnerType() { Field(x => x.Id, type: typeof(IdGraphType)).Description("Id property from the owner object."); Field(x => x.Name).Description("Name property from the owner object."); Field(x => x.Address).Description("Address property from the owner object."); } }
public interface IOwnerRepository { IEnumerable<Owner> GetAll(); } public class OwnerRepository : IOwnerRepository { private readonly ApplicationContext _context; public OwnerRepository(ApplicationContext context) { _context = context; } public IEnumerable<Owner> GetAll() => _context.Owners.ToList(); }
public class AppQuery : ObjectGraphType { public AppQuery(IOwnerRepository repository) { Field<ListGraphType<OwnerType>>( "owners", resolve: context => repository.GetAll() ); } }
public class AppSchema : Schema { public AppSchema(IDependencyResolver resolver) :base(resolver) { Query = resolver.Resolve<AppQuery>(); } }
public void ConfigureServices(IServiceCollection services) { ... services.AddScoped<IDependencyResolver>(s => new FuncDependencyResolver(s.GetRequiredService)); services.AddScoped<AppSchema>(); services.AddGraphQL(o => { o.ExposeExceptions = false; }) .AddGraphTypes(ServiceLifetime.Scoped); ... }
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { ... app.UseGraphQL<AppSchema>(); app.UseGraphQLPlayground(options: new GraphQLPlaygroundOptions()); app.UseMvc(); }
dotnet run
https://localhost:5001/ui/playground
@if (!SecurityService.IsAuthenticated) { <li>@Html.ActionLink("ورود", "Login", "Main")</li> }
public abstract class CustomViewPage : ViewPage { public CustomViewPage(IUserService userService, ISecurityService securityService, IUnitOfWork uow) { Uow = uow; SecurityService = securityService; UserService = userService; } public IUserService UserService { get; private set; } public ISecurityService SecurityService { get; private set; } public IUnitOfWork Uow { get; private set; } } public abstract class CustomViewPage<TModel> : ViewPage<TModel> { public CustomViewPage(IUserService userService, ISecurityService securityService, IUnitOfWork uow) { Uow = uow; SecurityService = securityService; UserService = userService; } public IUserService UserService { get; private set; } public ISecurityService SecurityService { get; private set; } public IUnitOfWork Uow { get; private set; } }
public class Kala { [Key] public int Kala_id { get; set; } [DisplayName("نام کالا")] public string Name { get; set; } [DisplayName("قیمت خرید")] public double Fee_Kharid { get; set; } public virtual Brand Brand { get; set; } public ICollection<Anbar_Kala> Anbar_Kalas { get; set; } } public class Anbar_Kala { [ForeignKey("Anbar_Id")] public virtual Anbar Anbar { get; set; } public int Anbar_Id { get; set; } [ForeignKey("Kala_Id")] public virtual Kala Kala{ get; set; } public int Kala_Id { get; set; } [DisplayName("تعداد")] public int Tedad { get; set; } //تعداد کالاها در هر انبار } public class KalaViewModel { public int Kala_Id { get; set; } public string Name { get; set; } public double Fee_Kharid { get; set; } public string Brand_Name { get; set; } public int Tedad { get; set; } } //controller var kala = _Kala_Service.GetAllKalas(); var tedad= _Anbar_Kala_Service.GetAllAnbar_Kalas(); var kalaviewmodel = EntityMapper.Map<List<KalaViewModel>>(kala, tedad); protected override void Configure() { Mapper.CreateMap<Kala, KalaViewModel>() .ForMember(des => des.Brand_Name, op => op.MapFrom(src => src.Brand.Brand_Name)); Mapper.CreateMap<Anbar_Kala, KalaViewModel>(); // این نگاشت باید به چه صورتی باشد؟ .ForMember(des =>des.Kala_Id, op=>op.Ignore(); }
public class MyBaseEntity { public int Id {get;set;} }
public class Student : MyBaseEntity { public string Name {get;set;} //... }
public class SomeGenericWorker <TEntity> where TEntity : BaseEntity { //... public void DoSth(TEntity entity) { if (entity is Student) { // ... } } }
using System; using SimpleCqrs.Domain; namespace CqrsPattern.Cqrs.Command { public class Account : AggregateRoot { public Account(Guid id) { Apply(new AccountCreatedEvent { AggregateRootId = id }); } public void SetName(string firstName, string lastName) { Apply(new AccountNameSetEvent { FirstName = firstName, LastName = lastName }); } public void OnAccountCreated(AccountCreatedEvent evt) { Id = evt.AggregateRootId; } } }
using SimpleCqrs.Commanding; namespace CqrsPattern.Cqrs.Command { public class CreateAccountCommand : ICommand { public string FirstName { get; set; } public string LastName { get; set; } } }
using System; using SimpleCqrs.Commanding; using SimpleCqrs.Domain; namespace CqrsPattern.Cqrs.Command { public class CreateAccountCommandHandler : CommandHandler<CreateAccountCommand> { private readonly IDomainRepository repository; public CreateAccountCommandHandler(IDomainRepository repository) { this.repository = repository; } public override void Handle(CreateAccountCommand command) { var account = new Account(Guid.NewGuid()); account.SetName(command.FirstName, command.LastName); repository.Save(account); } } }
using SimpleCqrs.Eventing; namespace CqrsPattern.Cqrs.Command { public class AccountCreatedEvent : DomainEvent { } }
using SimpleCqrs.Eventing; namespace CqrsPattern.Cqrs.Command { public class AccountNameSetEvent : DomainEvent { public string FirstName { get; set; } public string LastName { get; set; } } }
using System.Linq; using SimpleCqrs.Eventing; using CqrsPattern.Cqrs.Db; namespace CqrsPattern.Cqrs.Command { public class AccountEventHandler : IHandleDomainEvents<AccountCreatedEvent>, IHandleDomainEvents<AccountNameSetEvent> { private readonly FakeAccountTable accountTable; public AccountEventHandler(FakeAccountTable accountTable) { this.accountTable = accountTable; } public void Handle(AccountCreatedEvent domainEvent) { accountTable.Add(new FakeAccountTableRow { Id = domainEvent.AggregateRootId }); } public void Handle(AccountNameSetEvent domainEvent) { var account = accountTable.Single(x => x.Id == domainEvent.AggregateRootId); account.Name = domainEvent.FirstName + " " + domainEvent.LastName; } } }
using System.Collections.Generic; namespace CqrsPattern.Cqrs.Db { public class FakeAccountTable : List<FakeAccountTableRow> { } }
using System; namespace CqrsPattern.Cqrs.Db { public class FakeAccountTableRow { public Guid Id { get; set; } public string Name { get; set; } } }
using SimpleCqrs; using SimpleCqrs.Unity; namespace CqrsPattern { public class SampleRunTime : SimpleCqrsRuntime<UnityServiceLocator> { } }
using System; namespace CqrsPattern.Cqrs.Query { public class AccountReadModel { public string Name { get; set; } public Guid Id { get; set; } } }
using CqrsPattern.Cqrs.Db; using System.Collections.Generic; using System.Linq; namespace CqrsPattern.Cqrs.Query { public class AccountReportReadService { private FakeAccountTable fakeAccountDb; public AccountReportReadService(FakeAccountTable fakeAccountDb) { this.fakeAccountDb = fakeAccountDb; } public IEnumerable<AccountReadModel> GetAccounts() { return from a in fakeAccountDb select new AccountReadModel { Id = a.Id, Name = a.Name }; } } }
using System; using SimpleCqrs.Commanding; using CqrsPattern.Cqrs.Query; using CqrsPattern.Cqrs.Command; namespace CqrsPattern { class Program { static void Main(string[] args) { var runtime = new SampleRunTime(); runtime.Start(); var fakeAccountTable = new FakeAccountTable(); runtime.ServiceLocator.Register(fakeAccountTable); runtime.ServiceLocator.Register(new AccountReportReadService(fakeAccountTable)); var commandBus = runtime.ServiceLocator.Resolve<ICommandBus>(); var cmd = new CreateAccountCommand { FirstName = "Ali", LastName = "Kh" }; commandBus.Send(cmd); var accountReportReadModel = runtime.ServiceLocator.Resolve<AccountReportReadService>(); Console.WriteLine("Accounts in database"); Console.WriteLine("####################"); foreach (var account in accountReportReadModel.GetAccounts()) { Console.WriteLine(" Id: {0} Name: {1}", account.Id, account.Name); } runtime.Shutdown(); Console.ReadLine(); } } }
public override void Handle(CreateAccountCommand command) { var account = new Account(Guid.NewGuid()); //line 1 account.SetName(command.FirstName, command.LastName); //line 2 repository.Save(account); //line 3 }
public Account(Guid id) { Apply(new AccountCreatedEvent { AggregateRootId = id }); }
public void SetName(string firstName, string lastName) { Apply(new AccountNameSetEvent { FirstName = firstName, LastName = lastName }); }
public void Handle(AccountCreatedEvent domainEvent) { accountTable.Add(new FakeAccountTableRow { Id = domainEvent.AggregateRootId }); } public void Handle(AccountNameSetEvent domainEvent) { var account = accountTable.Single(x => x.Id == domainEvent.AggregateRootId); account.Name = domainEvent.FirstName + " " + domainEvent.LastName; }
var accountReportReadModel = runtime.ServiceLocator.Resolve<AccountReportReadService>(); var accounts = accountReportReadModel.GetAccounts();
namespace Refactoring.Day1.EncapsulateCollection
{
public class OrderItem
{
public int Id { set; get; }
public string Name { set; get; }
public int Amount { set; get; }
}
}
using System.Collections.Generic;
namespace Refactoring.Day1.EncapsulateCollection
{
public class Orders
{
public List<OrderItem> OrderItems { set; get; }
}
}
Error, Certainty 95, for Do Not Expose Generic Lists
Warning, Certainty 75, for Collection Properties Should Be ReadOnly
using System.Linq;
using System.Collections.Generic;
namespace Refactoring.Day1.EncapsulateCollection
{
public class Orders
{
private int _orderTotal;
private List<OrderItem> _orderItems;
public IEnumerable<OrderItem> OrderItems
{
get { return _orderItems; }
}
public void AddOrderItem(OrderItem orderItem)
{
_orderTotal += orderItem.Amount;
_orderItems.Add(orderItem);
}
public void RemoveOrderItem(OrderItem orderItem)
{
var order = _orderItems.Find(o => o == orderItem);
if (order == null) return;
_orderTotal -= orderItem.Amount;
_orderItems.Remove(orderItem);
}
}
}
<?xml version="1.0" encoding="UTF-8" ? /> <OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"> <ShortName>My Site's Asset Finder</ShortName> <Description>Find all your assets</Description> <Url type="text/html" method="get" template="http://MySite.com/Home/Search/?q=searchTerms"/> <InputEncoding>UTF-8</InputEncoding> <SearchForm>http://MySite.com/</SearchForm> </OpenSearchDescription>
using System; using System.Text; using System.Web; using System.Web.Mvc; using System.Xml; namespace WebToolkit { public class OpenSearchResult : ActionResult { public string ShortName { set; get; } public string Description { set; get; } public string SearchForm { set; get; } public string FavIconUrl { set; get; } public string SearchUrlTemplate { set; get; } public override void ExecuteResult(ControllerContext context) { if (context == null) throw new ArgumentNullException("context"); var response = context.HttpContext.Response; writeToResponse(response); } private void writeToResponse(HttpResponseBase response) { response.ContentEncoding = Encoding.UTF8; response.ContentType = "application/opensearchdescription+xml"; using (var xmlWriter = XmlWriter.Create(response.Output, new XmlWriterSettings { Indent = true })) { xmlWriter.WriteStartElement("OpenSearchDescription", "http://a9.com/-/spec/opensearch/1.1/"); xmlWriter.WriteElementString("ShortName", ShortName); xmlWriter.WriteElementString("Description", Description); xmlWriter.WriteElementString("InputEncoding", "UTF-8"); xmlWriter.WriteElementString("SearchForm", SearchForm); xmlWriter.WriteStartElement("Url"); xmlWriter.WriteAttributeString("type", "text/html"); xmlWriter.WriteAttributeString("template", SearchUrlTemplate); xmlWriter.WriteEndElement(); xmlWriter.WriteStartElement("Image"); xmlWriter.WriteAttributeString("width", "16"); xmlWriter.WriteAttributeString("height", "16"); xmlWriter.WriteString(FavIconUrl); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); xmlWriter.Close(); } } } }
using System.Web.Mvc; namespace Readers { public partial class OpenSearchController : Controller { public virtual ActionResult Index() { var fullBaseUrl = Url.Action(result: MVC.Home.Index(), protocol: "http"); return new OpenSearchResult { ShortName = ".NET Tips", Description = ".NET Tips Contents Search", SearchForm = fullBaseUrl, FavIconUrl = fullBaseUrl + "favicon.ico", SearchUrlTemplate = Url.Action(result: MVC.Search.Index(), protocol: "http") + "?term={searchTerms}" }; } } }
<link href="@Url.Action(result: MVC.OpenSearch.Index(), protocol: "http")" rel="search" title=".NET Tips Search" type="application/opensearchdescription+xml" />