0

I'm fairly new to MVC so please bear this in mind

I have created a viewmodel vmRecurringPack which contains another model Entity amongst other fields in its properties. In the view that I am passing vmRecurringPack, I am only using some of the Entity properties for display purposes (The remaining fields are not required for my view)

My issue arises in that when I POST my view back, the remaining fields of course haven't been bound to the view, and have lost their value. This part is fine in my case, however ModelState.IsValid no longer works because some of those fields are required.

How can I work around this without removing ModelState.IsValid?

(VB.net answers preferable, C# welcome)

EDIT: I have considered a restructure of my viewmodel, which would work, however I'm curious as to what other solutions exist

EDIT: As requested, code. Although I don't see how its required for this particular question... In relation to my question, I want to display the fields for vmRecurringPack.Entity.Code and vmRecurringPack.Entity.Name but in my form POST the ModelState.IsValid returns false because of the fields marked required in Entity coming through as nothing

vmRecurringPack

Namespace ViewModels
Public Class vmRecurringPack

    Property Entity As Entity
    Property Name As String
    Property Description As String
    Property Status As String

End Class
End Namespace

Entity

Namespace Models
Public Class Entity
    Public Property Id As Integer

    <Required>
    Public Property Name As String

    <Required>
    <StringLength(5)>
    Public Property Code As String

    <Required>
    <StringLength(7)>
    Public Property Abbrv As String
    Public Property Status As Boolean

    <DataType(DataType.EmailAddress)>
    Public Property Email As String

    Public Overridable Property EntityType As EntityType
    Public Overridable Property ReportLists As ICollection(Of ReportList) = New HashSet(Of ReportList)
    Public Overridable Property Packages As ICollection(Of Packages) = New HashSet(Of Packages)

End Class
End Namespace
0

3 Answers 3

1

The guidance to use view models is exactly for avoiding such issues as you're experiencing. You've used a view model, here, but you've simply attached your entity class as a property on it. If you don't need everything on the entity, then create a view model for that, as well. In general, it's a bad idea for any entity class to be sent to your view (even if it's via a property on another class). 99 times out of 100, you'll find yourself right back here and needing to switch it out with a view model, anyways.

Sign up to request clarification or add additional context in comments.

3 Comments

I'm happy with most of your answer but could you please elaborate on "In general, it's a bad idea for any entity class to be sent to your view (even if it's via a property on another class)" for my own understanding?
An entity is a class that is tied to a persistence store. In the case of Entity Framework (hence the name), these would be your POCOs. The needs of a view are generally very different than the needs of a database, so the class you use to model a database table (your entity) generally doesn't work well when used for a view. At best, it's shoe-horned in and you have to use things like the Bind attribute on your action parameters. At worst, you have issues like yours here.
Thank you, I will bear this in mind when creating my views in future. I've marked your reply as my accepted answer.
0

Restructuring your view model is the correct way to handle this. Reusing view models is a great thing in case they exactly fit your scenario, but you should not modify validation logic/change application logic only so you could reuse the same view. If you are using couple of Entity properties for display purposes than just add only those properties to your vmRecurringPack object without applying any validation rules to them.

In your case if you insist to use the original view model you may have to implement custom validation logic. For example libraries such as FluentValidation allow you to define complex validation rules.

1 Comment

Thanks Alex, this pretty much confirms what I suspected I was going to have to do.
0

View models are a method of modelling the data being sent to view, so if the data being sent from the browser to the server is different then a common approach is to create a new input model type.

public ActionResult Edit()
{
    return View(new RecurringPackViewModel(...));
}

[HttpPost]
public ActionResult Create(RecurringPackInputModel model)
{
    if (ModelState.IsValid)
    { 
       ... 
    }
}

This way both your view model and input model can have separate requirements.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.