[英]System.MissingMethodException: No parameterless constructor defined for this object. MVC4
[英]System.MissingMethodException: No parameterless constructor defined for this object
我在MVC 2 Web应用程序上间歇性地收到此错误。 我的模型没有无参数的构造函数,它们看起来像这样:
public AddParentModel(ITracktionDataLayer dataLayer, MessagePasser messager, AuthUserHelper authUser)
{
_model = new PersonAddEditModel(messager, dataLayer, authUser, null);
}
我应该注意,我的控制器确实具有无参数的构造函数。 PersonAddEditModel不会直接暴露给MVC。 存在AddParentModel只是为了使MVC绑定更容易。
由于服务器上存在AddParentModel(以及MVC使用的所有其他模型),因此我可以使它们成为无参数的,尽管这会使我的测试方法有些混乱。 关于这个的怪异部分是它间歇地发生。 我希望这样的问题会持续发生,但事实并非如此-我只是每隔一天左右就收到ELMAH向我发送一封电子邮件,并且有一些不幸的用户收到此错误。
我想知道我的选择是什么。 解决该问题的最简单方法是创建一个构造函数重载,该重载将这些参数设置为默认对象(我现在可能只是为了解决当前问题,但这样做实在很脏),但是我希望以正确的方式从人们那里得到输入。 我对MVC比较陌生。 提前致谢!
编辑:我想在完成处理的[HttpPost]方法中添加它,即使我在视图上使用模型进行MVC的编辑,我仍会收到FormCollection并使用它来更新模型,而不是使用MVC直接编辑模型。
/// <summary>
/// Add this person, then go to the next page where more people can be added.
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
[HttpPost]
public ActionResult Index(FormCollection fc, HttpPostedFileWrapper upload) {
Uri requestUri = !Request.Url.ToString().Contains("/127.0.0.1/") ? Request.Url : new Uri("...");
MessagePasser messager = new MessagePasser();
ITracktionDataLayer dataLayer = DataFactory.GetDataLayer();
AuthUserHelper user = AuthUserHelper.AnonymousWebUserFrom(dataLayer, requestUri);
AddParentModel model = new AddParentModel(dataLayer, messager, user);
if (TryUpdateModel(model, fc) && ModelState.IsValid)
{
...
我还意识到,对于某些模型,我无法创建无参数构造函数,因为一些模型在我的数据层,消息传递层和经过身份验证的用户之上和之外都需要几个额外的原语。
我无法使用依赖项注入来解决此问题,因为我需要依赖于构造函数中用户信息的额外参数。 我的构造函数接受IDataLayer,MessagePasser和AuthUserHelper,这对于所有模型都是通用的,但是我还要求提供两个int ID,它们依赖于一些隐藏的输入字段或querystring参数。
因此,我将把模型的属性分为自己的类(模型)和实际的处理过程,例如加载和保存到服务类中。 该模型只是一个属性包,可以具有无参数的构造函数,而将调用服务类以填充和保存数据。 我希望这个答案可以帮助某个人。
因此,在我之前:
public class EditFamilyMemberModel
{
#region Constructor
public EditFamilyMemberModel(ITracktionDataLayer dataLayer, MessagePasser messager, AuthUserHelper authUser, int originalPersonID, int familyMemberID)
{
_dataLayer = dataLayer;
_originalPerson = new PersonAddEditModel(messager, dataLayer, authUser, originalPersonID);
_model = new PersonAddEditModel(messager, dataLayer, authUser, familyMemberID);
_grades = _dataLayer.GetGradesForOrganization(authUser.OrganizationID, _model.Person.Grade, true).ToArray();
}
#endregion
#region Private
ITracktionDataLayer _dataLayer;
PersonAddEditModel _originalPerson;
PersonAddEditModel _model;
IList<Grade> _grades;
#endregion
#region Properties
#region Read Only
public Person Person
{
get { return _model.Person; }
}
public AuthUserHelper AuthUser
{
get { return _model.AuthUser; }
}
public IList<School> Schools
{
get { return _model.Schools; }
}
public IList<ContactType> ContactTypes
{
get { return _model.ContactTypes; }
}
public IList<string> Genders
{
get { return _model.Genders; }
}
public IList<Grade> Grades
{
get { return /*_model.Grades;*/ _grades; }
}
public IList<USState> USStates
{
get { return _model.USStates; }
}
public IList<PersonType> PersonTypes
{
get { return _model.PersonTypes; }
}
public IList<FamilyRole> FamilyRoles
{
get { return _model.FamilyRoles; }
}
#endregion
[Required]
[StringLength(100)]
public string Address
{
get { return _model.Person.Address; }
set { _model.Person.Address = value; }
}
[StringLength(100)]
public string Address2
{
get { return _model.Person.Address2; }
set { _model.Person.Address2 = value; }
}
[Required]
[StringLength(50)]
public string City
{
get { return _model.Person.City; }
set { _model.Person.City = value; }
}
[Required]
[StringLength(50)]
public string State
{
get { return _model.Person.State; }
set { _model.Person.State = value; }
}
[Required]
[StringLength(50)]
public string Zip
{
get { return _model.Person.Zip; }
set { _model.Person.Zip = value; }
}
[DataType(DataType.Date)]
//[Required]
public DateTime? DOB
{
get { return _model.Person.DOB; }
set { _model.Person.DOB = value; }
}
[Required]
public string Gender
{
get { return _model.Person.Gender; }
set { _model.Person.Gender = value; }
}
[Required]
public string FirstName
{
get { return _model.Person.FirstName; }
set { _model.Person.FirstName = value; }
}
[Required]
public string LastName
{
get { return _model.Person.LastName; }
set { _model.Person.LastName = value; }
}
public int? SchoolID
{
get { return _model.Person.SchoolID; }
set { _model.Person.SchoolID = value; }
}
public int? GradeID
{
get { return _model.Person.Grade; }
set { _model.Person.Grade = value; }
}
public string SpecialNeedsDescription
{
get { return _model.Person.SpecialNeedsDescription; }
set { _model.Person.SpecialNeedsDescription = value; }
}
public string SpecialNeedsSummary
{
get { return _model.Person.SpecialNeedsSummary; }
set { _model.Person.SpecialNeedsSummary = value; }
}
public byte[] PictureData
{
get;
set;
}
public string PictureAction
{
get;
set;
}
#region Membership
[Display(Name = "User Name")]
[DisplayName("User Name")]
[UniqueUserName(ErrorMessage = "The user name specified is already in use, please choose another user name.")]
public string Username { get; set; }
[Display(Name = "Password")]
[DisplayName("Enter a password")]
[StringLength(50, MinimumLength = 6, ErrorMessage = "Password must be at least 6 characters long.")]
public string Password { get; set; }
[DisplayName("Confirm Password")]
[StringLength(50, MinimumLength = 6)]
public string PasswordConfirm { get; set; }
#endregion
#region Abstracted Contact Methods
/// <summary>
/// When adding someone, this represents the phone number contact record.
/// </summary>
[Display(Name = "Home Phone Number")]
[DisplayName("Home Phone Number")]
[USPhoneNumber]
//[Required]
public string HomePhoneNumber
{
get { return _model.HomePhone; }
set { _model.HomePhone = value; }
}
/// <summary>
/// When adding someone, this represents the phone number contact record.
/// </summary>
[Display(Name = "Cell Phone Number")]
[DisplayName("Cell Phone Number")]
[USPhoneNumber]
//[Required]
public string CellPhoneNumber
{
get { return _model.PersonalCell; }
set { _model.PersonalCell = value; }
}
/// <summary>
/// When adding someone, this represents the email address contact record.
/// </summary>
[Display(Name = "Email Address")]
[DisplayName("Email Address")]
//[Required] -- Some parents dont have email addresses
[UniqueEmailAddress(ErrorMessage = "The email address was already found in our system, please sign in or use another email.")]
[Email(ErrorMessage = "The email address specified isn't an email address.")]
public string EmailAddress
{
get { return _model.EmailAddress; }
set { _model.EmailAddress = value; }
}
#endregion
#endregion
#region Logic
public void SaveChanges()
{
_model.Person.ChangedTimeStamp = DateTime.Now;
_model.Person.ChangedBy = -1;
// If we have a valid home #, add it
if (!string.IsNullOrWhiteSpace(HomePhoneNumber))
_model.HomePhone = HomePhoneNumber;
// If we have a valid cell #, add it
if (!string.IsNullOrWhiteSpace(CellPhoneNumber))
_model.PersonalCell = CellPhoneNumber;
// If we have a valid email, add it
if (!string.IsNullOrWhiteSpace(EmailAddress))
_model.EmailAddress = EmailAddress;
// Some fields may have 'not applicable'; blank them
_model.Person.SpecialNeedsDescription = _model.Person.SpecialNeedsDescription.NormalizeNotApplicable().NullIfEmptyOrWhitespace();
_model.Person.SpecialNeedsSummary = _model.Person.SpecialNeedsSummary.NormalizeNotApplicable().NullIfEmptyOrWhitespace();
// Names of people should be proper case if they're all entered in lowercase
_model.Person.FirstName = _model.Person.FirstName.NormalizeName();
_model.Person.LastName = _model.Person.LastName.NormalizeName();
if (PictureData != null && (PictureAction == "replace" || (PictureAction ?? "") == ""))
{
// Replace just adds, it does not remove the old picture.
Photo pic = PhotoHandling.GetPhotoEntityFromBytes(PictureData);
pic.ROWGUID = Guid.NewGuid();
pic.OrganizationID = _model.AuthUser.OrganizationID;
pic.CreationTimestamp = DateTime.Now;
pic.Deleted = false;
_model.AddNewPhoto(pic);
_model.Person.Avatar = pic.ROWGUID;
}
else if (PictureAction == "remove" && _model.Person.Avatar.HasValue)
{
var pic = _model.Person.Photos.SingleOrDefault(p => p.ROWGUID == _model.Person.Avatar.Value);
if (pic != null)
{
pic.Deleted = true;
_model.Person.Avatar = null;
}
}
_model.SaveChanges();
}
#endregion
}
现在,我将其分为:
public class EditFamilyMemberModel
{
public EditFamilyMemberModel() { }
#region Properties
[Required]
[StringLength(100)]
public string Address { get; set; }
[StringLength(100)]
public string Address2 { get; set; }
[Required]
[StringLength(50)]
public string City { get; set; }
[Required]
[StringLength(50)]
public string State { get; set; }
[Required]
[StringLength(50)]
public string Zip { get; set; }
[DataType(DataType.Date)]
//[Required]
public DateTime? DOB { get; set; }
[Required]
public string Gender { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public int? SchoolID { get; set; }
public int? GradeID { get; set; }
public string SpecialNeedsDescription { get; set; }
public string SpecialNeedsSummary { get; set; }
public byte[] PictureData { get; set; }
public string PictureAction { get; set; }
#region Membership
[Display(Name = "User Name")]
[DisplayName("User Name")]
[UniqueUserName(ErrorMessage = "The user name specified is already in use, please choose another user name.")]
public string Username { get; set; }
[Display(Name = "Password")]
[DisplayName("Enter a password")]
[StringLength(50, MinimumLength = 6, ErrorMessage = "Password must be at least 6 characters long.")]
public string Password { get; set; }
[DisplayName("Confirm Password")]
[StringLength(50, MinimumLength = 6)]
public string PasswordConfirm { get; set; }
#endregion
#region Abstracted Contact Methods
/// <summary>
/// When adding someone, this represents the phone number contact record.
/// </summary>
[Display(Name = "Home Phone Number")]
[DisplayName("Home Phone Number")]
[USPhoneNumber]
//[Required]
public string HomePhoneNumber { get; set; }
/// <summary>
/// When adding someone, this represents the phone number contact record.
/// </summary>
[Display(Name = "Cell Phone Number")]
[DisplayName("Cell Phone Number")]
[USPhoneNumber]
//[Required]
public string CellPhoneNumber { get; set; }
/// <summary>
/// When adding someone, this represents the email address contact record.
/// </summary>
[Display(Name = "Email Address")]
[DisplayName("Email Address")]
//[Required] -- Some parents dont have email addresses
//[UniqueEmailAddress(ErrorMessage = "The email address was already found in our system, please sign in or use another email.")]
[Email(ErrorMessage = "The email address specified isn't an email address.")]
public string EmailAddress { get; set; }
#endregion
#endregion
#region Read-Only Properties
public IList<School> Schools { get; internal set; }
public IList<ContactType> ContactTypes { get; internal set; }
public IList<string> Genders { get; internal set; }
public IList<Grade> Grades { get; internal set; }
public IList<USState> USStates { get; internal set; }
public IList<PersonType> PersonTypes { get; internal set; }
public IList<FamilyRole> FamilyRoles { get; internal set; }
public Person Person { get; internal set; }
#endregion
}
public class EditFamilyMemberService
{
#region Constructor
public EditFamilyMemberService(ITracktionDataLayer dataLayer, MessagePasser messager, AuthUserHelper authUser, int originalPersonID, int familyMemberID)
{
_dataLayer = dataLayer;
_originalPerson = new PersonAddEditModel(messager, dataLayer, authUser, originalPersonID);
_model = new PersonAddEditModel(messager, dataLayer, authUser, familyMemberID);
_grades = _dataLayer.GetGradesForOrganization(authUser.OrganizationID, _model.Person.Grade, true).ToArray();
Model = new EditFamilyMemberModel()
{
Address = _model.Person.Address,
Address2 = _model.Person.Address2,
CellPhoneNumber = _model.PersonalCell,
City = _model.Person.City,
ContactTypes = _model.ContactTypes,
DOB = _model.Person.DOB,
EmailAddress = _model.EmailAddress,
FamilyRoles = _model.FamilyRoles,
FirstName = _model.Person.FirstName,
Gender = _model.Person.Gender,
Genders = _model.Genders,
GradeID = _model.Person.Grade,
Grades = _model.Grades,
HomePhoneNumber = _model.HomePhone,
LastName = _model.Person.LastName,
Password = null,
PasswordConfirm = null,
PersonTypes = _model.PersonTypes,
PictureAction = null,
PictureData = null,
SchoolID = _model.Person.SchoolID,
Schools = _model.Schools,
SpecialNeedsDescription = _model.Person.SpecialNeedsDescription,
SpecialNeedsSummary = _model.Person.SpecialNeedsSummary,
State = _model.Person.State,
Username = null,
USStates = _model.USStates,
Zip = _model.Person.Zip,
Person = _model.Person
};
}
#endregion
#region Private
ITracktionDataLayer _dataLayer;
PersonAddEditModel _originalPerson;
PersonAddEditModel _model;
IList<Grade> _grades;
#endregion
#region Properties
public EditFamilyMemberModel Model { get; internal set; }
#region Read Only
public Person Person
{
get { return _model.Person; }
}
public AuthUserHelper AuthUser
{
get { return _model.AuthUser; }
}
#endregion
#endregion
#region Logic
public void SaveChanges()
{
_model.Person.ChangedTimeStamp = DateTime.Now;
_model.Person.ChangedBy = -1;
// If we have a valid home #, add it
if (!string.IsNullOrWhiteSpace(Model.HomePhoneNumber))
_model.HomePhone = Model.HomePhoneNumber;
// If we have a valid cell #, add it
if (!string.IsNullOrWhiteSpace(Model.CellPhoneNumber))
_model.PersonalCell = Model.CellPhoneNumber;
// If we have a valid email, add it
if (!string.IsNullOrWhiteSpace(Model.EmailAddress))
_model.EmailAddress = Model.EmailAddress;
// Some fields may have 'not applicable'; blank them
Model.SpecialNeedsDescription = Model.SpecialNeedsDescription.NormalizeNotApplicable().NullIfEmptyOrWhitespace();
Model.SpecialNeedsSummary = Model.SpecialNeedsSummary.NormalizeNotApplicable().NullIfEmptyOrWhitespace();
// Names of people should be proper case if they're all entered in lowercase
Model.FirstName = Model.FirstName.NormalizeName();
Model.LastName = Model.LastName.NormalizeName();
// Save this extra information
_model.Person.Address = Model.Address;
_model.Person.Address2 = Model.Address2;
_model.PersonalCell = Model.CellPhoneNumber;
_model.Person.City = Model.City;
_model.Person.DOB = Model.DOB;
_model.EmailAddress = Model.EmailAddress;
_model.Person.FirstName = Model.FirstName;
_model.Person.Gender = Model.Gender;
_model.Person.Grade = Model.GradeID;
_model.HomePhone = Model.HomePhoneNumber;
_model.Person.LastName = Model.LastName;
_model.Person.SchoolID = Model.SchoolID;
_model.Person.SpecialNeedsDescription = Model.SpecialNeedsDescription;
_model.Person.SpecialNeedsSummary = Model.SpecialNeedsSummary;
_model.Person.State = Model.State;
_model.Person.Zip = Model.Zip;
// Save picture data
if (Model.PictureData != null && (Model.PictureAction == "replace" || (Model.PictureAction ?? "") == ""))
{
// Replace just adds, it does not remove the old picture.
Photo pic = PhotoHandling.GetPhotoEntityFromBytes(Model.PictureData);
pic.ROWGUID = Guid.NewGuid();
pic.OrganizationID = _model.AuthUser.OrganizationID;
pic.CreationTimestamp = DateTime.Now;
pic.Deleted = false;
_model.AddNewPhoto(pic);
_model.Person.Avatar = pic.ROWGUID;
}
else if (Model.PictureAction == "remove" && _model.Person.Avatar.HasValue)
{
var pic = _model.Person.Photos.SingleOrDefault(p => p.ROWGUID == _model.Person.Avatar.Value);
if (pic != null)
{
pic.Deleted = true;
_model.Person.Avatar = null;
}
}
_model.SaveChanges();
}
#endregion
}
该模型本身不需要任何ctor参数,并且不应再引发该错误。 我非常喜欢将相关的逻辑和数据封装到一个类中,但是由于这只是繁重的PersonAddEditModel的包装,并且仅用于MVC方面,因此我可以解决这一问题。
如果有人对我刚刚发布的内容有任何投入或替代,我将不知所措。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.