Question

I am using asp.net MVC3 with Enitity frameword. both are communicating via WCF web service.

the problem is that , at the server side DB developers don't want to set the [Required]/[Range] attributes to property in there Entity classes. But i want to validate the field at my end in mvc3 application. where as i added the WCF webservice reference. which generated proxy.

I don't want to use Jquery/javascript as per client policy. so i need to do it at my controller/Model level. how to manage this ? some how i need to add the required attribute to the properties of each entity dynamically from mvc 3 aaplication. need right direction to speed up.

Forgot to add: Db developer striclty avoiding to user required. also db not generated in entity and mappings.

Was it helpful?

Solution

You must write a code to validate your entities. Even if developers used those attributes on entities you would not have them on your side because you are accessing the DAL through WCF generated proxy and those attributes are not generated by the tool on your side.

All classes generated by add service reference should be partial so you can add your custom partial part and implement validation (by implementing IValidatableObject interface).

OTHER TIPS

I agree with Ladislav Mrnka but if you are not able to change the properties of the entity class, you have to source it out:

[MetadataType(typeof(YourOwnClassForValidation))]
public partial class ClassOfYourDbDeveloper
{
    // db developer doesn't allow you to change this
    public string Title { get; set; }
}

public class YourOwnClassForValidation
{
    // here you can use your data annotations
    // important to use object
    [Required]
    public object Title { get; set; }
}

It's just for setting the properties, read more about that here at the bottom: http://www.asp.net/mvc/tutorials/validation-with-the-data-annotation-validators-cs

You can register a class to be used as metadata/validation provider for your models.

Having your entity, that cannot be changed:

public class MyModel 
{
    public int IntProperty { get; set; }

    public DateTime DateProperty { get; set; }
}

You can have it's metadata on MVC side, that you can validate and provide metadata as if it is the original class:

[ValidationAttribute(...)]
[ValidationAttribute(...)]
public class MyModelValidator
{
    [Required]
    [Display("My Integer")]
    public int IntProperty { get; set; }

    [DataType(DataType.DateTime)]
    public DateTime DateProperty { get; set; }
}

Finally you just have to attach the Metadata/Validator class to the correspondent base class, for example on Global.asax:

protected void Application_Start()
{
    AssociatedMetadataTypeTypeDescriptionProvider typeDescriptionProvider;

    typeDescriptionProvider = new AssociatedMetadataTypeTypeDescriptionProvider(
            typeof(MyModel),
            typeof(MyModelValidator));

    TypeDescriptor.AddProviderTransparent(typeDescriptionProvider, typeof(MyModel));

    // register other metadata classes
}

You can do this for every Entity you want.

Use view models. One of their intended purposes is to abstract away model (as M in MVC) objects from the views.

Put validation attributes in your view models and use a mapper (like automapper) to copy information to/from the db entities.

Use ModelState.IsValid in your controller actions to check if the view models are valid.

My POST action methods usually look someting liek this:

[HttpPost]
public virtual ActionResult Edit(EditModel model)
{
    if (!ModelState.IsValid)
        return View(model);

    try
    {
        // fetch db entity
        var template = _templateService.Get(model.Id);

        // copy info from view model to db entity
        Mapper.Map(model, template);

        // save db entity
        templateService.Save(template);

        return RedirectToAction("Details", new { id = template.Id });
    }
    catch (Exception err)
    {
        Logger.Error("Failed to save template", err);
        ModelState.AddModelError("", err);
        return View(model);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top