"[Required]" Data Annotation Not Enforced on POST Methods - asp.net-web-api

I had the idea to use Data Annotations in order to validate ModelState. This works wonderfully. The problem I am having is that the [Required] Data Annotation is being enforced on [Key] fields on post. Our data layer takes care of setting Id's and we don't want anyone consuming the service to have to worry about Id's. Is there a way around this in WebApi2?
I have looked at this question, and removing the Id field from ModelState in the POST method before checking for valid ModelState would work. The issue with that is that we use a filter for ModelState.
EDIT:
After doing some more research, what I am essentially wanting to do is what the [Bind] attribute does in MVC. After some research, it does not look like this is a feature that has yet been implemented in WebApi. If anyone has any ideas, feel free to post them.

What you can do is to replace your entity with a data transfer object, which is identical to your original entity without the ID field. For example,
The original entity may look like this
public class User
{
[Required]
public Guid UserId { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public string Username { get; set; }
public string Email { get; set; }
}
and the DTO may look like this
public class UserDto
{
public string Firstname { get; set; }
public string Lastname { get; set; }
public string Username { get; set; }
public string Email { get; set; }
}
Hope this helps.

Related

"Not Found" Exception when trying to call UpdateAsync or InsertAsync

I'm creating a pretty basic Azure Mobile App based on the TodoItem example, and i'm running into a weird issue. I can connect to the table controller and call ToEnumerableAsync (GET) without issue, but as soon as I call UpdateAsync or InsertAsync, I get a 404 (Not Found) response. I tried recreating the table controller, disabling authentication etc. to no avail.
Log stream on Azure sees the PATCH message and returns the 404. Not terribly helpful...
my DTO looks like this:
public class Patient : EntityData
{
public string PersonalHealthNumber{ get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime? DateOfBirth { get; set; }
}
and my client-side patient looks like this:
public class Patient
{
public string Id { get; set; }
public string PersonalHeathNumber { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public DateTime? DateOfBirth { get; set; }
[Version]
public string Version { get; set; }
}
Try derive your client model from that TableData base class and remove the 2 properties Id and Version from your client model because they are in the base class

Store same fields twice during serialization

I have a very simple POCO like:
public class Sample()
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
I'd like to use a custom Attribute like [AdditionalLowerField] as below
public class Sample()
{
public ObjectId Id { get; set; }
public string FirstName { get; set; }
[AdditionalLowerField]
public string LastName { get; set; }
}
so that in MongoDB LastName field is serialized twice, with an additional lowered case field like this:
{
_id : ......,
FirstName : "Mario",
LastName : "Special Case",
LastNameLower : "special case"
}
I'm trying to figure this out from doc http://docs.mongodb.org/ecosystem/tutorial/serialize-documents-with-the-csharp-driver/#write-a-custom-attribute but it's not so complete and I don't find good examples for this scenario.
Update: I know that an additional read-only Property can be used together with a [BsonElement] attribute to store its value in MongoDB during serialization and avoid to get it back during deserialization like described in opt-in paragraph:
[BsonElement]
public string LastNameLower
{
get { return LastName.ToLowerInvariant(); }
}
But I'd like to avoid creation of additional properties if possible.
Does anybody have experience on this scenario?
Thanks

Automapper concern - what if I remove property from view, but not viewmodel?

I've just started using AutoMapper in an MVC ASP.NET project to map my domain models to my view models. eg.
public class PersonModel
{
public string FirstName { get; set; }
public string NickName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }
}
public class PersonViewModel
{
public string FirstName { get; set; }
public string NickName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }
}
// Somewhere...
Mapper.CreateMap<PersonModel, PersonViewModel>();
Mapper.CreateMap<PersonViewModel, PersonModel>();
Having adopted this pattern, I'm concerned the following scenario happening in future:
1) Developer A creates Person View which shows editors for all 4x properties
2) Developer B later removes "Nickname" editor from the Person View, but leaves in PersonViewModel
3) Because the Nickname value is never preserved in the View, hence submitted on Save, Automapper starts mapping a null value for "Nickname" from PersonViewModel -> PersonModel and overwriting data without any run-time or compile-time warning.
Is this a legitimate risk, have you run into it, and how did you deal with it?
You can mitigate against such risks by having server side validation and automated end to end testing.
So in your example one of the tests would be that 'when saving a person the nickname should contain a value'.

MVC3 View Model versus Entity Framework Model

Not sure how to explain this, but here goes...
I've built a code first data model using EF 4.3. One of classes, "Address" contains typical address data, street, city, state, etc. Other classes in the model contain instances of the "Address" class.
The problem. The data will be gathered/presented using different views, some of which will require the address fields, others that will not.
I can build different view models, each having the necessary validation attributes, and copy the data back and forth between data model and view model but that seems wrong.
What am I missing? There has to be a smarter way to do this.
Thanks for your help,
Jimmy
First read these questions and their answers:
MVC: Data Models and View Models
Why Two Classes, View Model and Domain Model?
also this article could help:
ASP.NET MVC View Model Patterns
In conclusion, I think in most scenarios it's helpful to have a chubby domain model (DM) but light weight presentation models (PM) related to it. So when we want to edit only a small chunk of that fat DM, one of our PMs will raise its hand.
Imagine this class in DM:
namespace DomainModels
{
public class Person
{
public int ID { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public DateTime? DoB { get; set; }
public MyAddressDM Address { get; set; }
public string Phone { get; set; }
public IEnumerable<MyCarModel> Cars { get; set; }
//etc.
}
}
Now imagine that in one view we need to edit only Address and Phone. A light weight PM could be like:
namesapce PresentationModels
{
public PersonAddressPhone
{
public int ID { get; set;}
public string FullName { get; set;}
public string AddressSteet { get; set; }
public string AddressCity { get; set; }
public string AddressState { get; set; }
public string AddressZipCode { get; set; }
public string Phone { get; set; }
}
}
and in another view we need to add/remove cars for a person:
namesapce PresentationModels
{
public PersonCars
{
public int ID { get; set;}
public string FullName { get; set;}
public IEnumerable<PMCar> Cars { get; set;}
}
}
Mapping between DO and PM is the golden piece of this puzzle. Be sure to take a look at AutoMapper.

ASP.NET MVC 3 Login page as database

I want to make Login page by using LINQ.
Can I use [Authorize] on controller? or How can I make authorization through database?
I want to make custom login page without web site administration tool because it does not provide more details.
Could you help me? I am really beginner MVC 3.
Please give your hands. Thanks.
Here is my Customer table. Can I use this table for authorization?
Thanks
public class Customer
{
[Key] public int customerId { get; set; }
public Boolean admin { get; set; }
public String userName { get; set; }
public String password { get; set; }
public String firstName { get; set; }
public String lastName { get; set; }
public String company { get; set; }
public String address { get; set; }
public String postCode { get; set; }
public String email { get; set; }
public String phone { get; set; }
public String sortCode { get; set; }
public String accountNo { get; set; }
public String cardHolder { get; set; }
public String cardNo { get; set; }
public int securityCode { get; set; }
}
Yes you can use [Authorize] on your controller, or on individual actions to force the user to be authorized in order to use them.
As you say you are new to MVC, I'd suggest that you have a look at the tutorials on the ASP.Net MVC web site. I believe The MVC Music Store example show you how to implement authorization etc.
You can also have a look at the Nerd Dinner project, which is a great way to get started and to have something that is working to play around with and to learn from.

Resources