Kir Ginzburg
Kir Ginzburg

Reputation: 47

How to declare an MVC Model and WCF DataContract in one place?

I want to create a 1-page site with knockout.js and MVC 4.

After making some changes the user will click a save button targeting the controller Save action.
Controller side I want to validate the input data.
If the data is valid - I need to call a WCF method.
If the data is not valid - I'll return something to the client side and tell them something like "first name is too long".

It's simple to make something like this:

Code:

public JsonResult Save(SiteModel data)
{
    if (ModelState.IsValid)
    {
        var ui =  WcfUserInfo{FirstName = data.FirstName};
        if(wcfclient.wcfmethod(ui))
            return Json("IsValid");
    }
    return Json("IsNotValid");
}

Is it possible to create a DataContract with DataAnnotations and use this DataContract in the Save method, something like public JsonResult Save(WcfDataContract data)?

I just don't want to create and support two different classes with the same data: one MVC Model and one WCF DataContract.

Thank you.

UPDATE:
this 2 posts resolve my problem.
Send objects with custom attributes via a wcf service
How to make WCF client use the same data types as the WCF service

Upvotes: 2

Views: 2637

Answers (2)

asymptoticFault
asymptoticFault

Reputation: 4529

As a counter point to Anton's answer, which I do believe is a valid argument, I could argue that these two representations encompass exactly the same concern. What is a View Model but a "Data Contract" between the client (the browser) and server (web server). An MVC View Model and a WCF Data Contract both serve to establish a defined set of data that is communicated between two endpoints. To that end, if your WCF Service and Data Contract exist solely to provide the Web Server and client (browser) with your application data than why not use the same representation.

I don't believe there is anything wrong, nor any conflict will arise, from tagging the same class with DataContract and DataMember attributes along with DataAnnotation attributes such as; Required, Range, Display, etc.

[DataContract]
public class SiteModel
{
    [DataMember]
    [Display(Name = "First Name")]
    [Required]
    public string FirstName { get; set; }


    [DataMember]
    [Display(Name = "Last Name")]
    [Required]
    public string LastName { get; set; }
}

To reiterate, I am NOT saying that Anton is wrong. I am simply stating an alternative perspective as I believe the question is one of opinion more so than one that has a right and wrong answer.

Upvotes: 2

Anton
Anton

Reputation: 1386

I know this is NOT what you want to hear, but I cannot stress this enough: Your data contract with the service and your view model (your JSON representation) should not be the same. They are separate concerns, even though it does not feel like that right now.

Given that, what is stopping you from simply replacing the SiteModel with WcfUserInfo if they are the same (i.e. have the same properties)?

PS. If you use AutoMapper, you don't have to do the mapping yourself, AutoMapper will take care of that for you with two lines of code: one to configure the map and one to execute the mapping.

Upvotes: 3

Related Questions