اشتراکها
چند روز پیش در حال استفاده از افزونهی jQuery Bootgrid بودم که دادههای خود را در قالب زیر به صورت کوئری استرینگ ارسال میکند.
current=1&rowCount=10&sort[sender]=asc&searchPhrase=&id=b0df282a-0d67-40e5-8558-c9e93b7befed
قبلا هم با کوئری استرینگها کار کردهایم و نحوه دریافت آن را یاد گرفتهایم و میدانیم که اگر کلاس شما شامل پراپرتیهای همنام با کلیدهای کوئری استرینگ باشد مستقیما در کلاس شما جا میگیرند؛ ولی من دوست داشتم که پراپرتیهای کلاسم نام دلخواه من را داشته باشد و اجباری به استفاده از نامهای کوئری استرینگ نداشته باشد. اصلا ممکن است افراد Back End یک سری کد نوشتهاند و کلاسشان را هم ساختهاند و اصلا کاری با من ندارند که چطوری دادهها را و با چه اسامی از آنها دریافت میکنم و فقط انتظار دارند که کلاس آنها را با اطلاعات دریافتی پر کنم و ارسال کنم. اگر بخواهیم به طور دستی هر یک از کلیدها را چک کنیم، هم کدنویسی طولانی میشود و هم کد قابلیت استفاده مجدد ندارد. پس بهترین کار این است که یک کد با قابلیت استفاده مجدد بنویسیم.
دوست دارم چیزی شبیه به DeSerialize کردن فرمت json توسط کتابخانه Json.net داشته باشم؛ پس در اولین قدم یک attribute با مشخصات زیر میسازیم:
سپس در کلاس اصلی، ما این خصوصیتها را در بالای propertyها تعریف کرده و با کلیدهای موجود در کوئری استرینگ برابر میکنیم:
سپس کلاس زیر را مینویسیم که وظیفه دارد کلاسهای از جنس بالا را با query stringها رسیده در درخواست مطابقت دهد:
این متد یک تعریف کلاس را دریافت میکند. سپس رشتهی کوئری استرینگ موجود در بدنه درخواست را دریافت کرده و با استفاده از کد زیر اشیا را به صورت nameValueCollection دریافت میکنیم.
نکته: همچنین متد httputility.parseQueryString یک رشته کوئری استرینگ دریافت میکند و کوئری استرینگ را به زوج نام و مقدار nameValueCollection تبدیل میکند.
سپس در مرحلهی بعدی با استفاده از Reflection پراپرتیهایی را که دارای attribute تعریف شده هستند، پیدا میکنیم.
در صورتیکه شما کلید sort را درخواست کنید و از آنجا که کلید اصلی با نام [sort[sender است، مقدار null بازگشت میدهد. پس ما میتوانیم به این مقدار شک کنیم که شاید این کلید حاوی مقدار مورد نظر ماست؛ پس این حالت را بررسی میکنیم. برای بررسی، با استفاده از linq بررسی میکنیم که اگر کلیدهای namValueCollection با این کلید (در اینجا sort) آغاز میشوند، پس به احتمال زیاد همان حالت مورد نظر ما رخ داه است. پس اندیسهای [ و ] را میگیریم و اگر اندیس هر دو بزرگتر از صفر بود مقدار ما بین آن را به عنوان کلید بیرون میکشیم و در یک namValueCollection جدید قرار میدهیم و در نهایت به پراپرتی پاس میدهیم. کد نهایی این متد به شکل زیر است:
حال به صورت زیر این متد را صدا میزنیم:
[AttributeUsage(AttributeTargets.Property,Inherited = true)] public class RequestBodyField:Attribute { public string Field; public RequestBodyField(string field) { this.Field = field; } }
public class EmployeesRequestBody { [RequestBodyField("current")] public int CurrentPage { get; set; } [RequestBodyField("rowcount")] public int RowCount { get; set; } [RequestBodyField("searchPhrase")] public string SearchPhrase { get; set; } [RequestBodyField("sort")] public NameValueCollection SortDictionary { get; set; } }
public T GetFromQueryString<T>() where T : new() { var obj = new T(); var queryString = HttpContext.Current.Request.QueryString; var queries = HttpUtility.ParseQueryString(queryString.ToString()); var properties = typeof(T).GetProperties(); foreach (var property in properties) { foreach (Attribute attribute in property.GetCustomAttributes(true)) { var requestBodyField = attribute as RequestBodyField; if (requestBodyField == null) continue; //get value of query string var valueAsString = queries[requestBodyField.Field]; var converter = TypeDescriptor.GetConverter(property.PropertyType); var value = converter.ConvertFrom(valueAsString); if (value == null) continue; property.SetValue(obj, value, null); } } return obj; }
HttpContext.Current.Request.QueryString
سپس در مرحلهی بعدی با استفاده از Reflection پراپرتیهایی را که دارای attribute تعریف شده هستند، پیدا میکنیم.
مقدار داده شده به attribute را در nameValueCollection بررسی میکنیم و در صورت موجود بودن، مقدار آن را میگیریم. از آنجا که این مقدار از نوع رشته است و ممکن است مقدار داخل آن عددی یا هر نوع دیگری باشد، باید آن را به نوع صحیح تبدیل کنیم که خطوط زیر کار تبدیل را انجام میدهند:
var converter = TypeDescriptor.GetConverter(property.PropertyType); var value = converter.ConvertFrom(valueAsString);
در خط اول بر اساس نوع property کلاس، یک converter دریافت میکنیم و سپس مقدار ارسال شده را به آن میدهیم تا مقدار جدید را با نوع صحیح خود، دریافت کنیم.
سپس در صورتی که مقدار صحیح دریافت شود و برابر null نباشد، مقدار را در پراپرتی مربوطه جا میدهیم.
نکتهای که در اینجا نیاز به تلاش بیشتر دارد، کلید sort در کوئری استرینگ است. با نگاهی دقیقتر متوجه میشوید که خود کلید دو مقدار دارد که یکی از مقادیرش با کلید ترکیب شده است. این حالت روش ارسال آرایهها با نام کلیدی متفاوت در کوئری استرینگ است. این حالت ارسال باعث میشود که گرید بتواند حالت multi sort را نیز پیاده سازی کند.
پس برای دریافت این نوع مقادیر کمی کد به آن اضافه میکنیم. برای دریافت مقادیر آرایهای کد زیر را به سیستم اضافه میکنیم:
سپس در صورتی که مقدار صحیح دریافت شود و برابر null نباشد، مقدار را در پراپرتی مربوطه جا میدهیم.
نکتهای که در اینجا نیاز به تلاش بیشتر دارد، کلید sort در کوئری استرینگ است. با نگاهی دقیقتر متوجه میشوید که خود کلید دو مقدار دارد که یکی از مقادیرش با کلید ترکیب شده است. این حالت روش ارسال آرایهها با نام کلیدی متفاوت در کوئری استرینگ است. این حالت ارسال باعث میشود که گرید بتواند حالت multi sort را نیز پیاده سازی کند.
پس برای دریافت این نوع مقادیر کمی کد به آن اضافه میکنیم. برای دریافت مقادیر آرایهای کد زیر را به سیستم اضافه میکنیم:
if (valueAsString == null) { var keys = from key in queries.AllKeys where key.StartsWith(requestBodyField.Field) select key; var collection = new NameValueCollection(); foreach (var key in keys) { var openBraketIndex = key.IndexOf("[", StringComparison.Ordinal); var closeBraketIndex = key.IndexOf("]", StringComparison.Ordinal); if (openBraketIndex < 0 || closeBraketIndex < 0) throw new Exception("query string is corrupted."); openBraketIndex++; //get key in [...] var fieldName = key.Substring(openBraketIndex, closeBraketIndex - openBraketIndex); collection.Add(fieldName, queries[key] ); } property.SetValue(obj, collection, null); continue; }
public T GetFromQueryString<T>() where T : new() { var obj = new T(); var properties = typeof(T).GetProperties(); var queryString = HttpContext.Current.Request.QueryString; var queries = HttpUtility.ParseQueryString(queryString.ToString()); foreach (var property in properties) { foreach (Attribute attribute in property.GetCustomAttributes(true)) { var requestBodyField = attribute as RequestBodyField; if (requestBodyField == null) continue; //get value of query string var valueAsString = queries[requestBodyField.Field]; if (valueAsString == null) { var keys = from key in queries.AllKeys where key.StartsWith(requestBodyField.Field) select key; var collection = new NameValueCollection(); foreach (var key in keys) { var openBraketIndex = key.IndexOf("[", StringComparison.Ordinal); var closeBraketIndex = key.IndexOf("]", StringComparison.Ordinal); if (openBraketIndex < 0 || closeBraketIndex < 0) throw new Exception("query string is corrupted."); openBraketIndex++; //get key in [...] var fieldName = key.Substring(openBraketIndex, closeBraketIndex - openBraketIndex); collection.Add(fieldName, queries[key]); } property.SetValue(obj, collection, null); continue; } var converter = TypeDescriptor.GetConverter(property.PropertyType); var value = converter.ConvertFrom(valueAsString); if (value == null) continue; property.SetValue(obj, value, null); } } return obj; }
حال به صورت زیر این متد را صدا میزنیم:
public virtual ActionResult GetEmployees() { var request = new Requests().GetFromQueryString<EmployeesRequestBody>(); }
اشتراکها
موتور جستجوی مجموعهداده – گوگل
رویس جدیدی اخیراً توسط گوگل منتشر شده است با نام Dataset Search که روزنامهنگاران، پژوهشگران و مهندسین داده میتوانند ازین پس، مجموعه دادههای مورد نیاز خود را به کمک این موتور جستجو بیابند.
خطاهایی که در حین ارتقاء به نگارش 2.2 احتمالا شاهد خواهید بود:
الف) پروژه با خطای زیر بارگذاری نمیشود:
برای رفع این خطا،
- ابتدا تمام TargetFrameworkهای موجود را به 2.2 تغییر دهید.
ب) اخطار زیر را جهت ذکر صریح شماره نگارش بستهی Microsoft.AspNetCore.App، مشاهده میکنید:
در فایل پروژه، PackageReference این بستهی مخصوص را بدون شماره نگارش ذکر کنید تا همواره به صورت خودکار از آخرین SDK نصب شده استفاده کند:
الف) پروژه با خطای زیر بارگذاری نمیشود:
Version conflict detected for Microsoft.AspNetCore.Http.Abstractions. Install/reference Microsoft.AspNetCore.Http.Abstractions 2.2.0 directly to project xyz to resolve this issue.
- ابتدا تمام TargetFrameworkهای موجود را به 2.2 تغییر دهید.
<TargetFramework>netcoreapp2.2</TargetFramework>
- پس از آن تمام پوشههای bin و obj موجود در تمام پروژههای solution جاری را باید یکبار حذف کنید و سپس دستور dotnet restore را صادر کنید. این خطای تداخل نگارشها (Version conflict detected) از وجود پوشههای قدیمی bin و obj ناشی میشود.
- اکنون نیاز است وابستگیهای پروژه را نیز یکدست کنید:
dotnet tool update --global dotnet-outdated dotnet outdated -u
A PackageReference to 'Microsoft.AspNetCore.App' specified a Version of `2.2.0`. Specifying the version of this package is not recommended. For more information, see https://aka.ms/sdkimplicitrefs
<PackageReference Include="Microsoft.AspNetCore.App" />
اشتراکها
مدیریت خطا در ASP.NET Core
اشتراکها
7.Visual Studio 2017 15.9 منتشر شد
These are the customer-reported issues addressed in 15.9.7:
- Crashes when expanding variables!.
- /DEBUG:FASTLINK + C7 + PCH crashes debugger.
- Native C++ application crashes because of stack corruption with VS 2017 15.9.2.
- Incorrect Release Mode code.
- Xamarin Unobserved Task Exception WebRequest.
- Link /SOURCELINK option seems to do nothing. This fixes Source Link for Managed C++ Debugging.
- Fixed an issue with corruption of AVX/MPX/AVX512 registers while Debugging.
- Update of Microsoft.VCLibs.140.00.UWPDestkop framework packages for C++ UWP DesktopBridge applications adding support for ARM64.
- Corrected incorrect version of VCToolsRedistVersion in Microsoft.VCToolsVersion.default.props.
- Corrected unsigned embedded dll for VC Redist installers.
- SSDT/Web Tools: We fixed an issue where SQL LocalDB was not installed on Polish, Turkish, and Czech locales.
- SSDT: We fixed an issue affecting SQL Server Analysis Services (Method not found exception when clicking on UI).
- SSDT: We fixed an accessibility issue which was causing the contents of a table not to be visible in the result window when using High-Contrast mode.
Security Advisory Notices
اشتراکها
قرار دادن Power BI در برنامه خودتان
اشتراکها
NET 8.0.402. منتشر شد
.NET 8.0.402 - September 24, 2024
Today, we are releasing an update to .NET 8.0.400 SDK due to an issue with RestoreTask randomly fails after upgrading to latest version fixed by Allow @@ as a fallback.
The .NET 8.0.402 release is available for download. This SDK includes the previously released .NET 8.0.8 Runtime and is in support of Visual Studio 17.11 release. The latest 8.0 release is always listed at .NET 8.0 Releases.