MVC2: Can't convert String to ExtensionDataObject (without knowing I wanted to) - asp.net-mvc

I'm getting the following InvalidOperationException:
The parameter conversion from type 'System.String' to type 'System.Runtime.Serialization.ExtensionDataObject' failed because no type converter can convert between these types.
In a Post action on my ASP.Net MVC2 page, but I'm really not sure what it's referring to. I'm using data annotation validation:
public class FamilyPersonMetadata
{
[Required(ErrorMessage = "Name Required")]
public String Name;
[Required(ErrorMessage = "Date of Birth required")]
[DateTime(ErrorMessage = "Invalid Date")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:d")]
public DateTime DateOfBirth;
}
[MetadataType(typeof(FamilyPersonMetadata))]
public partial class FamilyPerson
{
}
And my view inhertis from a ViewPage with a subtype of FamilyPerson. I just create controls with names matching those of FamilyPerson and then submit the form, but for some reason my ModelState is invalid and the above error is apparently the reason. I'm quite perplexed as to the nature of the error. Similar code is working for other views and actions.
Could someone point me in the direction of things to look at that might cause this?

Regarding [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:d")]
"{0:d" should be "{0:d}"

Here's an actual explanation of the problem, and how to solve it: http://www.shawson.co.uk/codeblog/mvc-strongly-typed-view-returns-a-null-model-on-post-back/comment-page-1/
Short summary: Don't give your view parameters the same names as model fields, unless they represent the same value (and have the same type).

It seems to have gone away on its own. Weird.

This may help someone:
I had this exception being thrown because i had mulitiple forms in my view.
However one of the forms did not explicitly set the 'action' attribute. That is, i was using this constructor:
#using (Html.BeginForm())
Instead of this one:
#using (Html.BeginForm("ACTION_METHOD", "CONTROLLER", FormMethod.Post, null))
This would result in the incorrect parameters being posted with the Form. Spoecifically, the business model object was being included on the Form when it shouldn't be. In turn, .Net was then trying to convert a System.String to a business model object when it shouldn't be attempting such a conversion.
The solution is to use the later overloaded method and ensure that the correct 'action' attribute is being set for your Form upon postback.
FYI: To inspect the 'action' attribute of your Form, use FireBug and inspect the HTML, find the Form element and the 'action' attribute will be there with all the parameters that will be posted back to the serber when that Form is submitted.

Related

Passing TimeSpan in Html.EditorFor()

I'm getting a very strange exception.
I have a model with a TimeSpan property and try to create a view.
public class Clock {
[DataType(DataType.Time)]
[DisplayFormat(DataFormatString = #"{0:hh\:mm}", ApplyFormatInEditMode = true)]
public TimeSpan Time {get;set;}
}
#Html.EditorFor(model => model.Time)
That is what I get
[InvalidOperationException: The model item passed into the dictionary is of type 'System.TimeSpan', but this dictionary requires a model item of type 'System.String'.]
System.Web.Mvc.ViewDataDictionary`1.SetModel(Object value) +321071
System.Web.Mvc.ViewDataDictionary..ctor(ViewDataDictionary dictionary) +377
System.Web.Mvc.WebViewPage`1.SetViewData(ViewDataDictionary viewData) +48
I've used this technique in another project and it works, but in my current project it fails and I don't know my. Maybe I've missed something or something is disabled.
When using #Html.EditorFor(), MVC first looks to see if it can find a template using the default convention (or one you may have defined in a custom ViewEngine).
If it can't find one -- and in your case, you didn't have one defined -- then it uses built in templates. In the case of TimeSpan, it was trying to use a template for a String type, which resulted in the exception you saw.
You will need to explicitly define a TimeSpan.cshtml template, typed with #model TimeSpan.
My answer is not so much an answer as a workaround, since I'm not sure of the reason for the exception, but for me it works if I do a clean checkout from TFS.

How to validate that user enters string in textbox in asp mvc4

How to validate that user enters string in textbox in asp mvc4?
What to write in required tag?
[required]
Use the [RegularExpression] attribute if you want to limit the user to only typing in alphabetic characters.
More info on MSDN.
Here is a good link to a regular expression that you can use.
This example maybe helps:
public class CustomerMetaData
{
// Require that the Title is not null.
// Use custom validation error.
[Required(ErrorMessage = "Title is required.")]
public object Title;
// Require that the MiddleName is not null.
// Use standard validation error.
[Required()]
public object MiddleName;
}
There are many ways to do it
1) By using plain Javascript or JQuery to check if it has value before submiting the page
2) On controller method check if it has value
3) If you a using EF and your view binded to a model add attribute called [Required]to the property of that model.
What do you actually want to do?
Make sure that the object the server receives has correct data in it? Then you should use data attributes on your C# model. However what do you mean by "enters string"? If the user simply needs to enter any string, then [Required] works - this just means that there has to be some value entered. Do you only want to allow a specific set of characters, like the English alphabet? Then you need to use a RegularExpression attribute.
If you further specify what you actually want to do I am sure we can help you more.

asp.net mvc 3 validation on data type

I am trying to realize valition on data type. I have used DataAnnotations, but for data type it's not showing customized message
for example when I' am trying enter string data into int typed field. How I can customize messages in this case?
If I had to guess, you sound like you want a custom message to display when validating one or more fields in your model. You can subclass the DataAnnotations.ValidationAttribute class and override the IsValid(object) method and finally setting a custom ErrorMessage value (where ErrorMessage already belongs to the ValidationAttribute class)
public class SuperDuperValidator : ValidationAttribute
{
public override bool IsValid(object value)
{
bool valid = false;
// do your validation logic here
return valid;
}
}
Finally, decorate your model property with the attribute
public class MyClass
{
[SuperDuperValidator(ErrorMessage="Something is wrong with MyInt")]
public int MyInt { get; set; }
}
If you're using out-of-the-box MVC3, this should be all you need to propertly validate a model (though your model will probably differ/have more properties, etc) So, in your [HttpPost] controller action, MVC will automagically bind MyClass and you will be able to use ModelState.IsValid to determine whether or not the posted data is, in fact, valid.
Pavel,
The DataAnnotations DataType attribute does not affect validation. It's used to decide how your input is rendered. In such a case, David's solution above works.
However, if you want to use only the built-in validation attributes, you probably need to use the Range attribute like this:
[Range(0, 10, ErrorMessage="Please enter a number between 0 and 10")]
public int MyInt { get ; set ;}
(Of course, you should really be using the ErrorMessageResourceName/Type parameters and extract out hard-coded error message strings into resx files.)
Make sure to let MVC know where to render your error message:
<%= Html.ValidationMessageFor(m => m.MyInt) %>
Or you can just use EditorForModel and it will set it up correctly.
I don't think this has been answered because I have the same issue.
If you have a Model with a property of type int and the user types in a string of "asd" then the MVC3 framework binding/validation steps in and results in your view displaying "The value 'asd' is not valid for <model property name or DisplayName here>".
To me the poster is asking can this message that the MVC3 framework is outputting be customized?
I'd like to know too. Whilst the message is not too bad if you label your field something that easily indicates an number is expected you might still want to include additional reasons so it says something like:
"The value 'asd' is not valid for <fieldname>; must be a positive whole number."
So that the user is not entering value after value and getting different error messages each time.

MVC2: Using DataAnnotations to validate DataType

I am using Entity Framework + SQL Server DB and am using partial classes with DataAnnotations to validate data. For things like Required and Range, this works fine, but I am unable to get the DataType validators to work.
Here is an example of the (custom) annotation:
[DataTypeWholeNumberAttribute(ErrorMessage = "Zip must be a whole number")]
public object Zip{ get; set; }
...and the Controller Code...
[HttpPost]
public ActionResult Edit(NamedInsuredViewModel viewModel)
{
try
{ //breakpoint here (opening squiggly bracket) shows .Zip is already null
if (ModelState.IsValid)
...save, etc...
}
}
And I know what's happening: The DataType of Zip in the database is int, so the default validation is catching that and applying the generic error message "the value [x] is not valid for [FieldName]" before my validator can get to it (to prove this, I also added the same validator to a string field, and it works just fine). What I don't know is, how can I get around that (and no, I can't change the DB to use strings for everything)?
Some suggestions have been offered in this post (http://forums.asp.net/p/1608322/4162819.aspx#4162819), but so far nothing has helped.
Thanks in advance.
PS - is there really no way to validate a primitive DataType without creating a custom Attribute?
I think the error is to pass something called "viewModel" to a Edit Action.
ViewModel is intended for pass data to a view to render it.
When you submit a form the data have to be mapped to a entity not to a viewModel.
[HttpPost]
public ActionResult Edit(YourEntity entity)
{
try
{ //breakpoint here (opening squiggly bracket) shows .Zip is already null
if (ModelState.IsValid)
...save, etc...
}
}
Apply your custom validator to the class. Then pass in your class instance as the parameter for your validator instead of as a string. Then you can perform the validation on the appropriate property regardless of type.

Server-side validation of a REQUIRED String Property in MVC2 Entity Framework 4 does not work

I'm trying to get server-side validation of an Entity Framework String Property to work. Other server-side validation such as data type validation and required dateTime and numeric EF properties are working.
This in VS 2010, .Net 4.0, MVC2 + Cloud, ADO.Net Entity Framework.
The String Property I am having issues with is mapped to a SQL 2008, Varchar(50) non-nullable column.
When I try to post to my Create action with an empty string for this Property, I get the follwing error.
Exception Details: System.Data.ConstraintException: This property cannot be set to a null value.
When I post to the action with a blank space, I successfully get a required field validation message.
I have tried using Data Annotations and ClientSideValidation but there seems to be issues with ClientSideValidation working on partial views and jquery dialogs.
Here is the orginal autogenerated code from the entity framework.
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public global::System.String GradeTypeName
{
get
{
return GradeTypeName;
}
set
{
OnGradeTypeNameChanging(value);
ReportPropertyChanging("GradeTypeName");
_GradeTypeName = StructuralObject.SetValidValue(value, false);
ReportPropertyChanged("GradeTypeName");
OnGradeTypeNameChanged();
}
}
Depending on the signature of the Action method (CREATE or EDIT), the exception can occur before stepping into the method or within the method when UpdateModel() is called. The inner exception is at the line below from the model.designer.cs file.
_GradeTypeName = StructuralObject.SetValidValue(value, false);
I have been able to reproduce this on a simple mvc2 web application.
i was having the same problem for a while. I have found a piece of explanation here: http://mvcmusicstore.codeplex.com/workitem/6604 . To put it in a nutshell, the exception "System.Data.ConstraintException: This property cannot be set to a null value" is thrown by Entity's Property Validation. This validation is performed when your mvc application tries to bind the form field to the corresponding entity property( it's called PreBinding Validation, and it occurs when submitting the form). As the field is empty( therefore convert to null), the binder tries to bind a null value to the property, which violates the Non-Null constraint on your entity's property.
But if you post with a blank field ( that is different from empty, therefore null) Entity validation passes( as the property is not set to a null value anymore), and then your see the message from the "Required" annotation validation, that is performed after the prebinding (it's PostBinding Validation).
A workaround is to use the annotation [DisplayFormat(ConvertEmptyStringToNull = false)] that tells to the binder not to convert an empty string to null.
[Required]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public string YourStringProperty { get; set;}
Hope, this helps!
This was very helpful. I'm using MVC3 and entity framework. I was passing my entities directly into the controller, but got the same error when the form was blank. With entity framework you can do data validation by editing the auto-generated code, but creating a separate partial class of the entity worked better for me.
[MetadataType(typeof(TestEntityValidation))]
public partial class TestEntity{
}
public class TestEntityValidation{
[Required]
[DisplayFormat(ConvertEmptyStringToNull = false)]
public String name { get;set}
}
Sometimes in database first approach in EF, may you update your column from not null to can be null using SQL query and use 'Update Model From Database...' (in EDMX right click) then maybe property of that entity not updated properly and so if you have some null data in that column ,in mapping ,violation occurs and this error shown.
To fix this; You can check the Nullable in Properties of that property of entity that you updated it.

Resources