ভুল তারিখের ফর্ম্যাট সহ এমভিসি ডেটটাইম বাঁধাই


132

Asp.net-MVC এখন ডেটটাইম অবজেক্টের অন্তর্নিহিত বাঁধাইয়ের অনুমতি দেয়। আমার লাইন ধরে একটি ক্রিয়া আছে

public ActionResult DoSomething(DateTime startDate) 
{ 
... 
}

এটি সফলভাবে একটি এজাক্স কল থেকে একটি স্ট্রিংকে ডেটটাইমে রূপান্তর করে। তবে, আমরা তারিখ বিন্যাসটি dd / MM / yyyy ব্যবহার করি; এমভিসি এমএম / ডিডি / ইয়াহিতে রূপান্তর করছে। উদাহরণস্বরূপ, স্ট্রিং '09 / 02/2009 'দিয়ে অ্যাকশনে একটি কল জমা দেওয়ার ফলে আমাদের স্থানীয় সেটিংসে '02 / 09/2009 00:00:00' তারিখের সময় বা 2 শে সেপ্টেম্বর ফলাফল পাওয়া যায়।

তারিখ বিন্যাসের জন্য আমি নিজের মডেল বাইন্ডার রোল করতে চাই না। তবে স্ট্রিং গ্রহণ করার জন্য অ্যাকশনটি পরিবর্তন করতে হবে এবং তারপরে ডেটটাইম ব্যবহার করা বাঞ্ছনীয় M এমভিসি আমার পক্ষে এটি করতে সক্ষম হয় তবে পার্স করুন।

ডেটটাইমের জন্য ডিফল্ট মডেল বাইন্ডারে ব্যবহৃত তারিখের বিন্যাসটি পরিবর্তন করার কোনও উপায় আছে কি? ডিফল্ট মডেল বাইন্ডারটি কীভাবে আপনার স্থানীয়করণ সেটিংস ব্যবহার করা উচিত নয়?


আরে .. কেবল আপনার সিস্টেমের তারিখের ফর্ম্যাটটি- DD / MM / yyyy কে এমএম / DD / yyy এ পরিবর্তন করুন এবং এটি সম্পন্ন করেছেন .. আমারও একই সমস্যা আছে, আমি সিস্টেমের তারিখের ফর্ম্যাট পরিবর্তন করে এটি সমাধান করেছি।
ব্যেনি

@ ব্যাণি যদি অ্যাপ্লিকেশনটি বিশ্বব্যাপী হয় এবং প্রত্যেকেরই একই তারিখের সময়ের ফর্ম্যাট না থাকে তবে আপনি এটি কীভাবে করতে পারেন? , আপনি ভাবেন না যে প্রত্যেকের তারিখের সময় ফর্ম্যাটটি পরিবর্তন করুন ..
রবি মেহতা

এই উত্তরগুলির কোনওটিই আমাকে সহায়তা করছে না। ফর্মটি স্থানীয়করণ করা দরকার। কিছু ব্যবহারকারীর তারিখ এক উপায়ে থাকতে পারে, অন্যরা অন্যভাবে। ওয়েবকনফাইগে কিছু সেট আপ করা হচ্ছে। বা গ্লোবাল.অ্যাক্সেক্স সাহায্য করবে না। আমি আরও ভাল উত্তরের সন্ধান চালিয়ে যাব, তবে একটি উপায় হ'ল আমি সিটিতে ফিরে না আসা পর্যন্ত স্ট্রিং হিসাবে তারিখটি মোকাবেলা করা।
অ্যাস্ট্রোস্টেভ

উত্তর:


164

আমি আরও কিছু ক্লান্তিকর গুগলিংয়ের সাথে এর উত্তরটি সবেমাত্র পেয়েছি:

এমভিসি কেন তারিখগুলির সাথে কাজ করে, এবং প্রয়োজনে আপনি কীভাবে এটিকে ওভাররাইড করতে পারেন তার মেলভিন হারবারের একটি বিশদ ব্যাখ্যা রয়েছে:

