FirstName
firstName
strFirstName lblFirstName
<Company>.<Technology|Produt|Project>[.<Feature>][.<SubNamespace>]
Microsoft.Reporting.WebForms Kara.Support.Manager.Enums Kara.CSS.HQ.WebUI.Configuration
PackageManager , PacakgeConfigGenerator Circle , Utility , Package
CreateConfig , classdata CManager , ClsPackage , Config_Creator , Config1389
CenterCollection , PackageCollection
public delegate void Logger (string log); public delegate void LoggingCallback (object sender, string reason);
AddEventArgs , EditEventArgs , DeleteEventArgs
Adding , Add , Added
public delegate void <EventName>EventHandler (object sender, <EventName>EventArgs e);
public event EventHandler <AddEventArgs> Adding;
DisplayNameAttribute , MessageTypeAttribute
IComponent (اسم) IConnectionProvider (موصوف) ICloneable (صفت)
public enum FileMode { Append, Read, … }
[Flag] public enum KeyModifiers { Alt = 1, Control = 2, Shift = 4 }
public enum OperationState { DoneState, FaultState, RollbackState }
AddDays , Save , DeleteRow , BindData , Close , Open
Radius , ReportType , DataSource , Mode , CurrentCenterId
public CenterCollection Centers { get; set; }
if (list.Contains(item)) if (regularExpression.Matches(text)) if (stream.CanSeek) if (context.Created) if (form.Enabled)
if (list.IsContains(item)) if (regularExpression.Match(text)) if (stream.Seekable) if (context.IsCreated) if (form.IsEnabled)
public Color Color { get; set; }
firstName , e , id , packageId , centerName , name
public static MyType operator +(MyType left, MyType right) public static bool operator ==(MyType left, MyType right)
public static MyType operator ++(MyType value)
public static MyType operator /(MyType dividend, MyType divisor)
public static MyType operator -(MyType d1, MyType d2) // incorrect!
Area , DataBinder , PublicCacheName
_centersList _firstName _currentCenter
parameterType , packageOperationTypeId
lblName (Label) txtHeader (TextBox) btnSave (Button)
ArgumentNullException , InvalidOperaionException
System.Data
<Company>.<Component>.dll <Company>.<Project|Product|Technology>.<Component>.dll
Microsoft.CSharp.dll , Kara.CSS.Manager.dll
public int IComparer<T> {…} public delegate bool Predicate<T> (T item)
public int ISessionChannel<TSession> {…} public delegate TOutput Converter<TInput, TOutput> (TInput from) public class Nullable<T> {…} public class List<T> {…}
ArgumentExceptionIllegalCharacters ArgumentExceptionInvalidName ArgumentExceptionFileNotFound
Pascal Casing |
camel Casing |
Wrong |
Callback |
callback |
CallBack |
BitFlag |
bitFlag |
Bitflag / bitflag |
Canceled |
canceled |
Cancelled |
DoNot |
doNot |
Donot / Don’t |
|
|
|
Endpoint |
endpoint |
EndPoint / endPoint |
FileName |
fileName |
Filename / filename |
Gridline |
gridline |
GridLine / gridLine |
Hashtable |
hashtable |
HashTable / hashTable |
Id |
id |
ID |
Indexes |
indexes |
Indices |
LogOff |
logOff |
Logoff / LogOut ! |
LogOn |
logOn |
Logon / LogIn ! |
SignOut |
signOut |
Signout / SignOff |
SignIn |
signIn |
Signin / SignOn |
Metadata |
metadata |
MetaData / metaData |
Multipanel |
multipanel |
MultiPanel / multiPanel |
Multiview |
multiview |
MultiView / multiView |
Namespace |
namespace |
NameSpace / nameSpace |
Ok |
ok |
OK |
Pi |
pi |
PI |
Placeholder |
placeholder |
PlaceHolder / placeHolder |
UserName |
username |
Username / username |
WhiteSpace |
whiteSpace |
Whitespace / whitespace |
Writable |
writable |
Writeable / writeable |
public class Color { … public static Color FromArgb(…) { … } }
نگاهی به ساختار طراحی اعتبارسنجی از راه دور در ASP.NET MVC و jQuery Validator
در نگارشهای مختلف ASP.NET MVC و ASP.NET Core، ویژگی Remote سمت سرور، سبب درج یک چنین ویژگیهایی در سمت کلاینت میشود:
data-val-remote="کلمه عبور وارد شده را راحت می‌توان حدس زد!" data-val-remote-additionalfields="*.Password1" data-val-remote-type="POST" data-val-remote-url="/register/checkpassword"
- متن نمایشی خطای اعتبارسنجی.
- تعدادی فیلد اضافی که در صورت نیز از فرم استخراج میشوند و به سمت سرور ارسال خواهند شد.
- نوع روش ارسال اطلاعات به سمت سرور.
- یک URL که مشخص میکند، این اطلاعات باید به کدام اکشن متد در سمت سرور ارسال شوند.
سمت سرور هم میتواند یک true یا false را بازگشت دهد و مشخص کند که آیا اطلاعات مدنظر معتبر نیستند یا هستند.
شبیه به یک چنین ساختاری را در ادامه با ایجاد یک دایرکتیو سفارشی اعتبارسنجی برنامههای Angular تدارک خواهیم دید.
ساختار اعتبارسنجهای سفارشی async در Angular
در مطلب «نوشتن اعتبارسنجهای سفارشی برای فرمهای مبتنی بر قالبها در Angular» جزئیات نوشتن اعتبارسنجهای متداول فرمهای Angular را بررسی کردیم. این نوع اعتبارسنجها چون اطلاعاتی را به صورت Ajax ایی به سمت سرور ارسال نمیکنند، با پیاده سازی اینترفیس Validator تهیه خواهند شد:
export class EmailValidatorDirective implements Validator {
export class RemoteValidatorDirective implements AsyncValidator {
validate(c: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null>;
پیاده سازی یک اعتبارسنج از راه دور مبتنی بر Observableها در Angular
ابتدا یک دایرکتیو جدید را به نام RemoteValidator به ماژول custom-validators اضافه کردهایم:
>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 تهیه شده مانند همان مطلب «نوشتن اعتبارسنجهای سفارشی برای فرمهای مبتنی بر قالبها در Angular» است، تنها با یک تفاوت:
@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">
- ویژگی remote-field مشخص میکند که اطلاعات المان جاری با چه کلیدی به سمت سرور ارسال شود.
- ویژگی remote-additional-fields مشخص میکند که علاوه بر اطلاعات کنترل جاری، اطلاعات کدامیک از کنترلهای دیگر را نیز میتوان به سمت سرور ارسال کرد.
یک نکته:
ذکر "remote-field="FirstName به معنای انتساب مقدار رشتهای FirstName به خاصیت متناظر با ویژگی remote-field است.
انتساب ویژهی "remoteUsernameValidationUrl" به [remote-url]، به معنای انتساب مقدار متغیر remoteUsernameValidationUrl که در کامپوننت متناظر این قالب مقدار دهی میشود، به خاصیت متصل به ویژگی remote-url است.
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); } } }
همچنین اعتبارسنج سفارشی از راه دور فوق، پیامها را تنها از طریق HttpPost ارسال میکند. علت اینجا است که در حالت POST، برخلاف حالت GET میتوان اطلاعات بیشتری را بدون نگرانی از طول URL، ارسال کرد و همچنین کل درخواست، به علت وجود کاراکترهای غیرمجاز در URL (حالت GET، به درخواست یک URL از سرور تفسیر میشود)، برگشت نمیخورد.
تکمیل کامپوننت فرم ثبت نام کاربران
در ادامه تکمیل قالب user-register.component.html را مشاهده میکنید:
<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>
زمانیکه یک async validator مشغول به کار است و هنوز پاسخی را دریافت نکردهاست، خاصیت pending را به true تنظیم میکند. به این ترتیب میتوان پیام اتصال به سرور را نمایش داد:
همچنین چون در اینجا نحوهی طراحی شکست اعتبارسنجی به صورت ذیل است:
obs.next({ remoteValidation: { remoteValidationMessage: result.message } });
مزایای استفاده از Observableها در حین طراحی async validators
در کدهای فوق چنین مواردی را هم مشاهده میکنید:
// 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()
همچنین وجود و تعریف new Subject، دراینجا ضروری است و از نشتی حافظه و همچنین رفت و برگشتهای اضافهی دیگری به سمت سرور، جلوگیری میکند. این subject سبب میشود تا کلیه اعمال ناتمام پیشین، لغو شده (takeUntil) و تنها آخرین درخواست جدید رسیدهی پس از 400 میلیثانیه، به سمت سرور ارسال شود.
بنابراین همانطور که مشاهده میکنید، Observableها فراتر هستند از صرفا ارسال اطلاعات به سرور و بازگشت آنها به سمت کلاینت (استفادهی متداولی که از آنها در برنامههای Angular وجود دارد).
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید.
UTF-8 برای برنامهنویسان
نیازی به توضیح نیست که این ۲۵۶ حرف برای نگهداری نویسههای زبانهای مختلف و حتی برای برخی از زبانها به تنهایی کافی نیست.
کنترل DatePicker شمسی مخصوص Silverlight 4
این روش Commanding حجم کد رو در VM زیاد میکنه، در یک پروژه که رویدادهای زیادی داره(مثلا چند تا برای TreeVirw و چندین دکمه و ...) پیدا کردن قسمتهای مختلف سخت میشه(البته CodeMap هست ولی خب...)
من در پروژه هام به ازای هر View یک پوشه در Commands ایجاد میکنم و Commandها رو به طور جداگانه ایجاد میکنم.
نام متدها رو با حرف کوچیک شروع کردین، دلیل خاصی داره؟(Naming Style کلی با حرف بزرگ شروع میشه)
حذف یک ردیف از اطلاعات به همراه پویانمایی محو شدن اطلاعات آن توسط jQuery در ASP.NET MVC
اینم امتحان کردم نشد
زبانهای محبوب برنامه نویسی سال 2014
احراز هویت
ASP.NET MVC #18
در این سؤال دوم عنوان کردید که کاربران وارد سیستم میشوند. حالا من چندتا زیر سیستم دارم. میخواهم برای هر زیر سیستم بر اساس «نقشهای» کاربران (واژه علمی «کاربران خاصی» که عنوان کردید) بتوانند به زیر سیستم خودشون وارد شوند.
باید فیلتر AuthorizeAttribute را سفارشی کنید بر اساس Roleهای مشخص سیستم. اگر زیر سیستمی باید صرفا برای کاربران برای مثال Editor قابل دسترسی باشد، در این کلاس و فیلتر سفارشی مشتق شده از AuthorizeAttribute، اول باید چک کنید که کوکی سفارشی خاص حاصل از ورود موفقیت آمیز به صفحه لاگین دوم، تنظیم شده یا خیر (یا در سادهترین حالت از سشن استفاده کنید). اگر خیر، بر اساس Role مشخص صفحه جاری، به یک صفحه لاگین ثانویه هدایت شود تا کاربر بتواند کوکی یا سشن لازم را پس از لاگین دوم تولید کند.