Remote validation not working for guid - asp.net-mvc-3

[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)
{
...
}

Related

Permission Contacts in Xamarin Forms iOS

I met an error display when I tried to access user contact to fetch all contacts: The splash screen hide the permission dialog.
Did anyone meet this error before?
Interface:
public interface IUserContactsService
{
List<PhoneContactInfo> GetAllPhoneContacts(IEnumerable<int> filterIds = null);
}
UserContactService.cs:
[assembly: Dependency(typeof(UserContactService))]
namespace Test.iOS
{
public class PhoneContact
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
public string Name { get => $"{FirstName} {LastName}"; }
}
public class UserContactService : IUserContactsService
{
string phoneNumber(string number)
{
string callNumber = number;
int i = 0;
while (i < callNumber.Length)
{
if (callNumber[i] == ' ' || callNumber[i] == 160 || callNumber[i] == '-')
callNumber = callNumber.Remove(i, 1);
else
i++;
}
return callNumber;
}
public List<PhoneContactInfo> GetAllPhoneContacts(IEnumerable<int> filterIds = null)
{var keysTOFetch = new[] { CNContactKey.GivenName, CNContactKey.FamilyName, CNContactKey.EmailAddresses };
NSError error;
CNContact[] contactList;
var ContainerId = new CNContactStore().DefaultContainerIdentifier;
using (var predicate = CNContact.GetPredicateForContactsInContainer(ContainerId))
using (var store = new CNContactStore())
{
contactList = store.GetUnifiedContacts(predicate, keysTOFetch, out error);
}
var contacts = new List<PhoneContactInfo>();
foreach (var item in contactList)
{
if (null != item && null != item.EmailAddresses)
{
contacts.Add(new PhoneContactInfo
{
contactName = item.GivenName,
contactNumber = item.PhoneNumbers.ToString()
});
}
}
return contacts;
}
}
Here is my solution:
public List<PhoneContactInfo> GetAllPhoneContacts (IEnumerable<int> filterIds = null)
{
// if the app was not authorized then we need to ask permission
if (ABAddressBook.GetAuthorizationStatus() == ABAuthorizationStatus.Authorized)
{
GetContacts();
}
else Console.WriteLine("Error");
}

check collection length - unobtrusive validation - asp.net mvc 3, 4

I've got custom ValidationAttribute with implemented IClientValidatable. It works great using(Html.BeginForm()) but not working using(Ajax.BeginForm()).
Client code:
$(function() {
jQuery.validator.unobtrusive.adapters.addBool('collectionLength');
});
Server code:
/// <summary>
/// Require a minimum length, and optionally a maximum length, for any IEnumerable
/// </summary>
sealed public class CollectionMinimumLengthValidationAttribute : ValidationAttribute, IClientValidatable
{
const string errorMessage = "{0} must contain at least {1} item(s).";
const string errorMessageWithMax = "{0} must contain between {1} and {2} item(s).";
int minLength;
int? maxLength;
public CollectionMinimumLengthValidationAttribute(int min)
{
minLength = min;
maxLength = null;
}
public CollectionMinimumLengthValidationAttribute(int min, int max)
{
minLength = min;
maxLength = max;
}
//Override default FormatErrorMessage Method
public override string FormatErrorMessage(string name)
{
if (maxLength != null)
{
return string.Format(errorMessageWithMax, name, minLength, maxLength.Value);
}
else
{
return string.Format(errorMessage, name, minLength);
}
}
public override bool IsValid(object value)
{
IEnumerable<object> list = value as IEnumerable<object>;
if (list != null && list.Count() >= minLength && (maxLength == null || list.Count() <= maxLength))
{
return true;
}
else
{
return false;
}
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule { ValidationType = " CollectionMinimumLengthValidation", ErrorMessage = FormatErrorMessage("Error") };
rule.ValidationParameters.Add("min", minLength);
rule.ValidationParameters.Add("max", maxLength);
yield return rule;
}
}
CollectionMinimumLengthValidation.js file:
jQuery.validator.addMethod("CollectionMinimumLengthValidation", function (value, element, param) {
debugger;
return false;
});