http://weblogs.asp.net/melvynharbour/archive/2008/11/21/mvc-modelbinder-and-localization.aspx

পার্স করার মানটি খুঁজতে গিয়ে, ফ্রেমওয়ার্কটি একটি নির্দিষ্ট ক্রমে যেমন:

  1. রুটডেটা (উপরে দেখানো হয়নি)
  2. ইউআরআই ক্যোয়ারী স্ট্রিং
  3. অনুরোধ ফর্ম

এর মধ্যে কেবল সর্বশেষ সংস্কৃতি সচেতন হবে। স্থানীয়করণের দৃষ্টিকোণ থেকে এটির জন্য খুব ভাল কারণ রয়েছে। কল্পনা করুন যে আমি একটি ওয়েব অ্যাপ্লিকেশন লিখেছি যাতে আমি অনলাইনে প্রকাশ করি বিমানের বিমানের ফ্লাইটের তথ্য প্রদর্শন করে। আমি সেই দিনের জন্য একটি লিঙ্কে ক্লিক করে একটি নির্দিষ্ট তারিখে ফ্লাইটগুলি সন্ধান করি (সম্ভবতঃ http://www.melsflighttimes.com/Flights/2008-11-21 এর মতো কিছু ) এবং তারপরে আমার সহকর্মীর সাথে সেই লিঙ্কটি ইমেল করতে চাই মার্কিন যুক্তরাষ্ট্র. কেবলমাত্র যেভাবে আমরা গ্যারান্টি দিতে পারি যে আমরা উভয়ই একই পৃষ্ঠার ডেটার দিকে নজর রাখব তা হ'ল যদি ইনভেয়ারেন্টকালচার ব্যবহৃত হয়। বিপরীতে, আমি যদি আমার ফ্লাইট বুক করতে কোনও ফর্ম ব্যবহার করি তবে সবকিছুই একটি শক্ত চক্রের মধ্যে ঘটছে। ফর্মটিতে লেখার সময় ডেটা কারেন্ট কালচারকে সম্মান জানাতে পারে এবং ফর্ম থেকে ফিরে আসার সময় এটিকে সম্মান করা দরকার।


করব. প্রশ্নটি পোস্ট করার পরে 48 ঘন্টা ধরে এই কার্যকারিতা অক্ষম করা আছে।
স্যাম ওয়েসেল

43
আমি দৃ strongly়ভাবে দ্বিমত করব যে প্রযুক্তিগতভাবে এটি সঠিক। মডেল বাইন্ডার সর্বদা পোষ্ট এবং জিইটি এর সাথে একই আচরণ করা উচিত। যদি অচেনা সংস্কৃতি হ'ল জিইটি যাওয়ার উপায় এটি পোষ্টের জন্যও তৈরি করে। HTTP ক্রিয়া উপর নির্ভর করে আচরণ পরিবর্তন করা বুদ্ধিমানের কাজ।
বার্ট ক্যালিক্স্টো

আমার একটি প্রশ্ন আছে, আমাদের ওয়েবসাইটে অন্য দেশে হোস্ট করা আছে, এটির MM/dd/yyyyফর্ম্যাট দরকার অন্যথায় এটি বৈধতা ত্রুটি দেখায় The field BeginDate must be a date., আমি কীভাবে dd/MM/yyyyফর্ম্যাট গ্রহণ করতে পারি ?
শাইজুত

ইউআরএল প্যারামিটারটি আইএসও স্ট্যান্ডার্ড ফর্ম্যাটিং ব্যবহারের মতো পরিষ্কার করা উচিত। তারপরে সংস্কৃতি সেটিংস কোনও বিষয় নয়।
nforss

এটি কারণ ব্যাখ্যা করার জন্য লিঙ্ক দেয় কিন্তু আসলে এই সমস্যার কোনও সহজ সমাধান সরবরাহ করে না (যেমন স্ক্রিপ্ট থেকে কোনও আইএসও ডেটটাইম স্ট্রিং পোস্ট করে), সেই পথটি সর্বদা কাজ করে এবং আমাদের নির্দিষ্ট সংস্কৃতি স্থাপনের বিষয়ে যত্ন নিতে হবে না the সার্ভার বা নিশ্চিত করুন যে ডেটটাইম ফর্ম্যাটটি সার্ভার এবং ক্লায়েন্টের মধ্যে অভিন্ন।
আশাহত

36

আমি বিশ্বব্যাপী আপনার সংস্কৃতি সেট করতে হবে। মডেলবাইন্ডার বাছাই!

  <system.web>
    <globalization uiCulture="en-AU" culture="en-AU" />

অথবা আপনি কেবল এই পৃষ্ঠার জন্য এটি পরিবর্তন।
তবে বিশ্বব্যাপী ওয়েবকনফিগে আমার মনে হয় এটি আরও ভাল


27
আমার জন্য হয়নি। আমি 23/10/2010 পাস করলে তারিখটি শূন্য হয়ে যায়।
GONELE

আমি মনে করি এটি সবচেয়ে সহজ সমাধান। আমার জন্য এটি সমস্ত তারিখে ফর্ম্যাট পরিবর্তন করে o টুস্ট্রিং ()। আমি মনে করি এটি বাঁধাইয়ের সাথেও কাজ করবে, তবে চেক করেনি, দুঃখিত :-(
msa.im

1
আমার ডেভ সার্ভারের ডেটফর্ম্যাটটি ডিডি / এমএম / ইয়ি সেট করা হয়েছে মডেলবাইন্ডার এমএম / ডিডি / ইয়াই ফর্ম্যাটটি ব্যবহার করেছে। ওয়েবকনফাইগে ফর্ম্যাটটি ডিডি / এমএম / ইয়িআইয়ে সেট করা এখন মডেলবাইন্ডারকে ইউরোপীয় বিন্যাসটি ব্যবহার করতে বাধ্য করে। আমার মতে এটি সার্ভারের তারিখ সেটিংস ব্যবহার করা উচিত। যাইহোক আপনি আমার সমস্যা সমাধান করেছেন।
কারেল

এটি আমার জন্য নিখুঁতভাবে কাজ করেছে ... একরকমভাবে এটি অদ্ভুত লাগছিল যদিও আমি জানি যে আমার অ্যাপ্লিকেশন সার্ভারটি ইউকেতে ইউএস ওএস চালাচ্ছে ...: /
টালমারিস

এমভিসি 4 তে পুরোপুরি কাজ করেছেন অ্যাজুরে ওয়েবসাইটগুলিতে চলছে
ম্যাটি বিয়ার

31

ডেটটাইম মডেল বৈশিষ্ট্যের সাথে সংক্ষিপ্ত তারিখের ফর্ম্যাট বাধ্যতামূলকভাবে আমি একই সমস্যাটি করছি। অনেকগুলি বিভিন্ন উদাহরণ দেখার পরে (কেবলমাত্র ডেটটাইম সম্পর্কিত নয়) আমি ফলউইউং একসাথে রেখেছি:

using System;
using System.Globalization;
using System.Web.Mvc;

namespace YourNamespaceHere
{
    public class CustomDateBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            if (controllerContext == null)
                throw new ArgumentNullException("controllerContext", "controllerContext is null.");
            if (bindingContext == null)
                throw new ArgumentNullException("bindingContext", "bindingContext is null.");

            var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

            if (value == null)
                throw new ArgumentNullException(bindingContext.ModelName);

            CultureInfo cultureInf = (CultureInfo)CultureInfo.CurrentCulture.Clone();
            cultureInf.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";

            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);

            try
            {
                var date = value.ConvertTo(typeof(DateTime), cultureInf);

                return date;
            }
            catch (Exception ex)
            {
                bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex);
                return null;
            }
        }
    }

    public class NullableCustomDateBinder : IModelBinder
    {
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            if (controllerContext == null)
                throw new ArgumentNullException("controllerContext", "controllerContext is null.");
            if (bindingContext == null)
                throw new ArgumentNullException("bindingContext", "bindingContext is null.");

            var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

            if (value == null) return null;

            CultureInfo cultureInf = (CultureInfo)CultureInfo.CurrentCulture.Clone();
            cultureInf.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";

            bindingContext.ModelState.SetModelValue(bindingContext.ModelName, value);

            try
            {
                var date = value.ConvertTo(typeof(DateTime), cultureInf);

                return date;
            }
            catch (Exception ex)
            {
                bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex);
                return null;
            }
        }
    }
}

