简体   繁体   中英

ASP.NET MVC Bad Practices: Optional Submodel With Required Property

There are loads of resources for this on Google but I can't fully understand what I need to do in my scenario:

I have this class:

public class CompanyLanguage : EntityBase
{
    public int CompanyId { get; set; }
    public int LanguageId { get; set; }
    public bool IsDefault { get; set; }


    public virtual Company Company { get; set; }
    public virtual Language Language { get; set; }
}

Language is defined as:

public class Language:EntityBase
{
    [Required]
    [DisplayName("Language Code")]
    public string LanguageCode { get; set; }

    [Required]
    [MaxLength(2, ErrorMessage ="2 characters maximum")]
    [DisplayName("2 Char Language Code")]
    public string LanguageCode2Char { get; set; }

    [Required]
    [DisplayName("Language Name")]
    public string LanguageName { get; set; }

    public virtual List<LabelLanguage> LabelLanguages { get; set; }
}

Running a Fortify Scan returns the issue below as a high priority:

(ASP.NET MVC Bad Practices: Optional Submodel With Required Property)

We can't run the fortify scan - it's being run by someone else, so I need to get the changes right so it doesn't come straight back.

All the resources I've looked at suggest that underposting attacks could be made - ie a null Language , even though Language has some required properties.

For me, this is a valid scenario - the required properties of Language are only required if Language isn't null.

So what am I supposed to do to resolve this? Do I make public int LanguageId { get; set; } public int LanguageId { get; set; } public int LanguageId { get; set; } required, or public virtual Language Language { get; set; } public virtual Language Language { get; set; } public virtual Language Language { get; set; } or both?

Or am I completely wrong an I have to do something else? As I say I can't test these as the software has to be sent away for the test or I'd be trying all sorts out.

To summarize our discussion from comments.

  1. Create a view model which models only the information that is needed to satisfy the corresponding view.
  2. populate view models in your controller action from your domain ef models
  3. either project directly into view models using linq queries or Automapper.

Example view model for your question

public class CompanyLanguageEditViewModel
{
    [DisplayName("Company")]
    [Required]
    public int CompanyId { get; set; }

    [DisplayName("Language")]
    [Required]
    public int LanguageId { get; set; }
    public bool IsDefault { get; set; }

    public IEnumerable<SelectListItem> Companies{ get; set; }
    public IEnumerable<SelectListItem> Languages { get; set; }
}

And in your view you can then use

@Html.DropDownListFor(x => x.CompanyId, Model.Companies);

and your label will be Country and you are only going to POST back what you need

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM