मैं कार्ल्स 'कोड के लिए कुछ संवर्द्धन जोड़ा गया है और मामले में उन्हें यहाँ साझा करना चाहते थे वे दूसरों के लिए उपयोगी हैं।
- सुनिश्चित करें कि अगर कोई पैटर्न सफलतापूर्वक समय पार्स, तो अभी भी आधार के लिए एक प्रमाणीकरण त्रुटि दिखाने के लिए फोन (अन्यथा मूल्य
TimeSpan.Zero
रूप में छोड़ दिया जाता है और कोई सत्यापन त्रुटि उठाया।)
- एक पाश नहीं बल्कि का उपयोग करें
if
एस की तुलना में।
AM
और PM
पर्याप्तता के उपयोग का समर्थन करें।
- व्हाइटस्पेस को अनदेखा करें।
कोड यह रहा:
public sealed class TimeSpanModelBinder : DefaultModelBinder
{
private const DateTimeStyles _dateTimeStyles = DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AssumeLocal | DateTimeStyles.NoCurrentDateDefault;
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
{
var form = controllerContext.HttpContext.Request.Form;
if (propertyDescriptor.PropertyType.Equals(typeof(TimeSpan?)) || propertyDescriptor.PropertyType.Equals(typeof(TimeSpan)))
{
var text = form[propertyDescriptor.Name];
TimeSpan time;
if (text != null && TryParseTime(text, out time))
{
SetProperty(controllerContext, bindingContext, propertyDescriptor, time);
return;
}
}
// Either a different type, or we couldn't parse the string.
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
}
public static bool TryParseTime(string text, out TimeSpan time)
{
if (text == null)
throw new ArgumentNullException("text");
var formats = new[] {
"HH:mm", "HH.mm", "HHmm", "HH,mm", "HH",
"H:mm", "H.mm", "H,mm",
"hh:mmtt", "hh.mmtt", "hhmmtt", "hh,mmtt", "hhtt",
"h:mmtt", "h.mmtt", "hmmtt", "h,mmtt", "htt"
};
text = Regex.Replace(text, "([^0-9]|^)([0-9])([0-9]{2})([^0-9]|$)", "$1$2:$3$4");
text = Regex.Replace(text, "^[0-9]$", "0$0");
foreach (var format in formats)
{
DateTime value;
if (DateTime.TryParseExact(text, format, CultureInfo.InvariantCulture, _dateTimeStyles, out value))
{
time = value.TimeOfDay;
return true;
}
}
time = TimeSpan.Zero;
return false;
}
}
यह शीर्ष पर एक छोटे से लग सकता है, लेकिन मैं अपने उपयोगकर्ताओं को काफी कुछ भी दर्ज करें और मेरे ऐप इस पर काम करने में सक्षम होना चाहता हूँ।
यह Global.asax.cs
में इस कोड के माध्यम से सभी DateTime
उदाहरणों के लिए लागू किया जा सकता है:
ModelBinders.Binders.Add(typeof(TimeSpan), new TimeSpanModelBinder());
या सिर्फ एक विशिष्ट कार्रवाई विधि पैरामीटर पर:
public ActionResult Save([ModelBinder(typeof(TimeSpanModelBinder))] MyModel model)
{ ... }
और यहाँ एक सरल इकाई परीक्षण बस मान्य करने के लिए है कुछ संभावित इनपुट/आउटपुट:
[TestMethod]
public void TimeSpanParsing()
{
var testData = new[] {
new { Text = "100", Time = new TimeSpan(1, 0, 0) },
new { Text = "10:00 PM", Time = new TimeSpan(22, 0, 0) },
new { Text = "2", Time = new TimeSpan(2, 0, 0) },
new { Text = "10", Time = new TimeSpan(10, 0, 0) },
new { Text = "100PM", Time = new TimeSpan(13, 0, 0) },
new { Text = "1000", Time = new TimeSpan(10, 0, 0) },
new { Text = "10:00", Time = new TimeSpan(10, 0, 0) },
new { Text = "10.00", Time = new TimeSpan(10, 0, 0) },
new { Text = "13:00", Time = new TimeSpan(13, 0, 0) },
new { Text = "13.00", Time = new TimeSpan(13, 0, 0) },
new { Text = "10 PM", Time = new TimeSpan(22, 0, 0) },
new { Text = " 10\t PM ", Time = new TimeSpan(22, 0, 0) },
new { Text = "10PM", Time = new TimeSpan(22, 0, 0) },
new { Text = "1PM", Time = new TimeSpan(13, 0, 0) },
new { Text = "1 am", Time = new TimeSpan(1, 0, 0) },
new { Text = "1 AM", Time = new TimeSpan(1, 0, 0) },
new { Text = "1 pm", Time = new TimeSpan(13, 0, 0) },
new { Text = "1 PM", Time = new TimeSpan(13, 0, 0) },
new { Text = "01 PM", Time = new TimeSpan(13, 0, 0) },
new { Text = "0100 PM", Time = new TimeSpan(13, 0, 0) },
new { Text = "01.00 PM", Time = new TimeSpan(13, 0, 0) },
new { Text = "01.00PM", Time = new TimeSpan(13, 0, 0) },
new { Text = "1:00PM", Time = new TimeSpan(13, 0, 0) },
new { Text = "1:00 PM", Time = new TimeSpan(13, 0, 0) },
new { Text = "12,34", Time = new TimeSpan(12, 34, 0) },
new { Text = "1012PM", Time = new TimeSpan(22, 12, 0) },
};
foreach (var test in testData)
{
try
{
TimeSpan time;
Assert.IsTrue(TimeSpanModelBinder.TryParseTime(test.Text, out time), "Should parse {0}", test.Text);
if (!Equals(time, test.Time))
Assert.Fail("Time parse failed. Expected {0} but got {1}", test.Time, time);
}
catch (FormatException)
{
Assert.Fail("Received format exception with text {0}", test.Text);
}
}
}
आशा है कि किसी को मदद मिलेगी।
बढ़िया! यह जाने का तरीका है ... –