গ্লোবাল এএসএএক্স ফাইলগুলিতে যেভাবে রুটগুলি ইত্যাদি নিয়ন্ত্রিত হয় তা ধরে রাখতে আমি আমার এমভিসি 4 প্রকল্পের কাস্টমমডেলবিন্ডার কনফিগ নামের অ্যাপ্লিকেশন স্টার্ট ফোল্ডারে একটি নতুন সিট্যাটিক ক্লাস যুক্ত করেছি:

using System;
using System.Web.Mvc;

namespace YourNamespaceHere
{
    public static class CustomModelBindersConfig
    {
        public static void RegisterCustomModelBinders()
        {
            ModelBinders.Binders.Add(typeof(DateTime), new CustomModelBinders.CustomDateBinder());
            ModelBinders.Binders.Add(typeof(DateTime?), new CustomModelBinders.NullableCustomDateBinder());
        }
    }
}

আমি তখনই আমার গ্লোবাল এএসএএসএক্স অ্যাপ্লিকেশন_স্টার্ট থেকে স্ট্যাটিক রেজিস্টারকাস্টমমডেলবাইন্ডারগুলিকে এভাবে কল করি:

protected void Application_Start()
{
    /* bla blah bla the usual stuff and then */

    CustomModelBindersConfig.RegisterCustomModelBinders();
}

