I'm building an ASP.NET web service.
I've got my code defined as below, but I can't figure out how to the the wsdl to specify the minOccurs of the FirstName and LastName properties. I want those as required, and can not be empty. Is it possible?
[WebMethod()]
public void TestMethod(TestClass Test)
{
...
}
[Serializable]
public class TestClass
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
It turns out that the WSDL is not used to validate incoming XML. It wouldn't matter whether or not you could specify minOccurs - it would not be used to validate the input.
I have posted the detailed answer on another thread with the same problem: How to make a dotnet webservice set minOccurs=“1” on a string value.
However the answer for strings is no.
The only way make minOccurs=1 without nullable=true is to declare a property with no default value (string has a default value of String.Empty) and without a property to check if the value was specified (making an identical property name with "Specified" word appended to it's name).
And you are still limited if John Saunders' answer is true.
It turns out that the WSDL is not used to validate incoming XML. It wouldn't matter whether or not you could specify minOccurs - it would not be used to validate the input.
Strings are reference types and so by definition nullable. If your property was an integer minoccurs would have been 1.
You can force the Serializer not to allow it to be null, by putting.
[XmlElement("name", IsNullable=false)]
above the property.
Edit: I meant reference types instead of value types. Thnx Joren!
Related
My view model has a [Required] non-nullable int property, selected by a DropDownListFor. If the list to choose from is empty, ModelState.IsValid is true.
My model has a Required int property:
public class MyModel
{
[Required]
public int PickedValue { get; set;}
IEnumerable<SelectListItem> Items { get; set; }
}
In my Create view, I render a <select> element:
#Html.DropDownListFor(model => model.PickedValue, model.Items)
And in my controller, if the model.Items list is empty (no elements to choose from), ModelState.IsValid is true:
[HttpPost]
public ActionResult Create( MyModel model )
{
if( ModelState.IsValid )
{
// true, and ModelState.Keys doesn't contain PickedValue because it was never POSTed.
}
//...
}
Now, the problem goes away if:
PickedValue is Nullable (int?), or
if I have an empty item in my <select> - #Html.DropDownListFor(model => model.PickedValue, model.Items, ""), or
if client-side validation is enabled (since the action is never fired).
Is there a way to force ModelState.IsValid to be false if some of MyModel's properties are [Required] but are missing from the POST data? Shouldn't this be the default behavior?
In your case, I think it would probably be better to make PickedValue a nullable int. If there is a chance that your DropDownList has no items, then null should be a possible value for your PickedValue.
Reply to comments
That makes sense but doesn't answer my original question... Is there a
way to force ModelState.IsValid to be false if some of MyModel's
properties are [Required] but are missing from the POST data?
Shouldn't this be the default behavior?
When it comes to ints, doubles, bools, and other primitives that cannot have a null value, when the DefaultModelBinder receives no data for them in the HTTP request, it must still construct a model instance. Therefore, the model gets constructed and the properties are initialized to their default values. In the case if int, this means it will be initialized to zero. Since nothing is received in the HTTP request, this means the int never gets set, hence it will always be zero. Have you tried giving your int a [Range] validator instead of a [Required] validator? This should validate that it is not zero:
[Range(1, int.MaxValue)]
public int PickedValue { get; set; }
I'd like to avoid changing the model because it's already a common
pattern in my code... Plus making a property in the model nullable to
force it not to be null seems counter-intuitive.
Just because it's a common pattern in your code doesn't mean it's correct. I have to reiterate my original answer: If it is possible for your dropdown list to not have any items, then your model should allow null for its selected value.
This is one reason why it's good practice to have separate entity & viewmodel layers. In your domain entities, a relationship might be required. However when a user is first presented with a form to select that relationship, you either have to give them a default or empty selected dropdown item. In this case, the foreign key in the entity might be an int, but the representation in the viewmodel should be a Nullable<int>. For this reason alone I don't think it's counter-intuitive to make something nullable just to make sure it is not null. You make it nullable in the viewmodel so you can give the user a form with a blank value, and require them to fill it in.
in web application, i am trying to declare property, i found in some of blogs that they declare property like this :
public System.Nullable<DateTime> LoginDateTime { get; set; }
what is the meaning of the above property.
This is called an auto-implemented property.
In C# 3.0 and later, auto-implemented properties make
property-declaration more concise when no additional logic is required
in the property accessors. They also enable client code to create
objects. When you declare a property as shown in the following
example, the compiler creates a private, anonymous backing field that
can only be accessed through the property's get and set accessors.
The compiler will transform this code into something like:
private System.Nullable<DateTime> xxx;
public System.Nullable<DateTime> LoginDateTime
{
get
{
return xxx;
}
set
{
xxx = value;
}
}
The "generated" code is then called a property:
A property is a member that provides a flexible mechanism to read,
write, or compute the value of a private field. Properties can be used
as if they are public data members, but they are actually special
methods called accessors. This enables data to be accessed easily and
still helps promote the safety and flexibility of methods.
About System.Nullable<>
Value type cannot have a null value (compared to reference types). The use of System.Nullable<> allows representing the correct range of values for its underlying value type, plus an additional null value.
Another notation to System.Nullable<DateTime> is DateTime?
Nullable Types (C# Programming Guide)
It's declaring a LoginDateTime property that can either contain a value or be null; it's equivalent to this:
public DateTime? LoginDateTime { get; set; }
Read more here: http://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx
What part of it are you confused about?
It happens to be a C# property of type Nullable(T), which is a structure that allows you to make other structures nullable. As in you can set the property to null, Note, you can't set a normal DateTime variable to null.
The property is written with some syntactic sugar called Auto-Implemented properties.
Having the name LoginDateTime it probably stores the Date and Time of when the person logged on.
I have an ASP.NET MVC3 application that uses entities generated from a database. Each entity has also has a separate partial class that uses the MetadataType attribute to associate each entity with a class that is decorated with a number of validation attributes (see below).
[MetadataType(typeof(Drawing.Metadata))]
public partial class Drawing
{
private sealed class Metadata
{
[Required]
[StringLength(50, MinimumLength = 3, ErrorMessage = "Drawing numbers must be between {2} and {1} characters in length.")]
[DisplayName("Drawing number")]
public string Number { get; set; }
[Required]
[StringLength(255, MinimumLength = 3, ErrorMessage = "Drawing titles must be between {2} and {1} characters in length.")]
public string Title { get; set; }
}
}
My controller code looks like this:
[HttpPost]
public ActionResult Create(Drawing drawing)
{
if (ModelState.IsValid)
{
// Save to database here...
return RedirectToAction("Index");
}
else
{
return View(drawing);
}
}
I have used the Visual Studio templates to create the views to add, edit and delete the entities (The designer code has not been altered).
The problem I am having is that when I create an entity, validation only works if I have client side validation enabled. If I turn off the client side validation then ModelState.IsValid always seems to return true and returns me to the index page.
Can anyone provide any suggestions on how to get server side validation working with Entity Framework entities?
UPDATE:
It seems this question is similar to mine. The author of this post seems to have solved the problem but rather unhelpfully omitted to mention how they fixed the problem...
I found another solution to this problem. Because I didn't really want to set my properties to nullable I added the following:
[DisplayFormat(ConvertEmptyStringToNull = false)]
Adding the following annotation to your model property fixes the error as well.
After further investigation it seems that my problem is occuring due to a ConstraintException being thrown by my entity class (which inherits from ObjectContext) when the default model binder tries to bind the user input values (Null in this case) to the entity properties.
I can see 2 possible solutions to this:
Relax the constraints on my database tables (I don't want to do this).
Make the entity fields nullable (use the entity designer set the nullable property to yes)
I have used and tested the second option and can confirm that server side validation now works as expected.
Whilst researching solutions to this problem I have come to the conclusion that the problem is due to my entities inheriting from ObjectContext which is quite a heavy class. I found a lot of tutorials which used a code-first approach. In this case, the entity class will inherit from DbContext which is much more lightweight so I guess this could be considered a third solution to the problem.
I am very confused with properties in asp.net.
I just don't understand why we use properties and when I should use them. Could anybody elaborate a little on this.
public class Customer
{
private int m_id = -1;
public int ID
{
set
{
m_id = value;
}
}
private string m_name = string.Empty;
public string Name
{
set
{
m_name = value;
}
}
public void DisplayCustomerData()
{
Console.WriteLine("ID: {0}, Name: {1}", m_id, m_name);
}
}
Properties provide the opportunity to protect a field in a class by reading and writing to it through the property. In other languages, this is often accomplished by programs implementing specialized getter and setter methods. C# properties enable this type of protection while also letting you access the property just like it was a field.
Another benefit of properties over fields is that you can change their internal implementation over time. With a public field, the underlying data type must always be the same because calling code depends on the field being the same. However, with a property, you can change the implementation. For example, if a customer has an ID that is originally stored as an int, you might have a requirements change that made you perform a validation to ensure that calling code could never set the ID to a negative value. If it was a field, you would never be able to do this, but a property allows you to make such a change without breaking code. Now, lets see how to use properties.
Taken From CSharp-Station
There are a couple of good reasons for it. The first is that you might need to add validation logic in your setter, or actually calculate the value in the getter.
Another reason is something to do with the IL code generated. If you are working on a large project that is spread over multiple assemblies then you can change the code behind your property without the application that uses your assembly having to recompile. This is because the "access point" of the property stays the same while allowing the implementation code behind it to be altered. I first read about this when I was looking into the point of automatic properties as I didnt see the point between those and a normal public variable.
It's easy.
All fields in class MUST be private (or protected). To show fields to another class yyou can use properties or get/set methods. Properties a shorter.
P.S. Don't declare write-only properties. It is worst practices.
Properties are a convenient way to encapsulate your classes' data.
Quoting from MSDN:
A property is a member that provides a flexible mechanism to read,
write, or compute the value of a private field. Properties can be used
as if they are public data members, but they are actually special
methods called accessors. This enables data to be accessed easily and
still helps promote the safety and flexibility of methods.
Let's consider two common scenarios:
1) You want to expose the Name property without making it changeable from outside the class:
private string m_name = string.Empty;
public string Name
{
get
{
return m_name;
}
}
2) You want to perform some checks, or run some code every time the data is accessed or set:
private string m_name = string.Empty;
public string Name
{
get
{
return m_name;
}
set
{
m_name = (String.IsNullOrEmpty(value)) ? "DefaultName" : value;
}
}
see:
http://msdn.microsoft.com/en-us/library/x9fsa0sw.aspx
The most important reason is for validation purpose in setter and manipulation part can be implemented in get part.
For Ex.
Storing weekdays, which should be from 1-7, if we take normal variable and declare it as public, anyone can assign any value.
But in Properties setter you can control and validate.
The next one you can use it for tracking. That means, you can know how many times set and get functions has been called by clients (statistical purpose, may be not useful frequently).
Finally, you can control read only, write only and read/write for the properties according to your requirements.
I have a .Net Web Service function that can accept one string.
That function will then serialize that string to JSON, but I only want to serialize it if it's value is not "".
I found these instructions:
http://msdn.microsoft.com/en-us/library/aa347792.aspx
[DataContract]
public class MyClass
{
[DataMember (EmitDefaultValue=false)]
public string myValue = ""
}
Unfortunatelly I can not hide the myValue from the serialization because "" is not the .Net default value for a string (how dumb is that!)
One of two option ocurred
On the web service have some kind of attribute that sets the "" to null
Have some condition on the class
I would prefer the 1st because it makes the code cleaner but an opinion would be great.
Thanks
You can explicitly set what the default value is (for the purposes of serialization) using the DefaultValueAttribute class:
[DataContract]
public class MyClass
{
[DataMember (EmitDefaultValue=false)]
[DefaultValue("")]
public string myValue = ""
}
I think you have at least a couple of options here. It's extra work but worth it.
You can encapsulate the string in a reference type. Since reference types are null if not present, that lets you know right away if a string was present or not (because the encapsulating reference type would be either non-null or null, if the string is non-empty or not.)
A final option you have is to add an extra complementary variable (perhaps a boolean) that is set on OnDeserializing/OnDeserialized/OnSerializing/OnSerialized and use this to track whether or not something was actually present on the wire. You might, for example, set this complementary variable to true only when you're actually serializing out a non-empty string and similarly