Silverlight 5 validation issue

i'm trying to validate the data entry of my project using the validation in silverlight
this is the result
http://imageshack.us/photo/my-images/842/immagineleb.png/
as you can see the borders of almost all the textboxes are red, actually, in this case, no one of them should be red! And in all of the tooltips there's the same message.
there are the properties of the object that i use in the data context of the form
private int matricola;
public int Matricola
{
get { return matricola; }
set
{
ValidateRequiredInt("Matricola", value, "Inserire un numero");
matricola = value;
OnNotifyPropertyChanged("Matricola");
}
}
private String cognome;
public String Cognome
{
get { return cognome; }
set
{
ValidateRequiredString("Cognome", value, "Inserire cognome");
cognome = value;
OnNotifyPropertyChanged("Cognome");
}
}
private String nome;
public String Nome
{
get { return nome; }
set
{
ValidateRequiredString("Nome", value, "Inserire nome");
nome = value;
OnNotifyPropertyChanged("Nome");
}
}
private String codiceUtente;
public String CodiceUtente
{
get { return codiceUtente; }
set
{
ValidateRequiredString("CodiceUtente", value, "Inserire codice utente");
codiceUtente = value;
OnNotifyPropertyChanged("CodiceUtente");
}
}
private String password;
public String Password
{
get { return password; }
set
{
ValidateRequiredString("Password", value, "Inserire password");
password = value;
OnNotifyPropertyChanged("Password");
}
}
private int? idOrario;
public int? IdOrario
{
get { return idOrario; }
set { idOrario = value; }
}
private DateTime? dataAssunzione;
public DateTime? DataAssunzione
{
get { return dataAssunzione; }
set
{
if (value != null)
{
ValidateDateTime("DataAssunzione", (DateTime)value, "Immettere una data corretta");
if (((DateTime)value).Year == 1 && ((DateTime)value).Month == 1 && ((DateTime)value).Day == 1)
{
dataAssunzione = null;
}
else
{
dataAssunzione = value;
}
OnNotifyPropertyChanged("DataAssunzione");
}
else
{
dataAssunzione = null;
}
}
}
private DateTime? dataLicenziamento;
public DateTime? DataLicenziamento
{
get { return dataLicenziamento; }
set
{
if (value != null)
{
ValidateDateTime("DataLicenziamento", (DateTime)value, "Immettere una data corretta");
if (((DateTime)value).Year == 1 && ((DateTime)value).Month == 1 && ((DateTime)value).Day == 1)
{
dataLicenziamento = null;
}
else
{
dataLicenziamento = value;
}
OnNotifyPropertyChanged("DataLicenziamento");
}
else
{
dataLicenziamento = null;
}
}
}
private int idGruppoAnag;
public int IdGruppoAnag
{
get { return idGruppoAnag; }
set { idGruppoAnag = value; }
}
private int? costoOrario;
public int? CostoOrario
{
get { return costoOrario; }
set
{
if (value != null)
{
ValidateInt("CostoOrario", (int)value, "Immettere un numero o lasciare il campo vuoto");
if (value == 0 || value == -1)
{
costoOrario = null;
}
else
{
costoOrario = value;
}
OnNotifyPropertyChanged("CostoOrario");
}
else
{
costoOrario = null;
}
}
}
and these are the methods used for the validation
protected bool ValidateRequiredInt(string propName, int value, string errorText)
{
if (DataErrors.ContainsKey(propName))
{
DataErrors[propName].Remove(errorText);
}
if (value == 0 || value == -1)
{
AddError(propName, errorText);
return false;
}
OnErrorsChanged(propName);
return true;
}
//validazione dei campi che richiedono numeri interi nullable
protected bool ValidateInt(string propName, int value, string errorText)
{
if (DataErrors.ContainsKey(propName))
{
DataErrors[propName].Remove(errorText);
}
if (value == 0)
{
AddError(propName, errorText);
return false;
}
OnErrorsChanged(propName);
return true;
}
//validazione dei campi che richiedono stringhe
protected bool ValidateRequiredString(string propName, string value, string errorText)
{
//Clear any existing errors since we're revalidating now
if (DataErrors.ContainsKey(propName))
{
DataErrors[propName].Remove(errorText);
}
if (string.IsNullOrEmpty(value))
{
AddError(propName, errorText);
return false;
}
OnErrorsChanged(propName);
return true;
}
protected bool ValidateDateTime(string propName, DateTime value, string errorText)
{
//Clear any existing errors since we're revalidating now
if (DataErrors.ContainsKey(propName))
{
DataErrors[propName].Remove(errorText);
}
if (value.Year == 9999 && value.Month == 12 && value.Day == 31)
{
AddError(propName, errorText);
return false;
}
OnErrorsChanged(propName);
return true;
}
i'm also using using a dataconverter, in the two "Data" textboxes, and numberconverter, in the matricola and costo textboxes, as locals resources and i can say that they work fine.
i'm missing something?
How about implementing INotifyDataErrorInfo?
In a view-model base class:
public abstract class BaseViewModel : INotifyPropertyChanged, INotifyDataErrorInfo
{
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
#region INotifyDataErrorInfo Members
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public System.Collections.IEnumerable GetErrors(string propertyName)
{
....
}
public System.Collections.IEnumerable GetErrors()
{
...
}
//Plus methods to push errors into an underlying error dictionary used by the above error get methods
}
Expand on this and you will have reusable base class for all view-models.
Validate properties in the appropriate setters. If they fail validation then push an error into the error dictionary keyed by property name. If validation succeeds then remove the validation error (if any) from the the dictionary for the property.
You will need to fire the ErrorsChanged event when you change the dictionary, but this can be achieved by having a protected
SetErrorForProperty(string propName, object error)
method whcih wraps this up.
Clearing an error can be done by passing null to this method and/or by having a separate
ClearErrorsFroProperty(string propName)
method.