এখানে একটি গুরুত্বপূর্ণ নোটটি হ'ল আপনি যদি কোনও হিডফিল্ডে ডেটটাইম মানটি লিখেন তবে:

@Html.HiddenFor(model => model.SomeDate) // a DateTime property
@Html.Hiddenfor(model => model) // a model that is of type DateTime

আমি এটি করেছি এবং পৃষ্ঠায় আসল মানটি "এমডি / ডিডি / ইয়াই এইচ: মিমি: এসএসটি টি" এর পরিবর্তে "ডিডি / এমএম / ইয়াই এইচ: মিমি: এসএসটি টিটি" ফর্ম্যাটে ছিল আমার মতো। এর ফলে আমার মডেল বৈধতাটি হয় হয় ব্যর্থ হয় বা ভুল তারিখটি ফিরে আসে (স্পষ্টতই দিন এবং মাসের মানগুলি অদলবদল করে)।

প্রচুর মাথার স্ক্র্যাচিং এবং ব্যর্থ চেষ্টার পরে সমাধানটি হ'ল গ্লোবাল.এএসএক্সে প্রতিটি অনুরোধের জন্য সংস্কৃতি সম্পর্কিত তথ্য সেট করা:

protected void Application_BeginRequest()
{
    CultureInfo cInf = new CultureInfo("en-ZA", false);  
    // NOTE: change the culture name en-ZA to whatever culture suits your needs

    cInf.DateTimeFormat.DateSeparator = "/";
    cInf.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
    cInf.DateTimeFormat.LongDatePattern = "dd/MM/yyyy hh:mm:ss tt";

    System.Threading.Thread.CurrentThread.CurrentCulture = cInf;
    System.Threading.Thread.CurrentThread.CurrentUICulture = cInf;
}

