کردیت کارت داشتی باشی، هزینهاش را پرداخت میکنی و یک کلید API دریافت خواهی کرد. مانند تمام سرویسهای پولی دیگر.
نظرات اشتراکها
using System.Windows; using StructureMap; namespace WpfFramework1999.Common.MVVM { /// <summary> /// Stitches together a view and its view-model /// </summary> public class ViewModelFactory { private readonly FrameworkElement _control; /// <summary> /// سازنده کلاس تزریق وابستگیها به ویوو مدل و وهله سازی آن /// </summary> /// <param name="control">وهلهای از شیءایی که باید کار تزریق وابستگیها در آن انجام شود</param> public ViewModelFactory(FrameworkElement control) { _control = control; } /// <summary> /// وهله متناظر با ویوو مدل /// </summary> public IViewModel ViewModelInstance { get; private set; } /// <summary> /// کار تزریق خودکار وابستگیها و وهله سازی ویوو مدل مرتبط انجام خواهد شد /// </summary> public void WireUp() { var viewName = _control.GetType().Name; var viewModelName = string.Concat(viewName, "ViewModel"); //قرار داد نامگذاری ما است if (!_control.IsLoaded) { _control.Loaded += (s, e) => { setDataContext(viewModelName); }; } else { setDataContext(viewModelName); } } private void setDataContext(string viewModelName) { //کار تزریق خودکار وابستگیها و وهله سازی ویوو مدل مرتبط انجام خواهد شد ViewModelInstance = ObjectFactory.TryGetInstance<IViewModel>(viewModelName); if (ViewModelInstance == null) // این صفحه ویوو مدل ندارد return; _control.DataContext = ViewModelInstance; } } }
/// <summary> /// ویوو مدل افزودن و مدیریت کاربران /// </summary> public class AddNewUserViewModel : BaseViewModel
/// <summary> /// کلاس پایه ویوو مدلهای برنامه که جهت علامتگذاری آنها برای سیم کشیهای تزریق وابستگیهای برنامه نیز استفاده میشود /// </summary> public abstract class BaseViewModel : DataErrorInfoBase, INotifyPropertyChanged, IViewModel
// Add all types that implement IView into the container, // and name each specific type by the short type name. scan.AddAllTypesOf<IViewModel>().NameBy(type => type.Name);
//کار تزریق خودکار وابستگیها و وهله سازی ویوو مدل مرتبط انجام خواهد شد ViewModelInstance = ObjectFactory.TryGetInstance<IViewModel>(viewModelName);
namespace WpfFramework.Infrastructure.Core { /// <summary> /// ایجاد یک کنترل فریم سفارشی که قابلیت تزریق وابستگیها را به صورت خودکار دارد /// به همراه اعمال مسایل راهبری برنامه که از منوی اصلی دریافت میشوند /// </summary> public class FrameFactory : Frame { /// <summary> /// در اینجا میشود به وهلهای از صفحهای که قرار است اضافه گردد دسترسی یافت /// </summary> protected override void OnContentChanged(object oldContent, object newContent) { base.OnContentChanged(oldContent, newContent); var newPage = newContent as FrameworkElement; if (newPage == null) return; _currentViewModelFactory = new ViewModelFactory(newPage); _currentViewModelFactory.WireUp(); //کار تزریق وابستگیها و وهله سازی ویوو مدل مرتبط انجام خواهد شد } } }
> create-react-app sample-15 > cd sample-15 > npm start
> npm install --save bootstrap
import "bootstrap/dist/css/bootstrap.css";
> npm i react-router-dom --save
import { BrowserRouter } from "react-router-dom";
ReactDOM.render( <BrowserRouter> <App /> </BrowserRouter>, document.getElementById("root") );
import React from "react"; const NavBar = () => { return ( <nav className="navbar bg-dark navbar-dark navbar-expand-sm"> <div className="navbar-nav"> <a className="nav-item nav-link" href="/"> Home </a> <a className="nav-item nav-link" href="/products"> Products </a> <a className="nav-item nav-link" href="/posts/2018/06"> Posts </a> <a className="nav-item nav-link" href="/admin"> Admin </a> </div> </nav> ); }; export default NavBar;
import "./App.css"; import React, { Component } from "react"; import NavBar from "./components/navbar"; class App extends Component { render() { return ( <div> <NavBar /> </div> ); } } export default App;
import "./App.css"; import React, { Component } from "react"; import { Route } from "react-router-dom"; import Dashboard from "./components/admin/dashboard"; import Home from "./components/home"; import NavBar from "./components/navbar"; import Posts from "./components/posts"; import Products from "./components/products"; class App extends Component { render() { return ( <div> <NavBar /> <div className="container"> <Route path="/products" component={Products} /> <Route path="/posts" component={Posts} /> <Route path="/admin" component={Dashboard} /> <Route path="/" component={Home} /> </div> </div> ); } } export default App;
import React, { Component } from "react"; class Products extends Component { state = { products: [ { id: 1, name: "Product 1" }, { id: 2, name: "Product 2" }, { id: 3, name: "Product 3" } ] }; render() { return ( <div> <h1>Products</h1> <ul> {this.state.products.map(product => ( <li key={product.id}> <a href={`/products/${product.id}`}>{product.name}</a> </li> ))} </ul> </div> ); } } export default Products;
import React from "react"; const Home = () => { return <h1>Home</h1>; }; export default Home;
import React from "react"; const Posts = () => { return ( <div> <h1>Posts</h1> Year: , Month: </div> ); }; export default Posts;
import React from "react"; const Dashboard = ({ match }) => { return ( <div> <h1>Admin Dashboard</h1> </div> ); }; export default Dashboard;
<div className="container"> <Route path="/products" component={Products} /> <Route path="/posts" component={Posts} /> <Route path="/admin" component={Dashboard} /> <Route path="/" component={Home} /> </div>
<Route path="/" exact component={Home} />
import { Route, Switch } from "react-router-dom";
class App extends Component { render() { return ( <div> <NavBar /> <div className="container"> <Switch> <Route path="/products" component={Products} /> <Route path="/posts" component={Posts} /> <Route path="/admin" component={Dashboard} /> <Route path="/" component={Home} /> </Switch> </div> </div> ); } }
import React from "react"; import { Link } from "react-router-dom"; const NavBar = () => { return ( <nav className="navbar bg-dark navbar-dark navbar-expand-sm"> <div className="navbar-nav"> <Link className="nav-item nav-link" to="/"> Home </Link> <Link className="nav-item nav-link" to="/products"> Products </Link> <Link className="nav-item nav-link" to="/posts/2018/06"> Posts </Link> <Link className="nav-item nav-link" to="/admin"> Admin </Link> </div> </nav> ); }; export default NavBar;
<Route path="/products" render={() => <Products param1="123" param2="456" />} />
<Route path="/products" render={props => ( <Products param1="123" param2="456" {...props} /> )} />
using var dbContext = new MyDbContext(); var objectToDelete = await dbContext.Objects.FirstAsync(o => o.Id == id); dbContext.Objects.Remove(objectToDelete); await dbContext.SaveChangesAsync();
using var dbContext = new MyDbContext(); var objectToDelete = new MyObject { Id = id }; dbContext.Objects.Remove(objectToDelete); await dbContext.SaveChangesAsync();
await dbContext.Objects.Where(x => x.Id == id).ExecuteDeleteAsync();
public class User { public int Id { get; set; } public required string FirstName { get; set; } public required string LastName { get; set; } public virtual List<Book> Books { get; set; } = new(); public virtual Address? Address { get; set; } } public class Book { public int Id { get; set; } public required string Type { get; set; } public required string Name { get; set; } public virtual User User { get; set; } = default!; public int UserId { get; set; } } public class Address { public int Id { get; set; } public required string Street { get; set; } public virtual User User { get; set; } = default!; public int UserId { get; set; } }
public class ApplicationDbContext : DbContext { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } public DbSet<User> Users { get; set; } = default!; public DbSet<Book> Books { get; set; } = default!; public DbSet<Address> Addresses { get; set; } = default!; }
context.Books.Where(book => book.Name.Contains("1")).ExecuteDelete();
DELETE FROM [b] FROM [Books] AS [b] WHERE [b].[Name] LIKE N'%1%'
context.Users.Where(user => user.Id <= 500).ExecuteDelete();
DELETE FROM [u] FROM [Users] AS [u] WHERE [u].[Id] <= 500 The DELETE statement conflicted with the REFERENCE constraint "FK_Books_Users_UserId". The conflict occurred in database "EF7BulkOperations", table "dbo.Books", column 'UserId'.
public class ApplicationDbContext : DbContext { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } public DbSet<User> Users { get; set; } = default!; public DbSet<Book> Books { get; set; } = default!; public DbSet<Address> Addresses { get; set; } = default!; protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder .Entity<User>() .HasMany(user => user.Books) .WithOne(book => book.User) .OnDelete(DeleteBehavior.Cascade); modelBuilder .Entity<User>() .HasOne(user => user.Address) .WithOne(address => address.User) .HasForeignKey<Address>(address => address.UserId) .OnDelete(DeleteBehavior.Cascade); } }
context.Users.Where(user => user.Id <= 400) .ExecuteUpdate(p => p.SetProperty(user => user.LastName, user => "Updated"));
UPDATE [u] SET [u].[LastName] = N'Updated' FROM [Users] AS [u] WHERE [u].[Id] <= 400
context.Users.Where(user => user.Id <= 300) .ExecuteUpdate(p => p.SetProperty(user => user.LastName, user => "Updated" + user.LastName));
UPDATE [u] SET [u].[LastName] = N'Updated' + [u].[LastName] FROM [Users] AS [u] WHERE [u].[Id] <= 300
context.Users.Where(user => user.Id <= 800) .ExecuteUpdate(p => p.SetProperty(user => user.LastName, user => "Updated" + user.LastName) .SetProperty(user => user.FirstName, user => "Updated" + user.FirstName));
UPDATE [u] SET [u].[FirstName] = N'Updated' + [u].[FirstName], [u].[LastName] = N'Updated' + [u].[LastName] FROM [Users] AS [u] WHERE [u].[Id] <= 800
<form #f="ngForm" (ngSubmit)="onSubmit(f.form)"> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title"> Add Product </h3> </div> <div class="panel-body form-horizontal"> <div class="form-group"> <label for="productName" class="col col-md-2 control-label">Name</label> <div class="controls col col-md-10"> <input ngControl="productName" id="productName" required #productName="ngForm" (change)="log(productName)" minlength="3" type="text" class="form-control" [(ngModel)]="productModel.productName"/> <div *ngIf="productName.touched && productName.errors"> <label class="text-danger" *ngIf="productName.errors.required"> Name is required. </label> <label class="text-danger" *ngIf="productName.errors.minlength"> Name should be minimum {{ productName.errors.minlength.requiredLength }} characters. </label> </div> </div> </div> <div class="form-group"> <label for="productCode" class="col col-md-2 control-label">Code</label> <div class="controls col col-md-10"> <input ngControl="productCode" id="productCode" required #productCode="ngForm" type="text" class="form-control" [(ngModel)]="productModel.productCode"/> <label class="text-danger" *ngIf="productCode.touched && !productCode.valid"> Code is required. </label> </div> </div> <div class="form-group"> <label for="releaseDate" class="col col-md-2 control-label">Release Date</label> <div class="controls col col-md-10"> <input ngControl="releaseDate" id="releaseDate" required #releaseDate="ngForm" type="text" class="form-control" [(ngModel)]="productModel.releaseDate"/> <label class="text-danger" *ngIf="releaseDate.touched && !releaseDate.valid"> Release Date is required. </label> </div> </div> <div class="form-group"> <label for="price" class="col col-md-2 control-label">Price</label> <div class="controls col col-md-10"> <input ngControl="price" id="price" required #price="ngForm" type="text" class="form-control" [(ngModel)]="productModel.price"/> <label class="text-danger" *ngIf="price.touched && !price.valid"> Price is required. </label> </div> </div> <div class="form-group"> <label for="description" class="col col-md-2 control-label">Description</label> <div class="controls col col-md-10"> <textarea ngControl="description" id="description" required #description="ngForm" rows="10" type="text" class="form-control" [(ngModel)]="productModel.description"></textarea> <label class="text-danger" *ngIf="description.touched && !description.valid"> Description is required. </label> </div> </div> <div class="form-group"> <label for="imageUrl" class="col col-md-2 control-label">Image</label> <div class="controls col col-md-10"> <input ngControl="imageUrl" id="imageUrl" required #imageUrl="ngForm" type="text" class="form-control" [(ngModel)]="productModel.imageUrl"/> <label class="text-danger" *ngIf="imageUrl.touched && !imageUrl.valid"> Image is required. </label> </div> </div> </div> <footer class="panel-footer"> <button [disabled]="!f.valid" type="submit" class="btn btn-primary"> Submit </button> </footer> </div> </form>
import { Component } from 'angular2/core'; import { Router } from 'angular2/router'; import { IProduct } from './product'; import { ProductService } from './product.service'; @Component({ //selector: 'product-form', templateUrl: 'app/products/product-form.component.html' }) export class ProductFormComponent { productModel = <IProduct>{}; // creates an empty object of an interface constructor(private _productService: ProductService, private _router: Router) { } log(productName): void { console.log(productName); } onSubmit(form): void { console.log(form); console.log(this.productModel); this._productService.addProduct(this.productModel) .subscribe((product: IProduct) => { console.log(`ID: ${product.productId}`); this._router.navigate(['Products']); }); } }
<div class="form-group"> <label for="description" class="col col-md-2 control-label">Description</label> <div class="controls col col-md-10"> <textarea ngControl="description" id="description" required #description="ngForm" rows="10" type="text" class="form-control" [(ngModel)]="productModel.description"></textarea> <label class="text-danger" *ngIf="description.touched && !description.valid"> Description is required. </label> </div> </div>
<input ngControl="productName" id="productName" required #productName="ngForm" (change)="log(productName)" minlength="3" type="text" class="form-control" [(ngModel)]="productModel.productName"/>
<textarea ngControl="description" id="description" required #description="ngForm" rows="10" type="text" class="form-control"></textarea> <div class="alert alert-danger" *ngIf="description.touched && !description.valid"> Description is required. </div>
.ng-touched.ng-invalid{ border: 1px solid red; }
<div class="alert alert-danger" *ngIf="productName.touched && !productName.valid"> Name is required. </div>
<div *ngIf="productName.touched && productName.errors"> <div class="alert alert-danger" *ngIf="productName.errors.required"> Name is required. </div> <div class="alert alert-danger" *ngIf="productName.errors.minlength"> Name should be minimum 3 characters. </div> </div>
<div *ngIf="productName.touched && productName.errors"> {{ productName.errors | json }}
Name should be minimum {{ productName.errors.minlength.requiredLength }} characters.
<form #f="ngForm" (ngSubmit)="onSubmit(f.form)">
onSubmit(form): void { console.log(form); }
<button [disabled]="!f.valid" type="submit" class="btn btn-primary"> Submit </button>
//same as before... import { ProductFormComponent } from './products/product-form.component'; @Component({ //same as before… template: ` //same as before… <li><a [routerLink]="['AddProduct']">Add Product</a></li> //same as before… `, //same as before… }) @RouteConfig([ //same as before… { path: '/addproduct', name: 'AddProduct', component: ProductFormComponent } ]) //same as before...
productModel = <IProduct>{}; // creates an empty object of an interface
<textarea ngControl="description" id="description" required #description="ngForm" rows="10" type="text" class="form-control" [(ngModel)]="productModel.description"></textarea>
addProduct(product: IProduct): Observable<IProduct> { let headers = new Headers({ 'Content-Type': 'application/json' }); // for ASP.NET MVC let options = new RequestOptions({ headers: headers }); return this._http.post(this._addProductUrl, JSON.stringify(product), options) .map((response: Response) => <IProduct>response.json()) .do(data => console.log("Product: " + JSON.stringify(data))) .catch(this.handleError); }
[HttpPost] public ActionResult AddProduct(Product product) {
import { Headers, RequestOptions } from 'angular2/http';
//Same as before… import { IProduct } from './product'; import { ProductService } from './product.service'; @Component({ //Same as before… }) export class ProductFormComponent { productModel = <IProduct>{}; // creates an empty object of an interface constructor(private _productService: ProductService, private _router: Router) { } //Same as before… onSubmit(form): void { console.log(form); console.log(this.productModel); this._productService.addProduct(this.productModel) .subscribe((product: IProduct) => { console.log(`ID: ${product.productId}`); this._router.navigate(['Products']); }); } }
namespace AngularTemplateDrivenFormsLab.Models { public class Product { public int ProductId { set; get; } public string ProductName { set; get; } public decimal Price { set; get; } public bool IsAvailable { set; get; } } }
using System.Collections.Generic; namespace AngularTemplateDrivenFormsLab.Models { public static class ProductDataSource { private static readonly IList<Product> _cachedItems; static ProductDataSource() { _cachedItems = createProductsDataSource(); } public static IList<Product> LatestProducts { get { return _cachedItems; } } private static IList<Product> createProductsDataSource() { var list = new List<Product>(); for (var i = 0; i < 1500; i++) { list.Add(new Product { ProductId = i + 1, ProductName = "نام " + (i + 1), IsAvailable = (i % 2 == 0), Price = 1000 + i }); } return list; } } }
http://localhost:5000/api/Product/GetPagedProducts?sortBy=productId&isAscending=true&page=2&pageSize=7
public interface IPagedQueryModel { string SortBy { get; set; } bool IsAscending { get; set; } int Page { get; set; } int PageSize { get; set; } }
public class ProductQueryViewModel : IPagedQueryModel { // ... other properties ... public string SortBy { get; set; } public bool IsAscending { get; set; } public int Page { get; set; } public int PageSize { get; set; } }
public static class IQueryableExtensions { public static IQueryable<T> ApplyPaging<T>( this IQueryable<T> query, IPagedQueryModel model) { if (model.Page <= 0) { model.Page = 1; } if (model.PageSize <= 0) { model.PageSize = 10; } return query.Skip((model.Page - 1) * model.PageSize).Take(model.PageSize); } }
http://localhost:5000/api/Product/GetPagedProducts?sortBy=productId&isAscending=true&page=2&pageSize=7
if(model.SortBy == "f1") { query = !model.IsAscending ? query.OrderByDescending(x => x.F1) : query.OrderBy(x => x.F1); }
namespace AngularTemplateDrivenFormsLab.Utils { public static class IQueryableExtensions { public static IQueryable<T> ApplyOrdering<T>( this IQueryable<T> query, IPagedQueryModel model, IDictionary<string, Expression<Func<T, object>>> columnsMap) { if (string.IsNullOrWhiteSpace(model.SortBy) || !columnsMap.ContainsKey(model.SortBy)) { return query; } if (model.IsAscending) { return query.OrderBy(columnsMap[model.SortBy]); } else { return query.OrderByDescending(columnsMap[model.SortBy]); } } } }
var columnsMap = new Dictionary<string, Expression<Func<Product, object>>>() { ["productId"] = p => p.ProductId, ["productName"] = p => p.ProductName, ["isAvailable"] = p => p.IsAvailable, ["price"] = p => p.Price }; query = query.ApplyOrdering(queryModel, columnsMap);
using System.Collections.Generic; namespace AngularTemplateDrivenFormsLab.Models { public class PagedQueryResult<T> { public int TotalItems { get; set; } public IEnumerable<T> Items { get; set; } } }
[Route("api/[controller]")] public class ProductController : Controller { [HttpGet("[action]")] public PagedQueryResult<Product> GetPagedProducts(ProductQueryViewModel queryModel) { var pagedResult = new PagedQueryResult<Product>(); var query = ProductDataSource.LatestProducts .AsQueryable(); //TODO: Apply Filtering ... .where(p => p....) ... var columnsMap = new Dictionary<string, Expression<Func<Product, object>>>() { ["productId"] = p => p.ProductId, ["productName"] = p => p.ProductName, ["isAvailable"] = p => p.IsAvailable, ["price"] = p => p.Price }; query = query.ApplyOrdering(queryModel, columnsMap); pagedResult.TotalItems = query.Count(); query = query.ApplyPaging(queryModel); pagedResult.Items = query.ToList(); return pagedResult; } }
public PagedQueryResult<Product> GetPagedProducts(ProductQueryViewModel queryModel)
var query = ProductDataSource.LatestProducts .AsQueryable(); //TODO: Apply Filtering ... .where(p => p....) ...
var columnsMap = new Dictionary<string, Expression<Func<Product, object>>>() { ["productId"] = p => p.ProductId, ["productName"] = p => p.ProductName, ["isAvailable"] = p => p.IsAvailable, ["price"] = p => p.Price }; query = query.ApplyOrdering(queryModel, columnsMap);
var pagedResult = new PagedQueryResult<Product>(); pagedResult.TotalItems = query.Count(); query = query.ApplyPaging(queryModel); pagedResult.Items = query.ToList(); return pagedResult;
var builder = WebApplication.CreateBuilder(args); builder.Services.Configure<MvcOptions>(options => { options.AllowEmptyInputInBodyModelBinding = true; });
public IActionResult Post([FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] MyBody? body) { // body will be null if the request Content-Length == 0 }
public class ExampleController : Controller { public IActionResult Post(MyBody? body) // Nullable { // body will be null if the request Content-Length == 0 } public IActionResult Post(MyBody body) // Non-nullable { // Request will fail with a 400 and "A non-empty request body is required." // when Content-Length == 0 } }
متاسفانه صابر راستیکردار، خالق فونتهای وزیرمتن (همون فونت زیبایی که روی تلگرام دسکتاپ و گوگلداکز و...) ازش استفاده میکنیم، به سرطان مبتلا شده و در وبلاگش در این مورد مطلبی نوشته.
اگر از فونتهاش استفاده میکنیم، شاید الان دونیت ما بیشتر از قبل به کارش بیاد.