ASP.NET MVC3 Physical Location of View from controller

What is the proper way to get the physical location of the View that will be served by a MVC action from inside the action?
I need the last modified time of the file for sending response headers.
The proper way to the get physical location of a view is to map its virtual path. The virtual path can be retrieved from the ViewPath property of BuildManagerCompiledView (RazorView derive from that class, and your IView instances will therefore typically have that property).
Here is an extension method that you can use:
public static class PhysicalViewPathExtension
{
public static string GetPhysicalViewPath(this ControllerBase controller, string viewName = null)
{
if (controller == null)
{
throw new ArgumentNullException("controller");
}
ControllerContext context = controller.ControllerContext;
if (string.IsNullOrEmpty(viewName))
{
viewName = context.RouteData.GetRequiredString("action");
}
var result = ViewEngines.Engines.FindView(context, viewName, null);
BuildManagerCompiledView compiledView = result.View as BuildManagerCompiledView;
if (compiledView != null)
{
string virtualPath = compiledView.ViewPath;
return context.HttpContext.Server.MapPath(virtualPath);
}
else
{
return null;
}
}
}
Use it something like this:
public ActionResult Index()
{
string physicalPath = this.GetPhysicalViewPath();
ViewData["PhysicalPath"] = physicalPath;
return View();
}
or:
public ActionResult MyAction()
{
string physicalPath = this.GetPhysicalViewPath("MyView");
ViewData["PhysicalPath"] = physicalPath;
return View("MyView");
}
That could work:
private DateTime? GetDate(string controller, string viewName)
{
var context = new ControllerContext(Request.RequestContext, this);
context.RouteData.Values["controller"] = controller;
var view = ViewEngines.Engines.FindView(context, viewName, null).View as BuildManagerCompiledView;
var path = view == null ? null : view.ViewPath;
return path == null ? (DateTime?) null : System.IO.File.GetLastWriteTime(path);
}

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