ورود

View Full Version : اشکال در PersianCulture



sepehr-nejati
یک شنبه 11 مهر 1395, 14:40 عصر
من از PersianCulture استفاده میکنم

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;

namespace GSD.Globalization
{
/// <summary>
/// <Publisher>http://www.Sayan.ir</Publisher>
/// <Author>Maziar Rezaie</Author>
/// </summary>
public class PersianCulture : CultureInfo
{
private readonly Calendar cal;
private readonly Calendar[] optionals;

/// <summary>
/// كد رو بخوان تا بفهمي
/// </summary>
/// <param name="cultureName">fa-IR</param>
/// <param name="useUserOverride">true</param>
/// <remarks>لطفا در هنگام استفاده به سايت سايان اشاره كنيد.</remarks>
public PersianCulture() : this("fa-IR", true)
{
}

public PersianCulture(string cultureName, bool useUserOverride)
: base(cultureName, useUserOverride)
{
//Temporary Value for cal.
cal = base.OptionalCalendars[0];

//populating new list of optional calendars.
var optionalCalendars = new List<Calendar>();
optionalCalendars.AddRange(base.OptionalCalendars) ;
optionalCalendars.Insert(0, new PersianCalendar());


Type formatType = typeof(DateTimeFormatInfo);
Type calendarType = typeof(Calendar);


PropertyInfo idProperty = calendarType.GetProperty("ID", BindingFlags.Instance | BindingFlags.NonPublic);
FieldInfo optionalCalendarfield = formatType.GetField("optionalCalendars",
BindingFlags.Instance | BindingFlags.NonPublic);

//populating new list of optional calendar ids
var newOptionalCalendarIDs = new Int32[optionalCalendars.Count];
for (int i = 0; i < newOptionalCalendarIDs.Length; i++)
newOptionalCalendarIDs[i] = (Int32)idProperty.GetValue(optionalCalendars[i], null);

optionalCalendarfield.SetValue(DateTimeFormat, newOptionalCalendarIDs);

optionals = optionalCalendars.ToArray();
cal = optionals[0];
DateTimeFormat.Calendar = optionals[0];
DateTimeFormat.MonthNames = new[] { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" };
DateTimeFormat.MonthGenitiveNames = new[] { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" };
DateTimeFormat.AbbreviatedMonthNames = new[] { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" };
DateTimeFormat.AbbreviatedMonthGenitiveNames = new[] { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" };


DateTimeFormat.AbbreviatedDayNames = new string[] { "ی", "د", "س", "چ", "پ", "ج", "ش" };
DateTimeFormat.ShortestDayNames = new string[] { "ی", "د", "س", "چ", "پ", "ج", "ش" };
DateTimeFormat.DayNames = new string[] { "یکشنبه", "دوشنبه", "ﺳﻪ شنبه", "چهارشنبه", "پنج شنبه", "جمعه", "شنبه" };

DateTimeFormat.AMDesignator = "ق.ظ";
DateTimeFormat.PMDesignator = "ب.ظ";

DateTimeFormat.ShortDatePattern = "yyyy-MM-dd";
DateTimeFormat.LongDatePattern = "yyyy-MM-dd";

DateTimeFormat.SetAllDateTimePatterns(new[] { "yyyy-MM-dd" }, 'd');
DateTimeFormat.SetAllDateTimePatterns(new[] { "dddd, dd MMMM yyyy" }, 'D');
DateTimeFormat.SetAllDateTimePatterns(new[] { "yyyy MMMM" }, 'y');
DateTimeFormat.SetAllDateTimePatterns(new[] { "yyyy MMMM" }, 'Y');


}

public override Calendar Calendar
{
get { return cal; }
}

public override Calendar[] OptionalCalendars
{
get { return optionals; }
}
}
}



در Global هم


protected void Application_BeginRequest(object sender, EventArgs e)
{
var persianCulture = new PersianCulture();
persianCulture.DateTimeFormat.ShortDatePattern = "yyyy/MM/dd";
persianCulture.DateTimeFormat.LongDatePattern = "dddd d MMMM yyyy";
persianCulture.DateTimeFormat.AMDesignator = "صبح";
persianCulture.DateTimeFormat.PMDesignator = "عصر";
Thread.CurrentThread.CurrentCulture = persianCulture;
Thread.CurrentThread.CurrentUICulture = persianCulture;
}

در مدل هم از datetime استفاده کردم
[DisplayFormat(DataFormatString = "{0:yyyy/MM/dd}", ApplyFormatInEditMode = true)]

اما موقع ذخیره شدن تاریخ در دیتابیس
تاریخ 2637-12-23 00:00:00.000
ولی در موقع نمایش
2016/10/02
اشکال از کجاست؟؟؟

ali_md110
یک شنبه 11 مهر 1395, 20:46 عصر
شما باید از مدل بایندر برای تبدیل داده های ارسالی از سمت کلاینت به اشیاء دات نتی استفاده کنید

کافیه اونو در startup صدا بزنید



public class PersianDateModelBinder : IModelBinder
{

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var valueResult = bindingContext.ValueProvider.GetValue(bindingConte xt.ModelName);
var modelState = new ModelState { Value = valueResult };
object actualValue = null;
try
{
var parts = valueResult.AttemptedValue.Split('/'); //ex. 1391/1/19
if (parts.Length != 3) return null;
int year = int.Parse(parts[0]);
int month = int.Parse(parts[1]);
int day = int.Parse(parts[2]);
var pc = new PersianCalendar();
var dt = Convert.ToDateTime(pc.ToDateTime(year, month, day, 0, 0, 0, 0, PersianCalendar.PersianEra));

actualValue = dt;// new DateTime(year, month, day, new PersianCalendar());
}
catch (FormatException e)
{
modelState.Errors.Add(e);
}

bindingContext.ModelState.Add(bindingContext.Model Name, modelState);
return actualValue;
}
}
public class MiladiDateModelBinder : IModelBinder
{

public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var valueResult = bindingContext.ValueProvider.GetValue(bindingConte xt.ModelName);
var modelState = new ModelState { Value = valueResult };
object actualValue = null;
try
{
// var parts = valueResult.AttemptedValue.Split('/'); //ex. 1391/1/19
// if (parts.Length != 3) return null;
var dt = Convert.ToDateTime(valueResult.AttemptedValue);
int ym = dt.Year;
int mm = dt.Month;
int dm = dt.Day;
PersianCalendar sss = new PersianCalendar();
int ys = sss.GetYear(new DateTime(ym, mm, dm, new GregorianCalendar()));
int ms = sss.GetMonth(new DateTime(ym, mm, dm, new GregorianCalendar()));
int ds = sss.GetDayOfMonth(new DateTime(ym, mm, dm, new GregorianCalendar()));
actualValue= ys + "/" + ms.ToString("00", CultureInfo.InvariantCulture) + "/" + ds.ToString("00", CultureInfo.InvariantCulture);


}
catch (FormatException e)
{
modelState.Errors.Add(e);
}

bindingContext.ModelState.Add(bindingContext.Model Name, modelState);
return actualValue;
}
}




protected void Application_Start()
{

//try
//{
var persianCulture = new PersianCulture();
Thread.CurrentThread.CurrentCulture = persianCulture;
Thread.CurrentThread.CurrentUICulture = persianCulture;


ModelBinders.Binders.Add(typeof(DateTime?), new PersianDateModelBinder());
ModelBinders.Binders.Add(typeof(DateTime), new PersianDateModelBinder());
{

gama_slv
دوشنبه 12 مهر 1395, 10:58 صبح
در
var valueResult = bindingContext.ValueProvider.GetValue(bindingConte xt.ModelName);
bindingConte xt.ModelName ارور رمیده
و در bindingContext.ModelState.Add(bindingContext.Model Name, modelState);
Name ارورو میده

sepehr-nejati
دوشنبه 12 مهر 1395, 11:20 صبح
از PersianDateModelBinder استفاده کردم و در Startup و Global کدها رو اضافه کردم ولی مشکل حل نشد
رو یک پروژه تستی که فقط یکی کلاس تو مدل دار تست کردم باز نشد؟؟؟

ali_md110
دوشنبه 12 مهر 1395, 19:35 عصر
شما برک پوینت بزارید توی اکشن پست ببینید مقدار فیلدهای ارسالی چقدره
در ضمن این روش تعریف فیلد مدلتون از نوع Datetime یزارید و تاریخ رو بصورت شمسی از سمت ویو ارسال کنی

sepehr-nejati
سه شنبه 13 مهر 1395, 12:35 عصر
برک پوینت گذاشتم
142879
و تاریخ درyear بهم میریزه
142880
کلاسها رو حذف کردم و از ExtensionMethods که سایت dotnettips گذاشته استفاده کردم
در global هم کد زیر رو گذاشتم
protected void Application_BeginRequest(object sender, EventArgs e)
{
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = PersianDateExtensionMethods.GetPersianCulture();
}
باز هم همین مشکل دوباره تکرار میشه اگر در global کد رو نزارم و تاریخ درست ثبت میشه ولی وقتی کد رو قرا میدم تاریخ درست ذحیره نمیشه ولی تاریخ های درست ذخیره شده رو بصورت شمسی نشون میده . یکدفعه این مشکل بوجود امد هیمشه من تو پروژه هام از این روش استفاده میکردم.

gama_slv
پنج شنبه 15 مهر 1395, 12:54 عصر
شما یک اشتباه ساده کردید در هنگام ذخیره کردن تاریخ باید تاریخ رو به جلالی بنویسید نه به میلادی.
PersianCulture تایخ فارسی میگیره و تاریخ در دیتابیس میلادی ذخیره میکنه و در نمایش دوباره تاریخ جلالی یا همون فارسی رو نشون میده
اگر شما تاریخ به میلادی بنویسید در دیتا بیس عدد سال خیلی بزرگ میشه مثلا سال ۹۵ به میلادی میشه 2637
موقع ذخیره سازی تاریخ حتما از یک کاموپونت تاریخ فارسی استفاده کنید تا این مشکل برطرف بشه