public class Model { public string Photo { get; set; } }
public class viewModel { public IFormFile Photo { get; set; } }
public class Model { public string Photo { get; set; } }
public class viewModel { public IFormFile Photo { get; set; } }
static void PassByValueSample() { int a = 1; PassByValue(a); Console.WriteLine($"after the invocation of {nameof(PassByValue)}, {nameof(a)} = {a}"); } static void PassByValue(int x) { x = 2; }
static void PassByReferenceSample() { int a = 1; PassByReference(ref a); Console.WriteLine($"after the invocation of {nameof(PassByReference)}, {nameof(a)} = {a}"); } static void PassByReference(ref int x) { x = 2; }
static void OutSample() { Out(out int a); Console.WriteLine($"after the invocation of {nameof(Out)}, {nameof(a)} = {a}"); } static void Out(out int x) { x = 2; }
if (int.TryParse("42", out var result)) { Console.WriteLine($"the result is {result}"); }
int x = 3; ref int x1 = ref x; x1 = 2; Console.WriteLine($"local variable {nameof(x)} after the change: {x}");
ref int i = sequence.Count();
ref int number1 = null; // ERROR ref int number2 = 42; // ERROR
static ref int ReturnByReference() { int[] arr = { 1 }; ref int x = ref arr[0]; return ref x; }
static ref int ReturnByReference2() { int[] arr = { 1 }; return ref arr[0]; }
static ref int ReturnByReference3(ref int x) { x = 2; return ref x; }
class Thing1 { ref string _Text1; /* Error */ ref string Text2 { get; set; } /* Error */ string _text = "Text"; ref string Text3 { get { return ref _text; } } // Properties that return a reference are allowed }
private MyBigStruct[] array = new MyBigStruct[10]; private int current; public ref MyBigStruct GetCurrentItem() { return ref array[current]; }
[MapFrom(typeof (Student), ignoreAllNonExistingProperty: true, alsoCopyMetadata: true)] public class AdminStudentViewModel { // [IgnoreMap] public int Id { set; get; } [MapForMember("Name")] public string FirstName { set; get; } [MapForMember("Family")] public string LastName { set; get; } public string Email { set; get; } [MapForMember("RegisterDateTime")] public string RegisterDateTimePersian { set; get; } [UseValueResolver(typeof (BookCountValueResolver))] public int BookCounts { set; get; } [UseValueResolver(typeof (BookPriceValueResolver))] public decimal BookPrice { set; get; } };
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public class MapFromAttribute : Attribute { public Type SourceType { get; private set; } public bool IgnoreAllNonExistingProperty { get; private set; } public bool AlsoCopyMetadata { get; private set; } //Go to: https://www.dntips.ir/courses/topic/16/cb36bc2e-4263-431e-86a5-236322cb5576 public MapFromAttribute(Type sourceType, bool ignoreAllNonExistingProperty = false, bool alsoCopyMetadata = false) { SourceType = sourceType; IgnoreAllNonExistingProperty = ignoreAllNonExistingProperty; AlsoCopyMetadata = alsoCopyMetadata; } };
[AttributeUsage(AttributeTargets.Property)] public class IgnoreMapAttribute : Attribute {};
[AttributeUsage(AttributeTargets.Property)] public class MapForMemberAttribute : Attribute { public string MemberToMap { get; private set; } public MapForMemberAttribute(string memberToMap) { MemberToMap = memberToMap; } };
[AttributeUsage(AttributeTargets.Property)] public class UseValueResolverAttribute : Attribute { public IValueResolver ValueResolver { get; private set; } public UseValueResolverAttribute(Type valueResolver) { ValueResolver = valueResolver.GetConstructors()[0].Invoke(new object[] {}) as IValueResolver; } };
Options یا Maybe در یک زبان تابعی مثل #F، نشان دهندهی این است که شیء (Object) ممکن است وجود نداشته باشد(Null Reference) که یکی از مهمترین ویژگیهای یک زبان شیءگرا مثل #C و یا Java محسوب میشود. ما برنامه نویسها (اغلب) از هرچیزی که باعث کرش برنامه میشود، بیزاریم و برای اینکه برنامه کرش نکند، مجبور میشویم تمام کدهای خود را از Null Reference محافظت کنیم. تمام این مشکلات توسط Tony Hoare مخترع ALOGL است که تنها دلیل وجود Null References را سادگی پیاده سازی آن میداند و او این مورد را یک «خطای میلیون دلاری» نامیدهاست.
به این مثال توجه بفرمایید:
public class User { public int Id { get; set; } public string Name { get; set; } } public class UserService : IUserService { private IList<User> _userData; public UserService() { _userData = new List<User> { new User {Id = 1,Name = "ali"}, new User {Id = 2,Name = "Karim"} }; } public User GetById(int id) { return _userData.FirstOrDefault(x => x.Id == id); } } public class UserController : Controller { private readonly IUserService _userService; public UserController(IUserService userService) { _userService = userService; } public ActionResult Details(int id) { var user=_userService.GetById(3); // این متد ممکن است مقداری برگرداند و یا مقدار نال برگرداند if( user == null) return HttpNotFound(); return View(user); } }
این کدی است که ما برنامه نویسان به صورت متداولی با آن سروکار داریم. اما چه چیزی درباره این کد اشکال دارد؟
مشکل از آن جایی هست که ما نمیدانیم متد GetById مقداری را برمیگرداند و یا Null را بر میگرداند. این متد هرگاه که امکان برگرداندن Null وجود داشته باشد، خطای NullReferenceException را در زمان اجرا بر میگرداند و همان طور که میدانید، به ازای هر شرطی که به برنامه اضافه میکنیم، پیچیدگی برنامه هم افزایش مییابد و کد خوانایی خود را از دست میدهد. تصور کنید دنیایی بدون NullReferenceException چه دنیایی زیبایی میبود؛ ولی متاسفانه این مورد از ویژگیهای زبان #C است. خوشبختانه راهحلهای برای حل NRE ارائه شدهاند که در ادامه به آنها میپردازیم.
ما میخواهیم متد GetById همیشه چیزی غیر از نال را برگرداند و یکی از راههایی که ما را به این هدف میرساند این است که این متد یک توالی را برگرداند.
public class UserService : IUserService { private IList<User> _userData; public UserService() { _userData = new List<User> { new User {Id = 1,Name = "ali"}, new User {Id = 2,Name = "Karim"} }; } public IEnumerable<User> GetById(int id) { var user = _userData.FirstOrDefault(x => x.Id == id); if (user == null) return new User[0]; return new[] { user }; } }
اگر به امضای متد GetById توجه کنید، به جای اینکه User را برگرداند، این متد یک توالی از User را بر میگرداند و اگر در اینجا کاربری یافت شد، این توالی دارای یک المان خواهد بود و در غیر این صورت اگر User یافت نشد، این متد یک توالی را بر میگرداند که دارای هیچ المانی نیست. در ادامه اگر کلاینت بخواهد از متد GetById استفاده کند، به صورت زیر خواهد بود:
public ActionResult Details(int id) { var user = _userService .GetById(3) .DefaultIfEmpty(new User()) .Single(); return View(user); }
متد GetById دارای دو وجه است و وجه مثبت آن این است که اگر مجموعه دارای مقداری باشد، هیچ مشکلی نیست؛ ولی اگر مجموعه دارای المانی نباشد، باید یک شیء را به صورت پیش فرض به آن اختصاص دهیم که این کار را با استفاده از متد DefualtIfEmpty انجام دادهایم.
در اول مقاله هم اشاره کردیم که Maybe یا Options، مجموعهای است که دارای یک المان و یا هیچ المانی است. اگر به امضای متد GetById توجه کنید، متوجه خواهید شد که این متد میتواند مجموعهای را برگرداند و نمیتواند گارانتی کند که حتما مجموعهای را بر میگرداند که دارای یک المان و یا هیچ باشد. برای حل این مشکل میتوانیم از کلاس Option استفاده کنیم:
public class Option<T> : IEnumerable<T> { private readonly T[] _data; private Option(T[] data) { _data = data; } public static Option<T> Create(T element) => new Option<T>(new[] { element }); public static Option<T> CreateEmpty() => new Option<T>(new T[0]); public IEnumerator<T> GetEnumerator() => ((IEnumerable<T>) _data).GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator(); }
تنها دلیل استفاده از متدهای Create و CreateEmpty این است که به خوانایی برنامه کمک کنیم؛ نه بیشتر. در ادامه اگر بخواهیم از کلاس option استفاده کنیم، به صورت زیر خواهد بود:
public class UserService : IUserService { ... ... public Option<User> GetById(int id) { var user = _userData.FirstOrDefault(x => x.Id == id); return user == null ? Option<User>.CreateEmpty() : Option<User>.Create(user); } } public class UserController : Controller { ... ... public ActionResult Details(int id) { var user = _userService .GetById(3) .DefaultIfEmpty(new User()) .Single(); return View(user); } }
چکیده:
مدیریت کردن References کار بسیار پیچیدهای است. قبل از آن که تلاش کنیم مقداری را برگردانیم و یا عملیاتی را بر روی آن انجام دهیم، اول باید مطمئن شویم که این شیء به جایی اشاره میکند. نمونههای متفاوتی از Option و یا Maybe را میتوانید در اینترنت پیدا کنید که هدف نهایی آنها، حذف NullReferenceException است و آشنایی با این ایده، شما را به دنیای برنامه نویسی تابعی در#C هدایت میکند.
for name in ["Vahid", "Hamid", "Saeid"] alert "Hi #{name}"
var i, len, name, ref; ref = ["Vahid", "Hamid", "Saeid"]; for (i = 0, len = ref.length; i < len; i++) { name = ref[i]; alert("Hi " + name); }
for name, i in ["Vahid", "Hamid", "Saeid"] alert "#{i} - Hi #{name}"
alert name for name in ["Vahid", "Hamid", "Saeid"]
names = ["Vahid", "Hamid", "Saeid"] alert name for name in names when name[0] is "V"
var i, len, name, names; names = ["Vahid", "Hamid", "Saeid"]; for (i = 0, len = names.length; i < len; i++) { name = names[i]; if (name[0] === "V") { alert(name); } }
names = "Vahid": "Mohammad Taheri", "Ali": "Ahmadi" alert("#{first} #{last}") for first, last of names
var first, last, names; names = { "Vahid": "Mohammad Taheri", "Ali": "Ahmadi" }; for (first in names) { last = names[first]; alert(first + " " + last); }
num = 6 minstrel = while num -= 1 num + " Hi"
var minstrel, num; num = 6; minstrel = (function() { var _results; _results = []; while (num -= 1) { _results.push(num + " Hi"); } return _results; })();
range = [1..5]
var range; range = [1, 2, 3, 4, 5];
firstTwo = ["one", "two", "three"][0..1]
var firstTwo; firstTwo = ["one", "two", "three"].slice(0, 2);
numbers = [0..9] numbers[3..5] = [-3, -4, -5]
my = "my string"[0..2]
words = ["Vahid", "Hamid", "Saeid", "Ali"] alert "Stop" if "Hamid" in words
@name = "Vahid"
this.name = "Vahid";
User::first = -> @records[0]
User.prototype.first = function() { return this.records[0]; };
alert "OK" if name?
if (typeof name !== "undefined" && name !== null) { alert("OK"); }
name = myName ? "-"
var name; name = typeof myName !== "undefined" && myName !== null ? myName : "-";
user.getAddress()?.getStreetName()
var ref; if ((ref = user.getAddress()) != null) { ref.getStreetName(); }
user.getAddress().getStreetName?()
var base; if (typeof (base = user.getAddress()).getStreetName === "function") { base.getStreetName(); }
namespace DNT.IDP { public static class Config { // api-related resources (scopes) public static IEnumerable<ApiResource> GetApiResources() { return new List<ApiResource> { new ApiResource( name: "imagegalleryapi", displayName: "Image Gallery API", claimTypes: new List<string> {"role" }) }; }
AllowedScopes = { IdentityServerConstants.StandardScopes.OpenId, IdentityServerConstants.StandardScopes.Profile, IdentityServerConstants.StandardScopes.Address, "roles", "imagegalleryapi" },
namespace DNT.IDP { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddIdentityServer() .AddDeveloperSigningCredential() .AddTestUsers(Config.GetUsers()) .AddInMemoryIdentityResources(Config.GetIdentityResources()) .AddInMemoryApiResources(Config.GetApiResources()) .AddInMemoryClients(Config.GetClients()); }
options.Scope.Add("imagegalleryapi");
dotnet add package IdentityServer4.AccessTokenValidation
using IdentityServer4.AccessTokenValidation; namespace ImageGallery.WebApi.WebApp { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddAuthentication(defaultScheme: IdentityServerAuthenticationDefaults.AuthenticationScheme) .AddIdentityServerAuthentication(options => { options.Authority = Configuration["IDPBaseAddress"]; options.ApiName = "imagegalleryapi"; });
namespace ImageGallery.WebApi.WebApp { public class Startup { public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseAuthentication();
namespace ImageGallery.WebApi.WebApp.Controllers { [Route("api/images")] [Authorize] public class ImagesController : Controller {
using System; using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.IdentityModel.Protocols.OpenIdConnect; namespace ImageGallery.MvcClient.Services { public interface IImageGalleryHttpClient { Task<HttpClient> GetHttpClientAsync(); } /// <summary> /// A typed HttpClient. /// </summary> public class ImageGalleryHttpClient : IImageGalleryHttpClient { private readonly HttpClient _httpClient; private readonly IConfiguration _configuration; private readonly IHttpContextAccessor _httpContextAccessor; public ImageGalleryHttpClient( HttpClient httpClient, IConfiguration configuration, IHttpContextAccessor httpContextAccessor) { _httpClient = httpClient; _configuration = configuration; _httpContextAccessor = httpContextAccessor; } public async Task<HttpClient> GetHttpClientAsync() { var currentContext = _httpContextAccessor.HttpContext; var accessToken = await currentContext.GetTokenAsync(OpenIdConnectParameterNames.AccessToken); if (!string.IsNullOrWhiteSpace(accessToken)) { _httpClient.SetBearerToken(accessToken); } _httpClient.BaseAddress = new Uri(_configuration["WebApiBaseAddress"]); _httpClient.DefaultRequestHeaders.Accept.Clear(); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); return _httpClient; } } }
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.1.1.0" /> <PackageReference Include="Microsoft.AspNetCore.Http" Version="2.1.1.0" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.Abstractions" Version="2.1.1.0" /> <PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="5.2.0.0" /> <PackageReference Include="IdentityModel" Version="3.9.0" /> </ItemGroup> </Project>
{ "nbf": 1536394771, "exp": 1536398371, "iss": "https://localhost:6001", "aud": [ "https://localhost:6001/resources", "imagegalleryapi" ], "client_id": "imagegalleryclient", "sub": "d860efca-22d9-47fd-8249-791ba61b07c7", "auth_time": 1536394763, "idp": "local", "role": "PayingUser", "scope": [ "openid", "profile", "address", "roles", "imagegalleryapi" ], "amr": [ "pwd" ] }
An unhandled exception occurred while processing the request. HttpRequestException: Response status code does not indicate success: 401 (Unauthorized). System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
public async Task<IActionResult> Index() { var httpClient = await _imageGalleryHttpClient.GetHttpClientAsync(); var response = await httpClient.GetAsync("api/images"); if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized || response.StatusCode == System.Net.HttpStatusCode.Forbidden) { return RedirectToAction("AccessDenied", "Authorization"); } response.EnsureSuccessStatusCode();
namespace ImageGallery.WebApi.WebApp.Controllers { [Route("api/images")] [Authorize] public class ImagesController : Controller { [HttpGet()] public async Task<IActionResult> GetImages() { var ownerId = this.User.Claims.FirstOrDefault(claim => claim.Type == "sub").Value;
namespace ImageGallery.WebApi.Services { public class ImagesService : IImagesService { public Task<List<Image>> GetImagesAsync(string ownerId) { return _images.Where(image => image.OwnerId == ownerId).OrderBy(image => image.Title).ToListAsync(); }
namespace ImageGallery.WebApi.WebApp.Controllers { [Route("api/images")] [Authorize] public class ImagesController : Controller { [HttpGet()] public async Task<IActionResult> GetImages() { var ownerId = this.User.Claims.FirstOrDefault(claim => claim.Type == "sub").Value; var imagesFromRepo = await _imagesService.GetImagesAsync(ownerId); var imagesToReturn = _mapper.Map<IEnumerable<ImageModel>>(imagesFromRepo); return Ok(imagesToReturn); }
namespace ImageGallery.WebApi.Services { public class ImagesService : IImagesService { public Task<bool> IsImageOwnerAsync(Guid id, string ownerId) { return _images.AnyAsync(i => i.Id == id && i.OwnerId == ownerId); }
namespace DNT.IDP { public static class Config { // api-related resources (scopes) public static IEnumerable<ApiResource> GetApiResources() { return new List<ApiResource> { new ApiResource( name: "imagegalleryapi", displayName: "Image Gallery API", claimTypes: new List<string> {"role" }) }; }
namespace ImageGallery.WebApi.WebApp.Controllers { [Route("api/images")] [Authorize] public class ImagesController : Controller { [HttpPost] [Authorize(Roles = "PayingUser")] public async Task<IActionResult> CreateImage([FromBody] ImageForCreationModel imageForCreation) {
var ownerId = User.Claims.FirstOrDefault(c => c.Type == "sub").Value; imageEntity.OwnerId = ownerId; // add and save. await _imagesService.AddImageAsync(imageEntity);
@if(User.IsInRole("PayingUser")) { <li><a asp-area="" asp-controller="Gallery" asp-action="AddImage">Add an image</a></li> <li><a asp-area="" asp-controller="Gallery" asp-action="OrderFrame">Order a framed picture</a></li> }
namespace ImageGallery.MvcClient.WebApp.Controllers { [Authorize] public class GalleryController : Controller { [Authorize(Roles = "PayingUser")] public IActionResult AddImage() { return View(); }
[HttpPost] [Authorize(Roles = "PayingUser")] [ValidateAntiForgeryToken] public async Task<IActionResult> AddImage(AddImageViewModel addImageViewModel)
/// <summary> /// حساب بانکی /// </summary> public class Account { /// <summary> /// مشتری /// </summary> public string Customer { get; set; } /// <summary> /// موجودی حساب /// </summary> public float Balance { get; set; } /// <summary> /// وضعیت /// </summary> public bool Active { get; set; } public Account(string customer, float balance) { Customer = customer; Balance = balance; Active = true; } /// <summary> /// افزایش موجودی / واریز به حساب /// </summary> /// <param name="amount">مبلغ واریز</param> public void Credit(float amount) { if (!Active) throw new Exception("این حساب مسدود است."); if (amount < 0) throw new ArgumentOutOfRangeException("amount"); Balance += amount; } /// <summary> /// کاهش موجودی / برداشت از حساب /// </summary> /// <param name="amount">مبلغ برداشت</param> public void Debit(float amount) { if (!Active) throw new Exception("این حساب مسدود است."); if (amount < 0) throw new ArgumentOutOfRangeException("amount"); if (Balance < amount) throw new ArgumentOutOfRangeException("amount"); Balance -= amount; } /// <summary> /// انسداد / رفع انسداد /// </summary> public void ChangeStateAccount() { Active = !Active; } }
class Program { static void Main(string[] args) { var account = new Account("Ali",1000); account.Credit(4000); account.Debit(2000); Console.WriteLine("Current balance is ${0}", account.Balance); Console.ReadKey(); } }
[TestClass] public class UnitTest { /// <summary> /// تعریف حساب جدید و بررسی تمامی فرآیندهای معمول روی حساب /// </summary> [TestMethod] public void Create_New_Account_And_Check_The_Process() { //Arrange var account = new Account("Hassan", 4000); var account2 = new Account("Ali", 10000); //Act account.Credit(5000); account2.Debit(3000); account.ChangeStateAccount(); account2.Active = false; account2.ChangeStateAccount(); //Assert Assert.AreEqual(account.Balance,9000); Assert.AreEqual(account2.Balance,7000); Assert.IsTrue(account2.Active); Assert.AreEqual(account.Active,false); }
/// <summary> /// زمانی که کاربر بخواهد به یک حساب مسدود واریز کند باید جلوی آن گرفته شود. /// </summary> [TestMethod] [ExpectedException(typeof (Exception))] public void When_Deactive_Account_Wants_To_add_Credit_Should_Throw_Exception() { //Arrange var account = new Account("Hassan", 4000) {Active = false}; //Act account.Credit(4000); //Assert //Assert is handled with ExpectedException } [TestMethod] [ExpectedException(typeof (ArgumentOutOfRangeException))] public void When_Customer_Wants_To_Debit_More_Than_Balance_Should_Throw_ArgumentOutOfRangeException() { //Arrange var account = new Account("Hassan", 4000); //Act account.Debit(5000); //Assert //Assert is handled with ArgumentOutOfRangeException }
public class OrganizationalService : ICommandHandler<CreateUnitTypeCommand>, ICommandHandler<DeleteUnitTypeCommand>, { private readonly IUnitOfWork _unitOfWork; private readonly IUnitTypeRepository _unitTypeRepository; private readonly IOrganizationUnitRepository _organizationUnitRepository; private readonly IOrganizationUnitDomainService _organizationUnitDomainService; public OrganizationalService(IUnitOfWork unitOfWork, IUnitTypeRepository unitTypeRepository, IOrganizationUnitRepository organizationUnitRepository, IOrganizationUnitDomainService organizationUnitDomainService) { _unitOfWork = unitOfWork; _unitTypeRepository = unitTypeRepository; _organizationUnitRepository = organizationUnitRepository; _organizationUnitDomainService = organizationUnitDomainService; }
[TestClass] public class OrganizationServiceTest { private static OrganizationalService _organizationalService; private static Mock<IUnitTypeRepository> _mockUnitTypeRepository; private static Mock<IUnitOfWork> _mockUnitOfWork; private static Mock<IOrganizationUnitRepository> _mockOrganizationUnitRepository; private static Mock<IOrganizationUnitDomainService> _mockOrganizationUnitDomainService; [ClassInitialize] public static void ClassInit(TestContext context) { TestBootstrapper.ConfigureDependencies(); _mockUnitOfWork = new Mock<IUnitOfWork>(); _mockUnitTypeRepository = new Mock<IUnitTypeRepository>(); _mockOrganizationUnitRepository = new Mock<IOrganizationUnitRepository>(); _mockOrganizationUnitDomainService=new Mock<IOrganizationUnitDomainService>(); _organizationalService = new OrganizationalService(_mockUnitOfWork.Object, _mockUnitTypeRepository.Object, _mockOrganizationUnitRepository.Object,_mockOrganizationUnitDomainService.Object); }
/// <summary> /// یک نوع واحد سازمانی را حذف مینماید /// </summary> /// <param name="command"></param> public void Handle(DeleteUnitTypeCommand command) { var unitType = _unitTypeRepository.FindBy(command.UnitTypeId); if (unitType == null) throw new DeleteEntityNotFoundException(); ICanDeleteUnitTypeSpecification canDeleteUnitType = new CanDeleteUnitTypeSpecification(_organizationUnitRepository); if (canDeleteUnitType.IsSatisfiedBy(unitType)) throw new UnitTypeIsUnderUsingException(unitType.Title); _unitTypeRepository.Remove(unitType); }
/// <summary> /// کامند حذف نوع واحد سازمانی باید به درستی حذف کند. /// </summary> [TestMethod] public void DeleteUnitTypeCommand_Should_Delete_UnitType() { //Arrange var unitTypeId=new Guid(); var deleteUnitTypeCommand = new DeleteUnitTypeCommand { UnitTypeId = unitTypeId }; var unitType = new UnitType("خوشه"); var org = new List<OrganizationUnit>(); _mockUnitTypeRepository.Setup(d => d.FindBy(deleteUnitTypeCommand.UnitTypeId)).Returns(unitType); _mockUnitTypeRepository.Setup(x => x.Remove(unitType)); _mockOrganizationUnitRepository.Setup(z => z.FindBy(unitType)).Returns(org); try { //Act _organizationalService.Handle(deleteUnitTypeCommand); } catch (Exception ex) { //Assert Assert.Fail(ex.Message); } }
/// <summary> /// کامند حذف یک نوع واحد سازمانی باید پیش از حذف بررسی کند که این شناسه داده شده برای حذف موجود باشد. /// </summary> [TestMethod] [ExpectedException(typeof(DeleteEntityNotFoundException))] public void DeleteUnitTypeCommand_ShouldNot_Delete_When_UnitTypeId_NotExist() { //Arrange var unitTypeId = new Guid(); var deleteUnitTypeCommand = new DeleteUnitTypeCommand(); var unitType = new UnitType("خوشه"); var org = new List<OrganizationUnit>(); _mockUnitTypeRepository.Setup(d => d.FindBy(unitTypeId)).Returns(unitType); _mockUnitTypeRepository.Setup(x => x.Remove(unitType)); _mockOrganizationUnitRepository.Setup(z => z.FindBy(unitType)).Returns(org); //Act _organizationalService.Handle(deleteUnitTypeCommand); } /// <summary> /// کامند حذف یک نوع واحد سازمانی نباید اجرا شود وقتی که نوع واحد برای تعریف واحدهای سازمان استفاده شده است. /// </summary> [TestMethod] [ExpectedException(typeof(UnitTypeIsUnderUsingException))] public void DeleteUnitTypeCommand_ShouldNot_Delete_When_UnitType_Exist_but_UsedForDefineOrganizationUnit() { //Arrange var unitTypeId = new Guid(); var deleteUnitTypeCommand = new DeleteUnitTypeCommand { UnitTypeId = unitTypeId }; var unitType = new UnitType("خوشه"); var org = new List<OrganizationUnit>() { new OrganizationUnit("مدیریت یک", unitType, null), new OrganizationUnit("مدیریت دو", unitType, null) }; _mockUnitTypeRepository.Setup(d => d.FindBy(deleteUnitTypeCommand.UnitTypeId)).Returns(unitType); _mockUnitTypeRepository.Setup(x => x.Remove(unitType)); _mockOrganizationUnitRepository.Setup(z => z.FindBy(unitType)).Returns(org); //Act _organizationalService.Handle(deleteUnitTypeCommand); }
Install-Package mongocsharpdriver
public class Author { public ObjectId Id { get; set; } public string Name { get; set; } }
public class Language { public ObjectId Id { get; set; } public string Name { get; set; } }
public class Book { public ObjectId Id { get; set; } public string Title { get; set; } public string ISBN { get; set; } public int Price { get; set; } public List<Author> Authors { get; set; } public Language Language { get; set; } }
var book =new Book() { Title = "Gone With Wind", ISBN = "43442424", Price = 50000, Language = new Language() { Name = "Persian" }, Authors = new List<Author>() { new Author() { Name = "Margaret Mitchell" }, new Author() { Name = "Ali Mahboobi (Translator)" }, } };
var client = new MongoClient();
string connectionString = "mongodb://localhost:27017"; MongoClientSettings settings = MongoClientSettings.FromUrl(new MongoUrl(connectionString)); var client = new MongoClient(settings);
var db = client.GetDatabase("publisher");
var collection = db.GetCollection<Book>("books");
collection.InsertOneAsync(book);
فعلا موجودیتهای مؤلفان و زبان به دلیل اینکه سند اختصاصی برای خود ندارند، با صفر پر شدهاند؛ ولی شناسه یکتای سند، مقدار خود را گرفته است.
عملیات خواندن
var client = new MongoClient(); var db = client.GetDatabase("publisher"); db.DropCollection("books"); var collection = db.GetCollection<Book>("books"); var book =new Book() { Title = "Gone With Wind", ISBN = "43442424", Price = 50000, Year = 1936, LastStock = DateTime.Now.AddDays(-13), Language = new Language() { Name = "Persian" }, Authors = new List<Author>() { new Author() { Name = "Margaret Mitchell" }, new Author() { Name = "Ali Mahboobi (Translator)" }, } }; var book2 = new Book() { Title = "Jane Eyre", ISBN = "87897897", Price = 60000, Year = 1847, LastStock = DateTime.Now.AddDays(-5), Language = new Language() { Name = "English" }, Authors = new List<Author>() { new Author() { Name = "Charlotte Brontë" }, } }; var book3 = new Book() { Title = "White Fang", ISBN = "43442424", Price = 50000, Year = 1936, LastStock = DateTime.Now.AddDays(-13), Language = new Language() { Name = "English" }, Authors = new List<Author>() { new Author() { Name = "Jack London" }, new Author() { Name = "Philippe Mignon" }, } }; var book4 = new Book() { Title = "The Lost Symbol", ISBN = "43442424", Price = 3500000, Year = 2009, LastStock = DateTime.Now.AddDays(-17), Language = new Language() { Name = "Persian" }, Authors = new List<Author>() { new Author() { Name = "Dan Brown" }, new Author() { Name = "Mehrdad" }, } }; var book7 = new Book() { Title = "The Lost Symbol", ISBN = "43442424", Price = 47000000, Year = 2009, LastStock = DateTime.Now.AddDays(-56), Language = new Language() { Name = "Persian" }, Authors = new List<Author>() { new Author() { Name = "Dan Brown" }, new Author() { Name = "Mehrdad" }, } }; var book5= new Book() { Title = "The Help", ISBN = "45345e3er3", Price = 9000000, Year = 2009, LastStock = DateTime.Now.AddDays(-2), Language = new Language() { Name = "Enlish" }, Authors = new List<Author>() { new Author() { Name = "Kathryn Stockett" }, } }; var book6 = new Book() { Title = "City of Glass", ISBN = "454534545", Price = 500000, Year = 2009, LastStock = DateTime.Now, Language = new Language() { Name = "Persian" }, Authors = new List<Author>() { new Author() { Name = "Cassandra Clare" }, new Author() { Name = "Ali" }, } }; var books = new List<Book> {book, book2, book3, book4, book5, book6,book7}; collection.InsertManyAsync(books);
var client = new MongoClient(); var db = client.GetDatabase("publisher"); var collection = db.GetCollection<Book>("books"); var filter=new BsonDocument(); var docs = collection.Find(filter).ToList(); foreach (var book in docs) { Console.WriteLine(book.Title + " By "+ book.Authors[0].Name); }
Gone With Wind By Margaret Mitchell Jane Eyre By Charlotte Brontë White Fang By Jack London The Lost Symbol By Dan Brown The Help By Kathryn Stockett City of Glass By Cassandra Clare The Lost Symbol By Dan Brown
var filter = Builders<Book>.Filter.Eq("Year", 2009); var docs = collection.Find(filter).ToList(); foreach (var book in docs) { Console.WriteLine(book.Title + " By "+ book.Authors[0].Name); }
The Lost Symbol By Dan Brown The Help By Kathryn Stockett City of Glass By Cassandra Clare The Lost Symbol By Dan Brown
// var filter=new BsonDocument(); var filterBuilder = Builders<Book>.Filter; var filter= filterBuilder.Eq("Year", 2009) | filterBuilder.Gte("Price",700000); var docs = collection.Find(filter).ToList(); foreach (var book in docs) { Console.WriteLine(book.Title + " By "+ book.Authors[0].Name); }
Gone With Wind By Margaret Mitchell White Fang By Jack London The Lost Symbol By Dan Brown The Help By Kathryn Stockett City of Glass By Cassandra Clare The Lost Symbol By Dan Brown
var docs = collection.AsQueryable().Where(x => x.Year == 2009 || x.Price <= 50000).ToList();
var sort = Builders<Book>.Sort.Ascending("Title").Descending("Price"); var docs = collection.Find(filter).Sort(sort).ToList(); foreach (var book in docs) { Console.WriteLine(book.Title + " By "+ book.Authors[0].Name); }
City of Glass By Cassandra Clare Gone With Wind By Margaret Mitchell The Help By Kathryn Stockett The Lost Symbol By Dan Brown The Lost Symbol By Dan Brown White Fang By Jack London
public class Product { public int Id { set; get; } public DateTime AddDate { set; get; } public string Name { set; get; } public decimal Price { set; get; } }
<!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="~/Content/themes/base/jquery.ui.all.css" rel="stylesheet" /> <link href="~/Content/jquery.jqGrid/ui.jqgrid.css" rel="stylesheet" /> <link href="~/Content/PersianDatePicker.css" rel="stylesheet" /> <link href="~/Content/Site.css" rel="stylesheet" type="text/css" /> </head> <body> <div> @RenderBody() </div> <script src="~/Scripts/jquery-1.7.2.min.js"></script> <script src="~/Scripts/jquery-ui-1.8.11.min.js"></script> <script src="~/Scripts/i18n/grid.locale-fa.js"></script> <script src="~/Scripts/jquery.jqGrid.min.js"></script> <script src="~/Scripts/PersianDatePicker.js"></script> <script src="~/Scripts/jquery.price_format.2.0.js"></script> @RenderSection("Scripts", required: false) </body> </html>
colModel: [ { name: 'Name', index: 'Name', align: 'right', width: 100, editable: true, edittype: 'text', editoptions: { maxlength: 40, dataInit: function (elem) { // http://jqueryui.com/autocomplete/ $(elem).autocomplete({ source: '@Url.Action("GetProductNames","Home")', minLength: 2, select: function (event, ui) { $(elem).val(ui.item.value); $(elem).trigger('change'); } }); } }, editrules: { required: true } } ],
public ActionResult GetProductNames(string term) { var list = ProductDataSource.LatestProducts .Where(x => x.Name.StartsWith(term)) .Select(x => x.Name) .Take(10) .ToArray(); return Json(list, JsonRequestBehavior.AllowGet); }
colModel: [ { name: 'AddDate', index: 'AddDate', align: 'center', width: 100, editable: true, edittype: 'text', editoptions: { maxlength: 10, // https://www.dntips.ir/post/1382 onclick: "PersianDatePicker.Show(this,'@today');" }, editrules: { required: true } } ],
@{ ViewBag.Title = "Index"; var today = DateTime.Now.ToPersianDate(); }
colModel: [ { name: 'Price', index: 'Price', align: 'center', width: 100, formatter: 'currency', formatoptions: { decimalSeparator: '.', thousandsSeparator: ',', decimalPlaces: 2, prefix: '$' }, editable: true, edittype: 'text', editoptions: { dir: 'ltr', dataInit: function (elem) { // http://jquerypriceformat.com/ $(elem).priceFormat({ prefix: '', thousandsSeparator: ',', clearPrefix: true, centsSeparator: '', centsLimit: 0 }); } }, editrules: { required: true, minValue: 0 } } ],
using System; using System.Globalization; using System.Threading; using System.Web.Mvc; namespace jqGrid05.CustomModelBinders { /// <summary> /// How to register it in the Application_Start method of Global.asax.cs /// ModelBinders.Binders.Add(typeof(decimal), new DecimalBinder()); /// </summary> public class DecimalBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if (bindingContext.ModelType == typeof(decimal) || bindingContext.ModelType == typeof(decimal?)) { return bindDecimal(bindingContext); } return base.BindModel(controllerContext, bindingContext); } private static object bindDecimal(ModelBindingContext bindingContext) { var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (valueProviderResult == null) return null; bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); decimal value; var valueAsString = valueProviderResult.AttemptedValue == null ? null : valueProviderResult.AttemptedValue.Trim(); if (string.IsNullOrEmpty(valueAsString)) return null; if (!decimal.TryParse(valueAsString, NumberStyles.Any, Thread.CurrentThread.CurrentCulture, out value)) { const string error ="عدد وارد شده معتبر نیست"; var ex = new InvalidOperationException(error, new Exception(error, new FormatException(error))); bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex); return null; } return value; } } }
using System; using System.Web.Mvc; using System.Web.Routing; using jqGrid05.CustomModelBinders; namespace jqGrid05 { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); ModelBinders.Binders.Add(typeof(DateTime), new PersianDateModelBinder()); ModelBinders.Binders.Add(typeof(decimal), new DecimalBinder()); } } }