سلام. مراجعه کنید به Asp.Net Identity #2 . فقط کافیه که یک Connection String تعریف کنید واسه ارتباط به پایگاه داده و یک کلید که معرف کلاس شروع Owin هست . نیاز به تنظیمات اضافهتری نداره.
نظرات مطالب
{ "name": "asp.net", "private": true, "dependencies": { "bootstrap": "3.3.6", "jquery": "2.2.0", "jquery-validation": "1.14.0", "jquery-validation-unobtrusive": "3.2.6", "jquery-ajax-unobtrusive": "3.2.4" } }
[ { "outputFileName": "wwwroot/css/site.min.css", "inputFiles": [ "bower_components/bootstrap/dist/css/bootstrap.min.css", "content/site.css" ] }, { "outputFileName": "wwwroot/js/site.min.js", "inputFiles": [ "bower_components/jquery/dist/jquery.min.js", "bower_components/jquery-validation/dist/jquery.validate.min.js", "bower_components/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js", "bower_components/jquery-ajax-unobtrusive/jquery.unobtrusive-ajax.min.js", "bower_components/bootstrap/dist/js/bootstrap.min.js" ], "minify": { "enabled": true, "renameLocals": true }, "sourceMap": false } ]
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - My ASP.NET Application</title> <link href="~/css/site.min.css" rel="stylesheet" /> </head> <body> <div> <div> @RenderBody() </div> </div> <script src="~/js/site.min.js" type="text/javascript" asp-append-version="true"></script> @RenderSection("Scripts", required: false) </body> </html>
HTML attribute | AjaxOptions |
data-ajax-confirm | Confirm |
data-ajax-method | HttpMethod |
data-ajax-mode | InsertionMode |
data-ajax-loading-duration | LoadingElementDuration |
data-ajax-loading | LoadingElementId |
data-ajax-begin | OnBegin |
data-ajax-complete | OnComplete |
data-ajax-failure | OnFailure |
data-ajax-success | OnSuccess |
data-ajax-update | UpdateTargetId |
data-ajax-url | Url |
parameters | Callback |
xhr, status | data-ajax-complete |
data, status, xhr | data-ajax-success |
xhr, status, error | data-ajax-failure |
data-ajax-success = "myJsMethod"
function myJsMethod(data, status, xhr) { }
return Json(new { param1 = 1, param2 = 2, ... });
using System.ComponentModel.DataAnnotations; namespace Core1RtmEmptyTest.ViewModels.Account { public class RegisterViewModel { [Required] [EmailAddress] [Display(Name = "Email")] public string Email { get; set; } } }
@using Core1RtmEmptyTest.ViewModels.Account @model RegisterViewModel @{ } <form method="post" asp-controller="TestAjax" asp-action="Index" asp-route-returnurl="@ViewBag.ReturnUrl" class="form-horizontal" role="form" data-ajax="true" data-ajax-loading="#Progress" data-ajax-success="myJsMethod"> <input asp-for="Email" class="form-control" /> <span asp-validation-for="Email" class="text-danger"></span> <button type="submit">ارسال</button> <div id="Progress" style="display: none"> <img src="images/loading.gif" alt="loading..." /> </div> </form> @section scripts{ <script type="text/javascript"> function myJsMethod(data, status, xhr) { alert(data.param1); } </script> }
using Core1RtmEmptyTest.ViewModels.Account; using Microsoft.AspNetCore.Mvc; namespace Core1RtmEmptyTest.Controllers { public class TestAjaxController : Controller { public IActionResult Index() { return View(); } [HttpPost] public IActionResult Index([FromForm]RegisterViewModel vm) { var ajax = isAjax(); if (ajax) { // it's an ajax post } if (ModelState.IsValid) { //todo: save data return Json(new { param1 = 1, param2 = 2 }); } return View(); } private bool isAjax() { return Request?.Headers != null && Request.Headers["X-Requested-With"] == "XMLHttpRequest"; } } }
<div id="EmployeeInfo"> <a asp-controller="MyController" asp-action="MyAction" data-ajax="true" data-ajax-loading="#Progress" data-ajax-method="POST" data-ajax-mode="replace" data-ajax-update="#EmployeeInfo"> Get Employee-1 info </a> <div id="Progress" style="display: none"> <img src="images/loading.gif" alt="loading..." /> </div> </div>
public IActionResult Index([FromBody] MyViewModel vm) { return View(); }
data-val-remote="کلمه عبور وارد شده را راحت می‌توان حدس زد!" data-val-remote-additionalfields="*.Password1" data-val-remote-type="POST" data-val-remote-url="/register/checkpassword"
export class EmailValidatorDirective implements Validator {
export class RemoteValidatorDirective implements AsyncValidator {
validate(c: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null>;
>ng g d CustomValidators/RemoteValidator -m custom-validators.module
import { Directive, Input } from "@angular/core"; import { AsyncValidator, AbstractControl, NG_ASYNC_VALIDATORS } from "@angular/forms"; import { Http, RequestOptions, Response, Headers } from "@angular/http"; import "rxjs/add/operator/map"; import "rxjs/add/operator/distinctUntilChanged"; import "rxjs/add/operator/takeUntil"; import "rxjs/add/operator/take"; import { Observable } from "rxjs/Observable"; import { Subject } from "rxjs/Subject"; @Directive({ selector: "[appRemoteValidator][formControlName],[appRemoteValidator][formControl],[appRemoteValidator][ngModel]", providers: [ { provide: NG_ASYNC_VALIDATORS, useExisting: RemoteValidatorDirective, multi: true } ] }) export class RemoteValidatorDirective implements AsyncValidator { @Input("remote-url") remoteUrl: string; @Input("remote-field") remoteField: string; @Input("remote-additional-fields") remoteAdditionalFields: string; constructor(private http: Http) {} validate(control: AbstractControl): Observable<{ [key: string]: any }> { if (!this.remoteUrl || this.remoteUrl === undefined) { return Observable.throw("`remoteUrl` is undefined."); } if (!this.remoteField || this.remoteField === undefined) { return Observable.throw("`remoteField` is undefined."); } const dataObject = {}; if ( this.remoteAdditionalFields && this.remoteAdditionalFields !== undefined ) { const otherFields = this.remoteAdditionalFields.split(","); otherFields.forEach(field => { const name = field.trim(); const otherControl = control.root.get(name); if (otherControl) { dataObject[name] = otherControl.value; } }); } // This is used to signal the streams to terminate. const changed$ = new Subject<any>(); changed$.next(); // This will signal the previous stream (if any) to terminate. const debounceTime = 400; return new Observable((obs: any) => { control.valueChanges .takeUntil(changed$) .take(1) .debounceTime(debounceTime) .distinctUntilChanged() .flatMap(term => { dataObject[this.remoteField] = term; return this.doRemoteValidation(dataObject); }) .subscribe( (result: IRemoteValidationResult) => { if (result.result) { obs.next(null); } else { obs.next({ remoteValidation: { remoteValidationMessage: result.message } }); } obs.complete(); }, error => { obs.next(null); obs.complete(); } ); }); } private doRemoteValidation(data: any): Observable<IRemoteValidationResult> { const headers = new Headers({ "Content-Type": "application/json" }); // for ASP.NET MVC const options = new RequestOptions({ headers: headers }); return this.http .post(this.remoteUrl, JSON.stringify(data), options) .map(this.extractData) .do(result => console.log("remoteValidation result: ", result)) .catch(this.handleError); } private extractData(res: Response): IRemoteValidationResult { const body = <IRemoteValidationResult>res.json(); return body || (<IRemoteValidationResult>{}); } private handleError(error: Response): Observable<any> { console.error("observable error: ", error); return Observable.throw(error.statusText); } } export interface IRemoteValidationResult { result: boolean; message: string; }
@Directive({ selector: "[appRemoteValidator][formControlName],[appRemoteValidator][formControl],[appRemoteValidator][ngModel]", providers: [ { provide: NG_ASYNC_VALIDATORS, useExisting: RemoteValidatorDirective, multi: true } ] })
export class RemoteValidatorDirective implements AsyncValidator { @Input("remote-url") remoteUrl: string; @Input("remote-field") remoteField: string; @Input("remote-additional-fields") remoteAdditionalFields: string;
<input #username="ngModel" required maxlength="8" minlength="4" type="text" appRemoteValidator [remote-url]="remoteUsernameValidationUrl" remote-field="FirstName" remote-additional-fields="email,password" class="form-control" name="username" [(ngModel)]="model.username">
export class UserRegisterComponent implements OnInit { remoteUsernameValidationUrl = "api/Employee/CheckUser";
[remote-field]="'FirstName'"
export interface IRemoteValidationResult { result: boolean; message: string; }
namespace AngularTemplateDrivenFormsLab.Controllers { [Route("api/[controller]")] public class EmployeeController : Controller { [HttpPost("[action]")] [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult CheckUser([FromBody] Employee model) { var remoteValidationResult = new { result = true, message = $"{model.FirstName} is fine!" }; if (model.FirstName?.Equals("Vahid", StringComparison.OrdinalIgnoreCase) ?? false) { remoteValidationResult = new { result = false, message = "username:`Vahid` is already taken." }; } return Json(remoteValidationResult); } } }
<div class="form-group" [class.has-error]="username.invalid && username.touched"> <label class="control-label">User Name</label> <input #username="ngModel" required maxlength="8" minlength="4" type="text" appRemoteValidator [remote-url]="remoteUsernameValidationUrl" remote-field="FirstName" remote-additional-fields="email,password" class="form-control" name="username" [(ngModel)]="model.username"> <div *ngIf="username.pending" class="alert alert-warning"> Checking server, Please wait ... </div> <div *ngIf="username.invalid && username.touched"> <div class="alert alert-danger" *ngIf="username.errors.remoteValidation"> {{username.errors.remoteValidation.remoteValidationMessage}} </div> </div> </div>
obs.next({ remoteValidation: { remoteValidationMessage: result.message } });
// This is used to signal the streams to terminate. const changed$ = new Subject<any>(); changed$.next(); // This will signal the previous stream (if any) to terminate. const debounceTime = 400; return new Observable((obs: any) => { control.valueChanges .takeUntil(changed$) .take(1) .debounceTime(debounceTime) .distinctUntilChanged()
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); FluentValidationModelValidatorProvider.Configure(); }
[Validator(typeof(PersonValidator))] public class Person { public int Id { get; set; } public string Name { get; set; } public string Email { get; set; } public int Age { get; set; } } public class PersonValidator : AbstractValidator<Person> { public PersonValidator() { RuleFor(x => x.Id).NotNull(); RuleFor(x => x.Name).Length(0, 10); RuleFor(x => x.Email).EmailAddress(); RuleFor(x => x.Age).InclusiveBetween(18, 60); } }
public class PeopleController : Controller { public ActionResult Create() { return View(); } [HttpPost] public ActionResult Create(Person person) { if(! ModelState.IsValid) { // re-render the view when validation failed. return View("Create", person); } TempData["notice"] = "Person successfully created"; return RedirectToAction("Index"); } }
@Html.ValidationSummary() @using (Html.BeginForm()) { Id: @Html.TextBoxFor(x => x.Id) @Html.ValidationMessageFor(x => x.Id) <br /> Name: @Html.TextBoxFor(x => x.Name) @Html.ValidationMessageFor(x => x.Name) <br /> Email: @Html.TextBoxFor(x => x.Email) @Html.ValidationMessageFor(x => x.Email) <br /> Age: @Html.TextBoxFor(x => x.Age) @Html.ValidationMessageFor(x => x.Age) <input type="submit" value="submit" /> }
public ActionResult Save([CustomizeValidator(RuleSet="MyRuleset")] Customer cust) { // ... }
public interface IValidatorFactory { IValidator<T> GetValidator<T>(); IValidator GetValidator(Type type); }
ObjectFactory.Configure(cfg => cfg.AddRegistry(new MyRegistry())); public class MyRegistry : Registry { public MyRegistry() { For<IValidator<Person>>() .Singleton() .Use<PersonValidator>(); } }
public class MyRegistry : Registry { public MyRegistry() { AssemblyScanner.FindValidatorsInAssemblyContaining<MyValidator>() .ForEach(result => { For(result.InterfaceType) .Singleton() .Use(result.ValidatorType); }); } }
protected void Application_Start() { RegisterRoutes(RouteTable.Routes); //Configure structuremap ObjectFactory.Configure(cfg => cfg.AddRegistry(new MyRegistry())); ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory()); //Configure FV to use StructureMap var factory = new StructureMapValidatorFactory(); //Tell MVC to use FV for validation ModelValidatorProviders.Providers.Add(new FluentValidationModelValidatorProvider(factory)); DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false; }
public class User : IdentityUser<int, UserClaim, UserRole, UserLogin>