public class TokenFactoryService { private readonly JwtBearerOptions _jwtBearerOptions; public TokenFactoryService(IOptionsSnapshot<JwtBearerOptions> jwtBearerOptions) { if (jwtBearerOptions == null) { throw new ArgumentNullException(nameof(jwtBearerOptions)); } _jwtBearerOptions = jwtBearerOptions.Value ?? throw new ArgumentNullException(nameof(jwtBearerOptions)); } // From: https://github.com/dotnet/aspnetcore/blob/a450cb69b5e4549f5515cdb057a68771f56cefd7/src/Security/Authentication/JwtBearer/src/JwtBearerHandler.cs public bool ValidateJwt(string token) { foreach (var validator in _jwtBearerOptions.SecurityTokenValidators) { try { if (validator.CanReadToken(token)) { validator.ValidateToken(token, _jwtBearerOptions.TokenValidationParameters, out _); } } catch { return false; } } return true; } }
معرفی System.Text.Json در NET Core 3.0.
options = new JsonSerializerOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, WriteIndented = true }; jsonString = JsonSerializer.Serialize(weatherForecast, options);
var options = new JsonSerializerOptions { Encoder = JavaScriptEncoder.Create(UnicodeRanges.All) };
بازنویسی سطح دوم کش برای Entity framework 6
//Function in Repository Class public IQueryable<T> FindAll(bool doCache, params Expression<Func<T, object>>[] includes) { return includes.Aggregate<Expression<Func<T, object>>, IQueryable<T>>( _dbset, (current, experssion) => current.Include(experssion)); }
//function in cache class public IQueryable<T> FindAll(bool doCache, params Expression<Func<T, object>>[] includes) { if (doCache) { var result = _repository.FindAll(doCache, includes).Cacheable(); return result; } else return _repository.FindAll(doCache, includes); }
//Call in service class _cache.FindAll(true,s=>s.Tag)
ثبت استثناهای مدیریت شده توسط ELMAH
public async Task<string> SaveAllChangesAsync(bool invalidateCacheDependencies = true, Guid? auditUserId = null) { try { if (auditUserId.HasValue) AuditFields(auditUserId.Value); await SaveChangesAsync(); if (!invalidateCacheDependencies) return string.Empty; var changedEntityNames = GetChangedEntityNames(); new EFCacheServiceProvider().InvalidateCacheDependencies(changedEntityNames); } catch (DbUpdateConcurrencyException ex) { Elmah.ErrorSignal.FromCurrentContext().Raise(ex); return ConcurrencyMessage; } return string.Empty; }
private static bool _isPreGeneratedViewCacheSet; private void InitializationPreGeneratedViews() { if (_isPreGeneratedViewCacheSet) return; var precompiledViewsFilePath = new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName + @”\EF6PrecompiledViews.xml”; InteractiveViews.SetViewCacheFactory(this, new FileViewCacheFactory(precompiledViewsFilePath)); _isPreGeneratedViewCacheSet = true; }
InteractiveViews .SetViewCacheFactory(ctx, new FileViewCacheFactory(new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName + @"\EF6PrecompiledViews.xml"));
در global
void Application_Start(object sender, EventArgs e) { // Schedule Start } void Application_End(object sender, EventArgs e) { // Code that runs on application shutdown var scheduler = new StdSchedulerFactory().GetScheduler(); scheduler.Shutdown(true); DoWebRequest ("SiteAddress"); }
public string DoWebRequest(string url) { WebRequest request = WebRequest.Create(url); request.Credentials = CredentialCache.DefaultCredentials; HttpWebResponse response = (HttpWebResponse)(request.GetResponse()); Stream dataStream = response.GetResponseStream(); StreamReader reader = new StreamReader(dataStream); string responseFromServer = reader.ReadToEnd(); reader.Close(); dataStream.Close(); response.Close(); return responseFromServer; }
این اجرا تا زمانیکه اولین کوئری به بانک اطلاعاتی ارسال نشود مثلا فراخوانی context.Entity.Find، به تعویق خواهد افتاد. به همین جهت برای وادار کردن EF به ساخت بانک اطلاعاتی و یا اعمال تغییرات جدید به آن، میتوان از نکته زیر استفاده کرد:
protected void Application_Start() { //... Database.SetInitializer(...همانند سابق...); using (var context = new MyContext()) { context.Database.Initialize(force: true); } //... }
چند دیتا سورس به عنوان ورودی داده
.MainTableDataSource(dataSource => { var crossTabList = Evaluations_Result.Pivot(x => new { گروه_سوال = x.QuestionGroupName, سوال = x.QuestionName, وزن = x.QuestionWeight.Value }, x1 => x1.IndexName, x2 => x2.Count(x => x.IndexName != null)); dataSource.Crosstab(crossTabList); }) .MainTableAdHocColumnsConventions(adHocColumnsConventions => { adHocColumnsConventions.ShowRowNumberColumn(true); adHocColumnsConventions.RowNumberColumnCaption("ردیف"); }) .MainTableSummarySettings(summarySettings => { summarySettings.OverallSummarySettings("جمع کل"); summarySettings.PageSummarySettings("جمع صفحه"); }) .MainTableEvents(events => { events.DataSourceIsEmpty(message: "اطلاعاتی برای نمایش وجود ندارد."); }
هر کامپوننتی در React یک چرخه زندگی دارد. زمانیکه یک کامپوننت را به روش React.createClass یا React.Component تعریف میکنیم و در ReactDOM.render نمونهای از کامپوننت را برای نمایش در مرورگر میسازیم، چرخه حیات آن شروع میشود.
ReactDOMServer
کتابخانه ReactDOMServer جهت ساخت یا render کردن کامپوننتها در سمت سرور استفاده میشود. توسط این کتابخانه میتوانیم کامپوننتها را در سمت سرور ایجاد کنیم و نتیجه آن را که تگهای HTML هستند به مرورگر ارسال کنیم. این روش جهت داشتن صفحههای وب سریعتر و اهداف SEO مفید است. جهت اطلاعات بیشتر و روشهای استفاده به مستندات آن رجوع کنید. در مثال زیر روش استفاده از این کتابخانه به اختصار آمده.
var persons = [ { id: 1, personName: "Parham", personContact: "parhamda@gmail.com" }, { id: 2, personName: "Roham", personContact: "roham@yahoo.com" }, { id: 3, personName: "Raha", personContact: "raha@live.com" } ]; class Person extends React.Component{ render(){ return ( <div> <p>{this.props.personName}</p> <p>{this.props.personContact}</p> </div> ) } } let person1 = persons[0]; let personElement = <Person personName={person1.personName} personContact={person1.personContact}/> console.log(ReactDOMServer.renderToStaticMarkup(personElement));
در کد بالا مواردی که جدید هستند، یکی ساخت یک نمونه از کامپوننت Person است و دیگری ساخت آن در سمت سرور، بدون آن که فعلا نمایشی در مرورگر داشته باشیم. در کنسول میتوانیم خروجی کتابخانه را که تگهای HTML هستند ببینیم. ReactDOMServer دو متد را فراهم کرده که کارکردی مشابه دارند؛ اما در جزئیات متفاوت هستند.
- renderStaticMarkup یک خروجی استاتیک و بدون attributeهای اضافه را تولید میکند که بیشتر برای بررسی یا استفاده در صفحههای وب ایستا مفید هستند.
- renderToString یک خروجی به صورت HTML String ایجاد میکند که برای HTML DOM در سمت کاربر سازگارتر است و مناسب برای صفحات پویا.
در نهایت خروجی از هر نوع که بود، برای اینکه در سمت کاربر قابل مشاهده باشد باید از همان متد ReactDOM.render استفاده کنیم. از آنجایی که این مجموعه جهت معرفی و بررسی ابزارهای اصلی React به صورت مختصر است، از آوردن مثالهای زیاد و پیچیده پرهیز میکنم. در اینجا میتوانید یک نمونه ساده برای استفاده از ReactDOMServer به صورت استاندارد و با جزئیات را بررسی کنید.
متدهای چرخه حیات در React
React چند متد را برای زمانهای قبل و بعد از ساخت شدن یک کامپوننت در DOM دارد که میشود رفتارهایی را برای کامپوننت، در این متدها در نظر گرفت تا در زمان مناسب اجرا شوند. در ادامه این متدها معرفی و کاربرد هر یک بیان میشود.
componentWillMount: این متد قبل از اینکه کامپوننت، تگهای متد render را بسازد اجرا میشود. این متد هم در سمت کلاینت کاربرد دارد و هم در سمت سرور. به همین جهت برای گرفتن log از دادههای کامپوننت و کار با پایگاه داده مکان مناسبی است. به عنوان مثال در قطعه کد زیر دادههای کامپوننت، توسط Ajax ارسال شدهاند.
componentWillMount() { Ajax.post("/componentLog", { name: this.constructor.name, props: this.props }); }
componentDidMount: این متد بعد از اینکه بخش render اجرا شد فراخوانی میشود. همچنین فقط در سمت کلاینت و زمانیکه از ReactDOM.render استفاده میکنیم کاربرد دارد. این متد مناسب برای تعامل کامپوننت با افزونهها و APIها است؛ مانند دریافت اطلاعات مورد نیاز کامپوننت از سایتی دیگر توسط یک API. از این متد در قسمت چهارم مثالی آورده شده.
(componentWillReciveProps(nextProps: این متد زمانی اجرا میشود که دادههای ورودی کامپوننت با مقادیری جدید تغییر کنند.
componentWillReceiveProps(nextProps) { // Do something with new received data and change the state. } ReactDOM.render( <TestComponent someData={newDataEveryFiveSecond()}/>, document.getElementById("divTest") );
در مثال بالا یک کامپوننت داریم که دادههای ورودی خود را از یک تابع میگیرد. این تابع هر پنج ثانیه یک بار یک داده تازه ایجاد میکند و به کامپوننت ارسال میکند. میتوانیم داخل کامپوننت، از متد componentWillReceiveProps جهت دستکاری دادههای رسیده و تغییر وضعیت کامپوننت توسط setState استفاده کنیم.
(shouldComponentUpdate(nextProps, nextState: این متد شبیه به متد componentWillReceiveProps است، البته با تفاوتهایی. این متد هم مقدار ورودی جدید برای پارامترهای کامپوننت میگیرد و هم مقداری برای وضعیتی که کامپوننت دارد. این متد باید یک مقدار بازگشتی false یا true داشته باشد. با این مقدار بازگشتی میتوان کنترل کرد که آیا کامپوننت بر اساس دادههای جدید بروز بشود یا نه.
class ComponentExample extends React.Component { shouldComponentUpdate(nextProps, nextState) { return notEqual(this.props, nextProps) || notEqual(this.state, nextState); } }
در مثال بالا پارامترها و وضعیت جاری کامپوننت، با مقدارهای تازه تغییر یافته و وضعیت جدید مقایسه میشوند. اگر مقادیر مقایسه شده برابر نباشند (یعنی داده تکراری وارد نشده) مقدار بازگشتی true خواهد بود و React کامپوننت را بر اساس وضعیت جدید و دادههای تازه دوباره میسازد.
(componentWillUpdate(nextProps, nextState: این متد زمانیکه کامپوننت ساخته شده، دادههای جدیدی را دریافت کند و یا وضعیت آن تغییر کند و دقیقا قبل از اجرای render فراخوانی میشود. اگر از متد shouldComponentUpdate مقدار false بازگشت داده شود، این متد دیگر اجرا نخواهد شد. باید توجه داشته باشیم که setState را نمیشود در این متد پیادهسازی کرده. به این علت که، زمانیکه وضعیت کامپوننت تغییر میکند، React متد componentWillUpdate و بلافاصله بعد از آن render را اجرا میکند و برای تغییر وضعیت دیگر دیر شده! تفاوت componentWillUpdate با componentWillMount این است که Will Mount در اولین وهله سازی از کامپوننت اجرا میشود، ولی Will Update بعد از هر دوباره سازی (rerender).
(componentDidUpdate(prevProps, prevStat: احتمالا میشود به راحتی حدس زد که این متد دقیقا بعد از دوباره سازی کامپوننتی که ساخته شده فراخوانی میشود.
componentWillUnmount: این متد زمانی اجرا میشود که یک کامپوننت از DOM پاک شود. برای پاک کردن نمونهای از یک کامپوننت که در DOM در حال نمایش است میتوانیم از دستور زیر استفاده کنیم.
ReactDOM.unmountComponentAtNode(document.getElementById("react"));
+ خروجی serializer.Serialize از نوع XElement است. بنابراین در قسمت آرگومان جنریک JsonConvert.DeserializeObject باید XElement ذکر شود. مرحله بعدی آن فراخوانی serializer.Deserialize روی این خروجی است.
Expression<Func<Book, bool>> expression = x => x.Code > 2 && x.Code < 5; var expressionSerializer = new Common.ExpressionSerializer(); var xml = expressionSerializer.Serialize(expression); var xmlToJson = JsonConvert.SerializeObject(xml); var xmlObject = JsonConvert.DeserializeObject<XElement>(xmlToJson); var exp2 = expressionSerializer.Deserialize(xmlObject) as Expression<Func<Book, bool>>;