আপনি এটি অ্যাপ্লিকেশন_স্টার্ট বা এমনকি সেশন_সত্তায় আটকে থাকলে এটি কাজ করবে না যেহেতু এটি সেশনের জন্য এটি বর্তমান থ্রেডকে নির্ধারণ করে। আপনি যেমন জানেন যে ওয়েব অ্যাপ্লিকেশনগুলি রাজ্যহীন তাই আপনার অনুরোধটি আগে যে থ্রেডটি প্রস্থান করেছিল তা হ'ল একই থ্রেডটি আপনার বর্তমান অনুরোধটি পরিবেশন করছে তাই আপনার সংস্কৃতি তথ্য ডিজিটাল আকাশের দুর্দান্ত জিসিতে চলে গেছে।

ধন্যবাদ এখানে যান: ইভান জ্লেতেভ - http://ivanz.com/2010/11/03/custom-model-b ਬਾਈ্যান্ডিং- ইউজিং- আইমোডেলবিন্দার- ইন- এএসপি- নেট- এমভিসি- টো- গোটচস /

গারিক - https://stackoverflow.com/a/2468447/578208

দিমিত্রি - https://stackoverflow.com/a/11903896/578208


13

এটি এমভিসি 3 এ কিছুটা আলাদা হতে চলেছে।

ধরুন আমাদের কাছে একটি নিয়ামক এবং গেট মেথডের সাথে একটি ভিউ রয়েছে

public ActionResult DoSomething(DateTime dateTime)
{
    return View();
}

আমাদের মডেলবাইন্ডার যুক্ত করা উচিত

public class DateTimeBinder : IModelBinder
{
    #region IModelBinder Members
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        DateTime dateTime;
        if (DateTime.TryParse(controllerContext.HttpContext.Request.QueryString["dateTime"], CultureInfo.GetCultureInfo("en-GB"), DateTimeStyles.None, out dateTime))
            return dateTime;
        //else
        return new DateTime();//or another appropriate default ;
    }
    #endregion
}

এবং Global.asax এর অ্যাপ্লিকেশন_স্টার্ট () -তে কমান্ড

ModelBinders.Binders.Add(typeof(DateTime), new DateTimeBinder());

এটি একটি শালীন সূচনা পয়েন্ট, তবে এটি সঠিকভাবে বাস্তবায়ন করে না IModelBinder, বিশেষত বৈধতার বিষয়ে। এছাড়াও, এটি শুধুমাত্র কাজ করে নাম DateTimeহয় DATETIME
স্যাম

2
এছাড়াও, আমি খুঁজে পেয়েছি যে DateTime?যদি আপনি অন্য কল যুক্ত করেন তবে এটি কেবলমাত্র কাজ ModelBinders.Binders.Addকরে typeof(DateTime?)
স্যাম

8

এটি লক্ষণীয় যে আপনার নিজের মডেল বাইন্ডার তৈরি না করেও একাধিক বিভিন্ন ফর্ম্যাট পার্সেবল হতে পারে।

উদাহরণস্বরূপ মার্কিন যুক্তরাষ্ট্রে নিম্নলিখিত স্ট্রিংগুলির সমতুল্য এবং স্বয়ংক্রিয়ভাবে একই ডেটটাইম মানের সাথে আবদ্ধ হয়ে উঠুন:

/ কোম্পানী / প্রেস / মে% 2001% 202008

/ কোম্পানী / প্রেস / 2008-05-01

/ কোম্পানী / প্রেস / 05-01-2008

আমি দৃyy়ভাবে yyyy-mm-dd ব্যবহার করার পরামর্শ দিচ্ছি কারণ এটি অনেক বেশি বহনযোগ্য। আপনি একাধিক স্থানীয় ফর্ম্যাট পরিচালনা করার সাথে সত্যই ডিল করতে চান না। কেউ যদি ৫ ই জানুয়ারির পরিবর্তে ১ লা মে ফ্লাইট বুক করে তবে আপনার বড় সমস্যা হতে চলেছে!

