I have “reset password” and “user profile info update” sections on one view.
I have a parent model with two child models: ResetPwdModel and UserInfoModel.
For both reset password submit and save profile info submit, I want the result URL to look the same (same as the current URL), so the users won’t be confused.
In an effort to achieve this, I overloaded the action methods with one accepting ResetPwdModel and the other accepting UserInfoModel. However, I get the error message The current request for action 'profile' on controller type 'XXController' is ambiguous...
Is there an elegant way to resolve this? My goal is to be able to use two models in 1 view and have the post URL looking the same as current URL.
Model
public class ProfileParentModel
{
public ProfileResetPwdModel ResetPwd { get; set; }
public ProfileUserInfoModel UserInfo { get; set; }
}
public class ProfileResetPwdModel
{
[Required]
[DataType(DataType.Password)]
[Display(Name = "Profile_lbl_OldPassword", ResourceType = typeof(Resource))]
public string OldPassword { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Profile_lbl_NewPassword", ResourceType = typeof(Resource))]
public string NewPassword { get; set; }
[Compare("NewPassword", ErrorMessageResourceName = "Profile_Error_NotMatch", ErrorMessageResourceType = typeof(Resource))]
[Required]
[DataType(DataType.Password)]
[Display(Name = "Profile_lbl_ConfirmNewPassword", ResourceType = typeof(Resource))]
public string ConfirmNewPassword { get; set; }
}
public class ProfileUserInfoModel
{
[Display(Name = "Profile_lbl_FirstName", ResourceType = typeof(Resource))]
public string FirstName { get; set; }
[Display(Name = "Profile_lbl_LastName", ResourceType = typeof(Resource))]
public string LastName { get; set; }
[Display(Name = "Profile_lbl_WorkTitle", ResourceType = typeof(Resource))]
public string WorkTitle { get; set; }
[Display(Name = "Profile_lbl_CompanyName", ResourceType = typeof(Resource))]
public string CompanyName { get; set; }
[Display(Name = "Profile_lbl_CompanyAddress", ResourceType = typeof(Resource))]
public string CompanyAddress { get; set; }
}
View
@{
var passwordHtml = Html.HtmlHelperFor(Model.ResetPwd);
var profileHtml = Html.HtmlHelperFor(Model.UserInfo);
}
@using (passwordHtml.BeginForm())
{
//HTML goes here...
}
@using (profileHtml.BeginForm())
{
//HTML goes here...
}
Controller
[ActionName("Profile")]
[HttpPost]
[Authorize]
public ActionResult ResetPassword(ProfileResetPwdModel model)
{
return View("Profile", parentModel);
}
[ActionName("Profile")]
[HttpPost]
[Authorize]
public ActionResult SaveUserInfo(ProfileUserInfoModel model)
{
return View("Profile", parentModel);
}
Your action method names are irrelevant to what you want the response URL to be.
First, are you submitting data using two separate Html forms? I would say this is the best way, and point each to a different action. Your action can then redirect to whichever action you want.
Next, you wont be able to specify the child models as parameters for the action as the framework will not be able to automatically work out the properties (because you use a parent model to begin with) but this actually depends on how you define the names of your form fields.
If you are using the
Html.TextBoxFormethods for example. then this will give a field name of ‘parent.childproperty’. In this case you should use the parent model as a parameter for both actions:If you are happy to manually set the field names yourself, to match the child class properties then you can use the child models as parameterss:
with fields set like:
and they will map correctly.
after processing each action just add the following at the end: