how can I use dfd,dtd and soprtr variable into another action? - asp.net-mvc-3

[HttpPost]
public ActionResult crbtmis(string submitbuttonoperator, DateTime fromdate, DateTime todate, string operatorname)
{
DateTime dfd = fromdate;
DateTime dtd = todate;
string soprtr = operatorname;
if (Session["user"] != null && Session["user"].ToString() == "MISADMIN")
{
switch (submitbuttonoperator)
{
case "Export":
return (ExportOprtrlist( fromdate, todate, operatorname));
case "Search":
return (SearchByOperator());
default:
return (View("LogOn"));
}
}
else
{
return RedirectToAction("LogOn");
}
}
I have defined three variable named as dfd,dtd and soprtr and want to use these variable into another ActionResult. Now please help me how will I do it?

In your action, you can use other action that contains some parameters:
public ActionResult crbtmis(string submitbuttonoperator, DateTime fromdate, DateTime todate, string operatorname)
{
//..your code
return RedirectToAction("OtherAction", new { dfd = dfd, dtd = dtd, soprtr = soprtr });
}

Related

How to validate date in my model at client side with data annotation

i have 2 specific require for date validation.
1) date field should be mandatory
2) invalid date will not be accepted.
when date will be empty then i want to show "Date is required"
when date will be invalid then i want to show "Date is invalid"
so guide me how could i do this.
here i try to wrote a code but do not know does it work or not.
public class Student
{
[Required(ErrorMessage = "DOB require")]
[Display(Name = "DOB :")]
[DataType(DataType.Date)]
public DateTime Dob { get; set; }
}
help me to implement this at client side. thanks
EDIT
one person guide me in this way
Inorder to validate date format, its better to create a custom ValidationAttribute as shown below
[AttributeUsage(AttributeTargets.Property, Inherited = false,
AllowMultiple = false)]
public sealed class DateOnlyAttribute : ValidationAttribute
{
public DateOnlyAttribute() :
base("\"{0}\" must be a date without time portion.")
{
}
public override bool IsValid(object value)
{
if (value != null)
{
if (value.GetType() == typeof(DateTime))
{
DateTime dateTime = (DateTime)value;
return dateTime.TimeOfDay == TimeSpan.Zero;
}
else if (value.GetType() == typeof(Nullable<DateTime>))
{
DateTime? dateTime = (DateTime?)value;
return !dateTime.HasValue
|| dateTime.Value.TimeOfDay == TimeSpan.Zero;
}
}
return true;
}
public override string FormatErrorMessage(string name)
{
return string.Format(CultureInfo.CurrentCulture,
ErrorMessageString, name);
}
}
And then you can use it as data annotation as shown below
[DateOnly]
public DateTime Dob { get; set; }
but the above code is not clear to me because i am new in MVC
here is few question on the above code
this code is not clear
public override bool IsValid(object value)
{
if (value != null)
{
if (value.GetType() == typeof(DateTime))
{
DateTime dateTime = (DateTime)value;
return dateTime.TimeOfDay == TimeSpan.Zero;
}
else if (value.GetType() == typeof(Nullable<DateTime>))
{
DateTime? dateTime = (DateTime?)value;
return !dateTime.HasValue
|| dateTime.Value.TimeOfDay == TimeSpan.Zero;
}
}
return true;
}
1) when this is true then what will be return
if (value.GetType() == typeof(DateTime))
2) what this line will do
return dateTime.TimeOfDay == TimeSpan.Zero;
3) what is the meaning of this line
else if (value.GetType() == typeof(Nullable))
4) what is the meaning of this below code
DateTime? dateTime = (DateTime?)value;
return !dateTime.HasValue
|| dateTime.Value.TimeOfDay == TimeSpan.Zero;
please guide me in detail to understand the code what u have written. thanks
Include the following code in the .cshtml file in which you need the client side validation,
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
EDIT
The explanation for the last 4 questions you have asked,
1) if (value.GetType() == typeof(DateTime)) Checks the type of 'value'(object) can be DateTime or not ! In other word, it checks for non nullable date format.
2) return dateTime.TimeOfDay == TimeSpan.Zero; returns false if 'value' has a valid date
TimeSpan.Zero returns TimeSpan for Zero Time (00:00:00)
Note: if you cannot cast 'value' to date time, you get 'datetime' value equal to TimeSpan.Zero
3) else if (value.GetType() == typeof(Nullable)<DateTime>) Same case a question 1, but checking for nullable DateTime (Note: Nullable DateTime and non nullable DateTime are treated as different datatype)
4)
DateTime? dateTime = (DateTime?)value;
return !dateTime.HasValue || dateTime.Value.TimeOfDay == TimeSpan.Zero;
Same case as question 2, if you cannot cast to nullable DateTime, you have 'datetime' equal to TimeSpan.Zero

Validation attributed is cached

I have following code in custom validation attribute called DateRange:
private DateTime _minDate = DateTime.Today.AddYears(-100);
private DateTime _maxDate = DateTime.MaxValue;
// String representation of the Min Date (yyyy/MM/dd)
public string Min
{
get { return FormatDate(_minDate, DateTime.Today.AddYears(-100)); }
set { _minDate = value == "Today" ? DateTime.Today : ParseDate(value, DateTime.Today.AddYears(-100)); }
}
// String representation of the Max Date (yyyy/MM/dd)
public string Max
{
get { return FormatDate(_maxDate, DateTime.MaxValue); }
set { _maxDate = value == "Today" ? DateTime.Today : ParseDate(value, DateTime.MaxValue); }
}
Then I write this attribute in metadata on some property of entity model like this:
[DateRange(Max = "Today")]
public string SomeDateProperty { get; set; };
I set breakpoint on Max property's getter. First time I open view, breakpoint is activated and DateTime.Today is got. Consequent refresh of the view does not activate breakpoint and old value is got. I think it's caching validation attribute. My question is: Is this because of caching? If it is, then how to disable it? Thanks in advance
The constructor for the custom attributes only get hit once, no idea how to turn off any sort of caching. The way I got round this for my scenario, was to only deal with the date calculation in the "IsValid" Method.
I created a date in the past attribute, that needed the date to be in the past, but you could set how long in the past was valid.
public class DateInPastAttribute : ValidationAttribute
{
private const string DefaultErrorMessage = "'{0}' must be in the past.";
public int DaysInPastAllowed { get; set; }
public DateInPastAttribute(int daysInPastAllowed)
: base(DefaultErrorMessage)
{
this.DaysInPastAllowed = daysInPastAllowed;
}
public override bool IsValid(object value)
{
if (!(value is DateTime))
{
return true;
}
DateTime maxDate = DateTime.Now;
DateTime minDate = maxDate.AddDays(this.DaysInPastAllowed * -1);
DateTime dateValue = (DateTime)value;
return
minDate <= dateValue &&
dateValue <= maxDate;
}
public override string FormatErrorMessage(string name)
{
return string.Format(CultureInfo.CurrentCulture, this.ErrorMessageString, name);
}
}
You can then use it in your view model like this:
[DateInPast(365)]
public DateTime DateReceived { get; set; }
Which would allow a date to be entered within the last year. You could amend this for the scenario that you require.

Remote validation not working for guid

[Remote("DropDownSelected", "Patient")]
public Guid SexIdentifier { get; set; }
public ActionResult DropDownSelected(object value)
{
var x = ((Guid)value).ToString();
string xsd = value.ToString();
var abc = ControllerContext.Controller;
if (value == null)
{
//value = string.Empty;
}
if (value.ToString() == Convert.ToString(Guid.Empty) || value.ToString() == string.Empty)
{
return Json(String.Format("0 does not exist."), JsonRequestBehavior.AllowGet);
}
return Json(true, JsonRequestBehavior.AllowGet);
}
If your property is called SexIdentifier then your action must use the same name for its argument:
public ActionResult DropDownSelected(Guid sexIdentifier)
{
...
}
Also if you have a default value of the dropdown you could use a nullable Guid:
public ActionResult DropDownSelected(Guid? sexIdentifier)
{
...
}

Default value is overriding passed in values

I have an action that accepts multiple values to filter from. These values are optional. I set default values. The default values are overriding the values I pass in.
If I pass in:
minAge:40, maxAge:40. Both values are set to 0.
This is the Action on my controller:
[HttpGet]
public ActionResult DataTableUpdate(string firstName = "", string lastName = "", int minAge = 0, int maxAge = 0, string currentState = "")
{
List<DataMember> data = DataMemberCache.GetMembers().FindAll(d => (d.FirstName.Contains(firstName)) && (d.LastName.Contains(lastName)) && (d.Age < minAge) && (d.Age > maxAge) && (d.CurrentState.Contains(currentState)));
return PartialView("_DataTable", data);
}
See here: Optional parameters in the MVC framework are handled by using nullable-type arguments for controller action methods.
For example, if a method can take a date as part of the query string but you want to the default to be today's date if the query string parameter is missing, you can use code like that in the following example:
public ActionResult ShowArticles(DateTime? date)
{
if(!date.HasValue)
{
date = DateTime.Now;
}
// ...
}
So, your code must change to this one:
[HttpGet]
public ActionResult DataTableUpdate(string firstName, string lastName, int? minAge, int? maxAge, string currentState)
{
firstName = firstName ?? "";
lastName = lastName ?? "";
minAge = minAge ?? 0;
maxAge = maxAge ?? 0;
currentState = currentState ?? "";
List<DataMember> data = DataMemberCache.GetMembers().FindAll(d => (d.FirstName.Contains(firstName)) && (d.LastName.Contains(lastName)) && (d.Age < minAge) && (d.Age > maxAge) && (d.CurrentState.Contains(currentState)));
return PartialView("_DataTable", data);
}