এনবি: আমি যদি স্পষ্টতই পরিষ্কার নই তবে যদি ইয়াই-মিমি-ডিডি সমস্ত সংস্কৃতিতে সর্বজনীনভাবে বিভক্ত হয় তবে সম্ভবত যে কেউ জানেন তারা একটি মন্তব্য যুক্ত করতে পারেন।


3
যেহেতু কেউই বলে না যে ইয়ে-এমএম-ডিডি সর্বজনীন নয়, আমি অনুমান করি এটি।
ডিয়ারচাও

এটি আমার মতে একটি মডেল বাইন্ডার ব্যবহার করার চেয়ে ভাল। .datepicker ("বিকল্প", "তারিখের ফর্ম্যাট", "yy-মিমি-ডিডি") বা কেবল এটি ডিফল্টে সেট করুন।
বার্ট ক্যালিক্স্টো

6

আইওএসএসটিং () ব্যবহার করার চেষ্টা করুন। এটি ISO8601 ফর্ম্যাটে স্ট্রিং প্রদান করে।

জিইটি পদ্ধতি

জাভাস্ক্রিপ্ট

$.get('/example/doGet?date=' + new Date().toISOString(), function (result) {
    console.log(result);
});

C #

[HttpGet]
public JsonResult DoGet(DateTime date)
{
    return Json(date.ToString(), JsonRequestBehavior.AllowGet);
}

পোস্ট পদ্ধতি

জাভাস্ক্রিপ্ট

$.post('/example/do', { date: date.toISOString() }, function (result) {
    console.log(result);
});

C #

[HttpPost]
public JsonResult Do(DateTime date)
{
     return Json(date.ToString());
}

5

আমি আমার এমভিসি 4 এ নীচের কনফিগারেশন সেট করেছি এবং এটি একটি কবজির মতো কাজ করে

<globalization uiCulture="auto" culture="auto" />

3
এটি আমার পক্ষেও কাজ করেছিল। নোট করুন যে বিশ্বায়ন উপাদানটি কনফিগারেশন> সিস্টেম.ওয়েব এর অধীনে চলে। msdn.microsoft.com/en-us/library/hy4kkhe0%28v=vs.85%29.aspx
Jowen

1
  public class DateTimeFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Request.RequestType == "GET")
        {

            foreach (var parameter in filterContext.ActionParameters)
            {
                var properties = parameter.Value.GetType().GetProperties();

                foreach (var property in properties)
                {
                    Type type = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;

                    if (property.PropertyType == typeof(System.DateTime) || property.PropertyType == typeof(DateTime?))
                    {
                        DateTime dateTime;

                        if (DateTime.TryParse(filterContext.HttpContext.Request.QueryString[property.Name], CultureInfo.CurrentUICulture, DateTimeStyles.None, out dateTime))
                            property.SetValue(parameter.Value, dateTime,null);
                    }
                }

            }
        }
    }
}

এটি কাজ করে না। dd-MM-yyyy এখনও স্বীকৃত নয়
jao

1
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    var str = controllerContext.HttpContext.Request.QueryString[bindingContext.ModelName];
    if (string.IsNullOrEmpty(str)) return null;
    var date = DateTime.ParseExact(str, "dd.MM.yyyy", null);
    return date;
}

1
কিছু ব্যাখ্যা যুক্ত করে আপনার উত্তরটি আরও সমৃদ্ধ করা উচিত।
আলেকজান্দ্রে লাভোয়ে

স্মৃতি থেকে, বিল্ট-ইন মডেল বাইন্ডারগুলি যেভাবে কাজ করে তার সাথে এটি সামঞ্জস্যপূর্ণ নয়, সুতরাং এটির বৈধতার জন্য টাইপ করা মান ধরে রাখার মতো একই গৌণ আচরণ নাও হতে পারে।
স্যাম

1

আমি সেট CurrentCultureএবং CurrentUICultureআমার কাস্টম বেস নিয়ামক

    protected override void Initialize(RequestContext requestContext)
    {
        base.Initialize(requestContext);

        Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-GB");
        Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-GB");
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.