public class Rpt { public string Title {set;get;} public int Price {set;get;} }
var list = new List<Rpt>(); list.Add(new Rpt{ Title = "عنوان دلخواه", Price = 1});
پس از ساخت لیست، از منبع داده StronglyTypedList استفاده کنید. یک مثال از این منبع داده
public class Rpt { public string Title {set;get;} public int Price {set;get;} }
var list = new List<Rpt>(); list.Add(new Rpt{ Title = "عنوان دلخواه", Price = 1});
جهت نگهداری بعضی از اطلاعات در صفحات کاربر، از فیلدهای مخفی ( Hidden Inputs ) استفاده میکنیم. مشکلی که در این روش وجود دارد این است که اگر این اطلاعات مهم باشند (مانند کلیدها) کاربر میتواند توسط ابزارهایی این اطلاعات را تغییر دهد و این مورد مسئلهای خطرناک میباشد.
راه حل رفع این مسئلهی امنیتی، استفاده از یک Html Helper جهت رمزنگاری این فیلد مخفی در مرورگر کاربر و رمز گشایی آن هنگام Post شدن سمت سرور میباشد.
برای رسیدن به این هدف یک Controller Factory ( Understanding and Extending Controller Factory in MVC ) سفارشی را جهت دستیابی به مقادیر فرم ارسالی، قبل از استفاده در Actionها و به همراه کلاسهای زیر ایجاد کردیم.
کلاس EncryptSettingsProvider :public interface IEncryptSettingsProvider { byte[] EncryptionKey { get; } string EncryptionPrefix { get; } } public class EncryptSettingsProvider : IEncryptSettingsProvider { private readonly string _encryptionPrefix; private readonly byte[] _encryptionKey; public EncryptSettingsProvider() { //read settings from configuration var useHashingString = ConfigurationManager.AppSettings["UseHashingForEncryption"]; var useHashing = System.String.Compare(useHashingString, "false", System.StringComparison.OrdinalIgnoreCase) != 0; _encryptionPrefix = ConfigurationManager.AppSettings["EncryptionPrefix"]; if (string.IsNullOrWhiteSpace(_encryptionPrefix)) { _encryptionPrefix = "encryptedHidden_"; } var key = ConfigurationManager.AppSettings["EncryptionKey"]; if (useHashing) { var hash = new SHA256Managed(); _encryptionKey = hash.ComputeHash(Encoding.UTF8.GetBytes(key)); hash.Clear(); hash.Dispose(); } else { _encryptionKey = Encoding.UTF8.GetBytes(key); } } #region ISettingsProvider Members public byte[] EncryptionKey { get { return _encryptionKey; } } public string EncryptionPrefix { get { return _encryptionPrefix; } } #endregion }
EncryptionKey : کلید رمز نگاری میباشد و در فایل Config برنامه ذخیره میباشد.
EncryptionPrefix : پیشوند نام Hidden فیلدها میباشد، این پیشوند برای یافتن Hidden فیلد هایی که رمزنگاری شده اند استفاده میشود. میتوان این فیلد را در فایل Config برنامه ذخیره کرد.
<appSettings> <add key="EncryptionKey" value="asdjahsdkhaksj dkashdkhak sdhkahsdkha kjsdhkasd"/> </appSettings>
کلاس RijndaelStringEncrypter :
public interface IRijndaelStringEncrypter : IDisposable { string Encrypt(string value); string Decrypt(string value); } public class RijndaelStringEncrypter : IRijndaelStringEncrypter { private RijndaelManaged _encryptionProvider; private ICryptoTransform _cryptoTransform; private readonly byte[] _key; private readonly byte[] _iv; public RijndaelStringEncrypter(IEncryptSettingsProvider settings, string key) { _encryptionProvider = new RijndaelManaged(); var keyBytes = Encoding.UTF8.GetBytes(key); var derivedbytes = new Rfc2898DeriveBytes(settings.EncryptionKey, keyBytes, 3); _key = derivedbytes.GetBytes(_encryptionProvider.KeySize / 8); _iv = derivedbytes.GetBytes(_encryptionProvider.BlockSize / 8); } #region IEncryptString Members public string Encrypt(string value) { var valueBytes = Encoding.UTF8.GetBytes(value); if (_cryptoTransform == null) { _cryptoTransform = _encryptionProvider.CreateEncryptor(_key, _iv); } var encryptedBytes = _cryptoTransform.TransformFinalBlock(valueBytes, 0, valueBytes.Length); var encrypted = Convert.ToBase64String(encryptedBytes); return encrypted; } public string Decrypt(string value) { var valueBytes = Convert.FromBase64String(value); if (_cryptoTransform == null) { _cryptoTransform = _encryptionProvider.CreateDecryptor(_key, _iv); } var decryptedBytes = _cryptoTransform.TransformFinalBlock(valueBytes, 0, valueBytes.Length); var decrypted = Encoding.UTF8.GetString(decryptedBytes); return decrypted; } #endregion #region IDisposable Members public void Dispose() { if (_cryptoTransform != null) { _cryptoTransform.Dispose(); _cryptoTransform = null; } if (_encryptionProvider != null) { _encryptionProvider.Clear(); _encryptionProvider.Dispose(); _encryptionProvider = null; } } #endregion }
متغیر key در سازنده کلاس کلیدی جهت رمزنگاری و رمزگشایی میباشد. این کلید میتواند AntiForgeryToken تولیدی در View ها و یا کلیدی باشد که در سیستم خودمان ذخیره سازی میکنیم.
در این پروژه از کلید سیستم خودمان استفاده میکنیم.
کلاس ActionKey :
public class ActionKey { public string Area { get; set; } public string Controller { get; set; } public string Action { get; set; } public string ActionKeyValue { get; set; } }
در اینجا هر View که بخواهد از این فیلد رمزنگاری شده استفاده کند بایستی دارای کلیدی در سیستم باشد.مدل متناظر مورد استفاده را مشاهده مینمایید. در این مدل، ActionKeyValue کلیدی جهت رمزنگاری این فیلد مخفی میباشد.
کلاس ActionKeyService :
/// <summary> /// پیدا کردن کلید متناظر هر ویو.ایجاد کلید جدید در صورت عدم وجود کلید در سیستم /// </summary> /// <param name="action"></param> /// <param name="controller"></param> /// <param name="area"></param> /// <returns></returns> string GetActionKey(string action, string controller, string area = ""); } public class ActionKeyService : IActionKeyService { private static readonly IList<ActionKey> ActionKeys; static ActionKeyService() { ActionKeys = new List<ActionKey> { new ActionKey { Area = "", Controller = "Product", Action = "dit", ActionKeyValue = "E702E4C2-A3B9-446A-912F-8DAC6B0444BC", } }; } /// <summary> /// پیدا کردن کلید متناظر هر ویو.ایجاد کلید جدید در صورت عدم وجود کلید در سیستم /// </summary> /// <param name="action"></param> /// <param name="controller"></param> /// <param name="area"></param> /// <returns></returns> public string GetActionKey(string action, string controller, string area = "") { area = area ?? ""; var actionKey= ActionKeys.FirstOrDefault(a => a.Action.ToLower() == action.ToLower() && a.Controller.ToLower() == controller.ToLower() && a.Area.ToLower() == area.ToLower()); return actionKey != null ? actionKey.ActionKeyValue : AddActionKey(action, controller, area); } /// <summary> /// اضافه کردن کلید جدید به سیستم /// </summary> /// <param name="action"></param> /// <param name="controller"></param> /// <param name="area"></param> /// <returns></returns> private string AddActionKey(string action, string controller, string area = "") { var actionKey = new ActionKey { Action = action, Controller = controller, Area = area, ActionKeyValue = Guid.NewGuid().ToString() }; ActionKeys.Add(actionKey); return actionKey.ActionKeyValue; } }
جهت بازیابی کلید هر View میباشد. در متد GetActionKey ابتدا بدنبال کلید View درخواستی در منبعی از ActionKeyها میگردیم. اگر این کلید یافت نشد کلیدی برای آن ایجاد میکنیم و نیازی به مقدار دهی آن نمیباشد.
کلاس MvcHtmlHelperExtentions :
public static class MvcHtmlHelperExtentions { public static string GetActionKey(this System.Web.Routing.RequestContext requestContext) { IActionKeyService actionKeyService = new ActionKeyService(); var action = requestContext.RouteData.Values["Action"].ToString(); var controller = requestContext.RouteData.Values["Controller"].ToString(); var area = requestContext.RouteData.Values["Area"]; var actionKeyValue = actionKeyService.GetActionKey( action, controller, area != null ? area.ToString() : null); return actionKeyValue; } public static string GetActionKey(this HtmlHelper helper) { IActionKeyService actionKeyService = new ActionKeyService(); var action = helper.ViewContext.RouteData.Values["Action"].ToString(); var controller = helper.ViewContext.RouteData.Values["Controller"].ToString(); var area = helper.ViewContext.RouteData.Values["Area"]; var actionKeyValue = actionKeyService.GetActionKey( action, controller, area != null ? area.ToString() : null); return actionKeyValue; } }
public static string GetActionKey(this System.Web.Routing.RequestContext requestContext)
public static string GetActionKey(this HtmlHelper helper)
کلاس InputExtensions :
public static class InputExtensions { public static MvcHtmlString EncryptedHidden(this HtmlHelper helper, string name, object value) { if (value == null) { value = string.Empty; } var strValue = value.ToString(); IEncryptSettingsProvider settings = new EncryptSettingsProvider(); var encrypter = new RijndaelStringEncrypter(settings, helper.GetActionKey()); var encryptedValue = encrypter.Encrypt(strValue); encrypter.Dispose(); var encodedValue = helper.Encode(encryptedValue); var newName = string.Concat(settings.EncryptionPrefix, name); return helper.Hidden(newName, encodedValue); } public static MvcHtmlString EncryptedHiddenFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) { var name = ExpressionHelper.GetExpressionText(expression); var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); return EncryptedHidden(htmlHelper, name, metadata.Model); } }
@Html.EncryptedHiddenFor(model => model.Id) @Html.EncryptedHidden("Id2","2")
public class DecryptingControllerFactory : DefaultControllerFactory { private readonly IEncryptSettingsProvider _settings; public DecryptingControllerFactory() { _settings = new EncryptSettingsProvider(); } public override IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) { var parameters = requestContext.HttpContext.Request.Params; var encryptedParamKeys = parameters.AllKeys.Where(x => x.StartsWith(_settings.EncryptionPrefix)).ToList(); IRijndaelStringEncrypter decrypter = null; foreach (var key in encryptedParamKeys) { if (decrypter == null) { decrypter = GetDecrypter(requestContext); } var oldKey = key.Replace(_settings.EncryptionPrefix, string.Empty); var oldValue = decrypter.Decrypt(parameters[key]); if (requestContext.RouteData.Values[oldKey] != null) { if (requestContext.RouteData.Values[oldKey].ToString() != oldValue) throw new ApplicationException("Form values is modified!"); } requestContext.RouteData.Values[oldKey] = oldValue; } if (decrypter != null) { decrypter.Dispose(); } return base.CreateController(requestContext, controllerName); } private IRijndaelStringEncrypter GetDecrypter(System.Web.Routing.RequestContext requestContext) { var decrypter = new RijndaelStringEncrypter(_settings, requestContext.GetActionKey()); return decrypter; } }
if (requestContext.RouteData.Values[oldKey] != null) { if (requestContext.RouteData.Values[oldKey].ToString() != oldValue) throw new ApplicationException("Form values is modified!"); }
protected void Application_Start() { .... ControllerBuilder.Current.SetControllerFactory(typeof(DecryptingControllerFactory)); }
*در تکمیل این مقاله میتوان SessionId کاربر یا AntyForgeryToken تولیدی در View را نیز در کلید دخالت داد و در هربار Post شدن اطلاعات این ActionKeyValue مربوط به کاربر جاری را تغییر داد و کلیدها را در بانکهای اطلاعاتی ذخیره نمود.
جواب این سوال بله میباشد. این سرویس در دو قالب سفید و مشکی ارائه شدهاست که به صورت پیش فرض قالب سفید آن انتخاب میشود. در تصویر زیر قالبهای این سرویس را مشاهده خواهید کرد.
اضافه نمودن reCAPTCHA به سایت:
اگر قبلا در گوگل ثبت نام نمودهاید کافیست وارد این سایت شوید و بر روی Get reCAPTCHA کلیک نمائید؛ در غیر اینصورت میبایستی یک حساب کاربری ایجاد نماید. بعد از ورود، به کنترل پنل هدایت خواهید شد. در نمای اول به تصویر زیر برخورد خواهید کرد که از شما ثبت سایت جدید را خواستار است:
نام، دامنه سایت و مالک را وارد و ثبت نام نماید.
پس از آنکه بر روی دکمهی ثبت نام کلیک نمودید، برای شما دو کلید جدید را ثبت مینماید که منحصر به سایت شماست. Site Key رشته ای را داراست که در کدهای HTML قرار خواهد گرفت و کلید بعدی Secret Key میباشد. ارتباط سایت شما با گوگل میبایستی به صورت محرمانه محفوظ بماند.
کد زیر را در قبل از بسته شدن تک <head/> قرار دهید:
<script src='https://www.google.com/recaptcha/api.js'></script>
<div data-sitekey="6LdHGgwTAAAAAClKFhGthRrjBXh5AUGd4eWNCQq7"></div>
وقتی کاربر فرم حاوی کپچا را که به صورت صحیح هویت سنجی آن انجام شده باشد به سمت سرور ارسال کند، به عنوان بخشی از دادهی ارسال شده، یک رشته با نام g-recaptcha-response با دستور Request دریافت خواهید کرد که به منظور بررسی اینکه آیا گوگل تایید کرده است که کاربر، یک درخواست POST ارسال نموداست. با این پارامترها یک مقدار json برگشت داده خواهد شد که میبایستی کلاسی متناظر با آن جهت خواندن ساخته شود.
با استفاده از کد زیر مقدار برگشتی Json را در کلاس مپ مینمائیم:using System.Collections.Generic; using Newtonsoft.Json; namespace BaseConfig.Security.Captcha { public class RepaptchaResponse { [JsonProperty("success")] public bool Success { get; set; } [JsonProperty("error-codes")] public List<string> ErrorCodes { get; set; } } }
using System.Configuration; using System.Net; using Newtonsoft.Json; namespace BaseConfig.Security.Captcha { public class ReCaptcha { public static string _secret; static ReCaptcha() { _secret = ConfigurationManager.AppSettings["ReCaptchaGoogleSecretKey"]; } public static bool IsValid(string response) { //secret that was generated in key value pair var client = new WebClient(); var reply = client.DownloadString($"https://www.google.com/recaptcha/api/siteverify?secret={_secret}&response={response}"); var captchaResponse = JsonConvert.DeserializeObject<RepaptchaResponse>(reply); // when response is false check for the error message if (!captchaResponse.Success) { //if (captchaResponse.ErrorCodes.Count <= 0) return View(); //var error = captchaResponse.ErrorCodes[0].ToLower(); //switch (error) //{ // case ("missing-input-secret"): // ViewBag.Message = "The secret parameter is missing."; // break; // case ("invalid-input-secret"): // ViewBag.Message = "The secret parameter is invalid or malformed."; // break; // case ("missing-input-response"): // ViewBag.Message = "The response parameter is missing."; // break; // case ("invalid-input-response"): // ViewBag.Message = "The response parameter is invalid or malformed."; // break; // default: // ViewBag.Message = "Error occured. Please try again"; // break; //} return false; } // Captcha is valid return true; } } }
// // POST: /Account/Login [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public virtual async Task<ActionResult> Login(LoginPageModel model, string returnUrl) { var response = Request["g-recaptcha-response"]; if (response != null && ReCaptcha.IsValid(response)) { // } }
/** * * @param {} data * @returns {} */ function Success(data) { grecaptcha.reset(); }
<div data-sitekey="6LdHGgwTAAAAAClKFhGthRrjBXh5AUGd4eWNCQq7"></div>
<script> var recaptcha1; var recaptcha2; var myCallBack = function () { //Render the recaptcha1 on the element with ID "recaptcha1" recaptcha1 = grecaptcha.render('recaptcha1', { 'sitekey': '6Lf9FQwTAAAAAE6XlDqrey24K4xJOPM5nNVBmNO9', 'theme': 'light' }); //Render the recaptcha2 on the element with ID "recaptcha2" recaptcha2 = grecaptcha.render('recaptcha2', { 'sitekey': '6Lf9FQwTAAAAAE6XlDqrey24K4xJOPM5nNVBmNO9', 'theme': 'light' }); //Render the recaptcha3 on the element with ID "recaptcha3" recaptcha2 = grecaptcha.render('recaptcha3', { 'sitekey': '6Lf9FQwTAAAAAE6XlDqrey24K4xJOPM5nNVBmNO9', 'theme': 'light' }); }; </script>
<div id="recaptcha1"></div> <div id="recaptcha2"></div> <div id="recaptcha3"></div>
<script src='https://www.google.com/recaptcha/api.js?hl=@(App_GlobalResources.CP.CurrentAbbrivation)'></script>
<script src='https://www.google.com/recaptcha/api.js?hl=fa'></script>
public void Update(Article entity) { var item = articles.Find(entity.Id); item.Author = entity.Author; item.CategoryId = entity.CategoryId; item.Content = entity.Content; item.Source = entity.Source; item.Title = entity.Title; if (entity.FileStream != null) item.FileStream = new File { ContentType=entity.FileStream.ContentType, Id=entity.Id, Size = entity.FileStream.Size, FileBytes = entity.FileStream.FileBytes }; var allTag = tags.ToCacheableList().ToList(); var tagsList = entity.Tags.ToList().Select(x => x.Name.ToPersianContent(true)).ToArray(); if (entity.Tags != null && entity.Tags.Any()) { entity.Tags.Clear(); entity.Tags = new Collection<Tag>(); } var listOfTags = tagsList.Select(tag => allTag.Any(x => x.Name == tag) ? allTag.FirstOrDefault(x => x.Name == tag) : new Tag { Name = tag }).ToList(); listOfTags.ForEach(tag => entity.Tags.Add(tag)); unitOfWork.PwsUpdateGraph(entity, map => map .OwnedEntity(p => p.FileStream) .OwnedCollection(p => p.Tags)); }
public static T ParseIt<T>(string content, IFormatProvider? provider) where T : IParsable<T> { return T.Parse(content, provider); } public IEnumerable<T> ParseCsvRow<T>(string content, IFormatProvider? provider) where T : IParsable<T> { return content.Split(',').Select(str => T.Parse(str, provider)); }
public static T ParseIt<T>(string content, IFormatProvider? provider) { var type = typeof(T); var method = type.GetMethod("Parse", BindingFlags.Static | BindingFlags.Public, new[] { typeof(string), typeof(IFormatProvider) }); return (T)method!.Invoke(null, new object?[] { content, provider })!; }
using FluentValidationSample.Models; using Microsoft.AspNetCore.Mvc; namespace FluentValidationSample.Web.Controllers { public class HomeController : Controller { public IActionResult Index() { return View(); } [HttpPost] public IActionResult RegisterValidateManually(RegisterModel model) { var validator = new RegisterModelValidator(); var validationResult = validator.Validate(model); if (!validationResult.IsValid) { return BadRequest(validationResult.Errors[0].ErrorMessage); } // TODO: Save the model return Ok(); } } }
public IActionResult RegisterValidateManually(RegisterModel model) { var validator = new RegisterModelValidator(); var validationResult = validator.Validate(model); if (!validationResult.IsValid) { validationResult.AddToModelState(ModelState, null); return BadRequest(ModelState); } // TODO: Save the model return Ok(); }
namespace FluentValidationSample.Web { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddTransient<IValidator<RegisterModel>, RegisterModelValidator>(); services.AddControllersWithViews(); }
namespace FluentValidationSample.Web.Controllers { public class HomeController : Controller { private readonly IValidator<RegisterModel> _registerModelValidator; public HomeController(IValidator<RegisterModel> registerModelValidator) { _registerModelValidator = registerModelValidator; } [HttpPost] public IActionResult RegisterValidatorInjection(RegisterModel model) { var validationResult = _registerModelValidator.Validate(model); if (!validationResult.IsValid) { return BadRequest(validationResult.Errors[0].ErrorMessage); } // TODO: Save the model return Ok(); } } }
namespace FluentValidationSample.Web { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddTransient<IValidator<RegisterModel>, RegisterModelValidator>(); services.AddControllersWithViews().AddFluentValidation(); }
namespace FluentValidationSample.Web.Controllers { public class HomeController : Controller { [HttpPost] public IActionResult RegisterValidatorAutomatically(RegisterModel model) { if (!ModelState.IsValid) { // re-render the view when validation failed. return View(model); } // TODO: Save the model return Ok(); } } }
namespace FluentValidationSample.Web.Controllers { [Route("[controller]")] [ApiController] public class HomeController : Controller { [HttpPost] public IActionResult RegisterValidatorAutomatically(RegisterModel model) { // TODO: Save the model return Ok(); } } }
{ "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "|84df05e2-41e0d4841bb61293.", "errors": { "FirstName": [ "'First Name' must not be empty." ] } }
public void ConfigureServices(IServiceCollection services) { // ... // override modelstate services.Configure<ApiBehaviorOptions>(options => { options.InvalidModelStateResponseFactory = context => { var errors = context.ModelState.Values.SelectMany(x => x.Errors.Select(p => p.ErrorMessage)).ToList(); return new BadRequestObjectResult(new { Code = "00009", Message = "Validation errors", Errors = errors }); }; }); }
namespace FluentValidationSample.Web { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews().AddFluentValidation( fv => fv.RegisterValidatorsFromAssemblyContaining<RegisterModelValidator>() ); }
public void ConfigureServices(IServiceCollection services) { services.AddControllersWithViews().AddFluentValidation( fv => { fv.RegisterValidatorsFromAssemblyContaining<RegisterModelValidator>(); fv.RunDefaultMvcValidationAfterFluentValidationExecutes = false; } ); }
private static IQueryable<T> PagedResult<T, TResult>(IQueryable<T> query, int pageNum, int pageSize, Expression<Func<T, TResult>> orderByProperty, bool isAscendingOrder, out int rowsCount, Expression<Func<T, bool>> whereClause = null) { if (pageSize <= 0) pageSize = 20; //مجموع ردیفهای به دست آمده rowsCount = query.Count(); // اگر شماره صفحه کوچکتر از 0 بود صفحه اول نشان داده شود if (rowsCount <= pageSize || pageNum <= 0) pageNum = 1; // محاسبه ردیف هایی که نسبت به سایز صفحه باید از آنها گذشت int excludedRows = (pageNum - 1) * pageSize; query = isAscendingOrder ? query.OrderBy(orderByProperty) : query.OrderByDescending(orderByProperty); //جستجو را در صورت لزوم انجام میدهد query = whereClause == null ? query : query.Where(whereClause); // ردشدن از ردیفهای اضافی و دریافت ردیفهای مورد نظر برای صفحه مربوطه return query.Skip(excludedRows).Take(pageSize); }
public static List<t_Prodcts> GetPaging(int currentPage, int pageSize, out int count, Expression<Func<t_Prodcts, bool>> search = null) { using (var db = new asusIranDBConnection()) { return PagedResult(db.t_Prodcts, currentPage, pageSize, o => true, false, out count, search).ToList(); } }
/// <summary>
/// آیا فایل مورد نظر با فرمت یونیکد دارای امضا ذخیره شده است؟
/// </summary>
/// <param name="filePath">فایل ورودی</param>
/// <returns>بله یا خیر</returns>
public static bool IsUTF8(string filePath)
{
using (FileStream file = new FileStream(filePath,
FileMode.Open, FileAccess.Read, FileShare.Read))
{
if (file.CanSeek)
{
byte[] bom = new byte[4]; // Get the byte-order mark, if there is one
file.Read(bom, 0, 4);
if ((bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf)) // utf-8
{
return true;
}
else
{
return false;
}
}
else
{
//احتمالا فایل بایناری است
return false;
}
}
}
/// <summary>
/// تبدیل یک فایل انسی عربی به یونیکد دارای امضاء
/// </summary>
/// <param name="path">مسیر ورودی</param>
public static void FixWindows1256(string path)
{
try
{
//باز کردن فایل با فرمت انسی عربی و تبدیل به یونیکد
string data = File.ReadAllText(path, Encoding.GetEncoding("windows-1256"));
//نوشتن حاصل یونیکد در جای قبلی با فرمت مربوطه
File.WriteAllText(path, data, Encoding.UTF8);
}
catch (Exception ex)
{
//دسترسی وجود ندارد یا امثال آن
Console.WriteLine(ex.ToString());
}
}
namespace TestPartCover
{
public class Foo
{
public int DoFoo(int x, int y)
{
int z = 0;
if ((x > 0) && (y > 0))
{
z = x;
}
return z;
}
public int DoSum(int x)
{
return ++x;
}
}
}
using NUnit.Framework;
namespace TestPartCover.Tests
{
[TestFixture]
public class Tests
{
[Test]
public void TestDoFoo()
{
var result = new Foo().DoFoo(-1, 2);
Assert.That(result == 0);
}
}
}
<configuration>
<startup>
<supportedRuntime version="v4.0.30319" />
</startup>
<runtime>
<loadFromRemoteSources enabled="true" />
TestPartCover.Tests.dll /framework=4.0.30319 /noshadow
+[TestPartCover]*
-[nunit*]*
-[log4net*]*
<PartCoverSettings>
<Target>D:\Prog\Libs\NUnit\bin\net-2.0\nunit-console.exe</Target>
<TargetWorkDir>D:\Prog\1390\TestPartCover\TestPartCover.Tests\bin\Debug</TargetWorkDir>
<TargetArgs>TestPartCover.Tests.dll /framework=4.0.30319 /noshadow</TargetArgs>
<Rule>+[TestPartCover]*</Rule>
<Rule>-[nunit*]*</Rule>
<Rule>-[log4net*]*</Rule>
</PartCoverSettings>
namespace EmberJS02.Models { public class User { public int Id { set; get; } public string UserName { set; get; } public string Email { set; get; } } }
using System.Collections.Generic; using System.Web.Http; using EmberJS02.Models; namespace EmberJS02.Controllers { public class UsersController : ApiController { // GET api/<controller> public IEnumerable<User> Get() { return UsersDataSource.UsersList; } } }
using System; using System.Web.Http; using System.Web.Routing; namespace EmberJS02 { public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { RouteTable.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } } }
PM> Install-Package EmberJS
App = Ember.Application.create(); App.IndexRoute = Ember.Route.extend({ setupController:function(controller) { controller.set('content', ['red', 'yellow', 'blue']); } });
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <script src="Scripts/jquery-2.1.1.js" type="text/javascript"></script> <script src="Scripts/handlebars.js" type="text/javascript"></script> <script src="Scripts/ember.js" type="text/javascript"></script> <script src="Scripts/app.js" type="text/javascript"></script> </head> <body> <script type="text/x-handlebars" data-template-name="application"> <h1>Header</h1> {{outlet}} </script> <script type="text/x-handlebars" data-template-name="index"> Hello, <strong>Welcome to Ember.js</strong>! <ul> {{#each item in content}} <li> {{item}} </li> {{/each}} </ul> </script> </body> </html>
App.Router.map(function() { this.resource('about'); });
<script type="text/x-handlebars" data-template-name="about"> <h2>Our about page</h2> </script>
<script type="text/x-handlebars" data-template-name="application"> <h1>Ember Demo App</h1> <ul class="nav"> <li>{{#linkTo 'index'}}Home{{/linkTo}}</li> <li>{{#linkTo 'about'}}About{{/linkTo}}</li> </ul> {{outlet}} </script>
App.Router.map(function() { this.resource('about'); this.resource('users'); });
App.UsersLink = Ember.Object.extend({}); App.UsersLink.reopenClass({ findAll: function () { var users = []; $.getJSON('/api/users').then(function(response) { response.forEach(function(item) { users.pushObject(App.UsersLink.create(item)); }); }); return users; } });
App.UsersRoute = Ember.Route.extend({ model: function() { return App.UsersLink.findAll(); } }); App.UsersController = Ember.ObjectController.extend({ customHeader : 'Our Users List' });
<script type="text/x-handlebars" data-template-name="users"> <h2>{{customHeader}}</h2> <ul> {{#each item in model}} <li> {{item.Id}}-{{item.UserName}} ({{item.Email}}) </li> {{/each}} </ul> </script>