modify a TT template to add required html element

I am trying to create a t4 template to help speed up my Create Form template.
Is it possible to add extra html depending if a model's property is required?
e.g.
[Required]
[Display(Name = "Contact Email Address:")]
public string ContactEmailAddress { get; set; }
Now in my tt file do something like
foreach (ModelProperty property in GetModelProperties(mvcHost.ViewDataType)) {
if (!property.IsPrimaryKey && !property.IsReadOnly) {
#>
<div>
#Html.LabelFor(model => model.<#= property.Name #>)
#Html.EditorFor(model => model.<#= property.Name #>)
#Html.ValidationMessageFor(model => model.<#= property.Name #>)
if(this.Required==true){<span class="required-field"></span>}
</div>
<#
}
Or is this not possible?
1,Open this file:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Web\Mvc\Scaffolding\Templates\MvcViewWithContextScaffolder\ModelPropertyFunctions.include.t4
2, Add some property to ModelProperty
class ModelProperty {
public string Name { get; set; }
public string AssociationName { get; set; }
public string ValueExpression { get; set; }
public string ModelValueExpression { get; set; }
public string ItemValueExpression { get; set; }
public EnvDTE.CodeTypeRef Type { get; set; }
public bool IsPrimaryKey { get; set; }
public bool IsForeignKey { get; set; }//
public bool IsReadOnly { get; set; }//
public bool IsRequired{ get; set;}//Here is your customer Property
public bool Scaffold { get; set; }
}
3, Add an method out under this class
bool IsRequired(EnvDTE.CodeProperty propertyType)
{
foreach (EnvDTE.CodeAttribute attribute in propertyType.Attributes)
{
if (String.Equals(attribute.FullName, "System.ComponentModel.DataAnnotations.RequiredAttribute", StringComparison.Ordinal))
{
return true;
}
}
return false;
}
4,Go to the bottom of this file to modify the method GetEligibleProperties:
List<ModelProperty> GetEligibleProperties(EnvDTE.CodeType typeInfo) {
List<ModelProperty> results = new List<ModelProperty>();
if (typeInfo != null) {
foreach (var prop in typeInfo.GetPublicMembers().OfType<EnvDTE.CodeProperty>()) {
if (prop.HasPublicGetter() && !prop.IsIndexerProperty() && IsBindableType(prop.Type)) {
string valueExpression = GetValueExpressionSuffix(prop);
results.Add(new ModelProperty {
Name = prop.Name,
AssociationName = GetAssociationName(prop),
ValueExpression = valueExpression,
ModelValueExpression = "Model." + valueExpression,
ItemValueExpression = "item." + valueExpression,
Type = prop.Type,
IsPrimaryKey = IsPrimaryKey(prop),
IsForeignKey = IsForeignKey(prop),
IsRequired=IsRequired(prop),//Here is your customer property.
IsReadOnly = !prop.HasPublicSetter(),
Scaffold = Scaffold(prop)
});
}
}
}
return results;
}
5, go to the file
C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Web\Mvc\Scaffolding\Templates\MvcViewWithContextScaffolder\Edit.cs.t4
Add the following check before your ValidationMessageFor
#Html.ValidationMessageFor(model => model.<#= property.Name #>):
Codes like this:
<#
if (property.IsRequired) {
#>
*<!--your html code-->
<#
}
#>
This would be possible but would take more work than what you have here. You could add a Required property to ModelProperty and then set it by looking for the required attribute on the property when getting the model properties. You can take a look at the code that determines whether or not a property is a primary key in the .tt templates for an example.
If someone still searching for a solution...
I'm using the MetadataType attibute to define the property attributes like Required or DisplayName in a seperate class.
Sample:
[MetadataType(typeof(personMetaData))]
public partial class Person
{
}
public class personMetaData
{
[DisplayName("Surname")]
[Required]
public object Name { get; set; }
}
If you want to access these attributes in the t4-template you have to extend the ModelProperty class and creator in the template-file.
Put the following code at the bottom of your template (e.g. List.tt). You have to replace the existing code.
<#+
// Describes the information about a property on the model
public class ModelProperty
{
public string Name { get; set; }
public string ValueExpression { get; set; }
public Type UnderlyingType { get; set; }
public bool IsPrimaryKey { get; set; }
public bool IsReadOnly { get; set; }
public string DisplayName { get; set; }
}
// Change this list to include any non-primitive types you think should be eligible for display/edit
private static Type[] bindableNonPrimitiveTypes = new[]
{
typeof (string),
typeof (decimal),
typeof (Guid),
typeof (DateTime),
typeof (DateTimeOffset),
typeof (TimeSpan),
};
// Call this to get the list of properties in the model. Change this to modify or add your
// own default formatting for display values.
public List<ModelProperty> GetModelProperties(Type type)
{
List<ModelProperty> results = GetEligibleProperties(type);
foreach (ModelProperty prop in results)
{
if (prop.UnderlyingType == typeof (double) || prop.UnderlyingType == typeof (decimal))
{
prop.ValueExpression = "String.Format(\"{0:F}\", " + prop.ValueExpression + ")";
}
else if (prop.UnderlyingType == typeof (DateTime))
{
prop.ValueExpression = "String.Format(\"{0:g}\", " + prop.ValueExpression + ")";
}
}
return results;
}
// Call this to determine if the property represents a primary key. Change the
// code to change the definition of primary key.
private bool IsPrimaryKey(PropertyInfo property)
{
if (string.Equals(property.Name, "id", StringComparison.OrdinalIgnoreCase))
{
// EF Code First convention
return true;
}
if (string.Equals(property.Name, property.DeclaringType.Name + "id", StringComparison.OrdinalIgnoreCase))
{
// EF Code First convention
return true;
}
foreach (object attribute in property.GetCustomAttributes(true))
{
if (attribute is KeyAttribute)
{
// WCF RIA Services and EF Code First explicit
return true;
}
var edmScalar = attribute as EdmScalarPropertyAttribute;
if (edmScalar != null && edmScalar.EntityKeyProperty)
{
// EF traditional
return true;
}
/* var column = attribute as ColumnAttribute;
if (column != null && column.IsPrimaryKey)
{
// LINQ to SQL
return true;
}*/
}
return false;
}
// This will return the primary key property name, if and only if there is exactly
// one primary key. Returns null if there is no PK, or the PK is composite.
private string GetPrimaryKeyName(Type type)
{
IEnumerable<string> pkNames = GetPrimaryKeyNames(type);
return pkNames.Count() == 1 ? pkNames.First() : null;
}
// This will return all the primary key names. Will return an empty list if there are none.
private IEnumerable<string> GetPrimaryKeyNames(Type type)
{
return GetEligibleProperties(type).Where(mp => mp.IsPrimaryKey).Select(mp => mp.Name);
}
// Helper
private List<ModelProperty> GetEligibleProperties(Type type)
{
List<ModelProperty> results = new List<ModelProperty>();
foreach (PropertyInfo prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
Type underlyingType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
if (prop.GetGetMethod() != null && prop.GetIndexParameters().Length == 0 &&
IsBindableType(underlyingType))
{
var displayName = prop.Name;
// Search in Metadata
var metadata = type.GetCustomAttributes(typeof(MetadataTypeAttribute), true).OfType<MetadataTypeAttribute>().ToArray().FirstOrDefault();
if (metadata != null)
{
var metaPropery = metadata.MetadataClassType.GetProperty(prop.Name);
if (metaPropery != null)
{
displayName = ((DisplayNameAttribute)metaPropery.GetCustomAttributes(typeof (DisplayNameAttribute), true).First()).DisplayName;
}
}
results.Add(new ModelProperty
{
Name = prop.Name,
ValueExpression = "Model." + prop.Name,
UnderlyingType = underlyingType,
IsPrimaryKey = IsPrimaryKey(prop),
IsReadOnly = prop.GetSetMethod() == null,
DisplayName = displayName
});
}
}
return results;
}
// Helper
private bool IsBindableType(Type type)
{
return type.IsPrimitive || bindableNonPrimitiveTypes.Contains(type);
}
#>
Now you can access these attributes like this:
<#
List<ModelProperty> properties = GetModelProperties(mvcHost.ViewDataType);
foreach (ModelProperty property in properties) {
if (!property.IsPrimaryKey) {
#>
<th>
<#= property.DisplayName #><#= property.AllowEmptyStrings ? "*" : "" #>
</th>
<#
}
}
#>
T4 templates have changed with MVC5. To accomplish this in MVC5, I've written a tutorial here: https://johniekarr.wordpress.com/2015/05/16/mvc-5-t4-templates-and-view-model-property-attributes/

Resources