Reputation: 4126
I have an object called "Professional", my professional has a list of "Skills"
I'm getting a problem when I try to insert a new skill to determinated professional
I've tried to do this at view that posts the new object:
<div>
@Html.ActionLink("Add Skill", "AddNewSkill", new { skill = Model, id = ViewBag.professionalId} )
</div>
The controller methods
public ActionResult AddNewSkill(int professionalId)
{
ViewBag.professionalId = professionalId;
return View();
}
[HttpPost]
public ActionResult AddNewSkill(SkillModel skill, int professionalId)
{
professionalBusiness = new ProfessionalBusiness();
var professional = professionalBusiness.GetById(professionalId);
professional.Skills.Add(skill);
if (ModelState.IsValid)
{
professionalBusiness.Update(professional);
return RedirectToAction("Index");
}
return RedirectToAction("Edit", professionalId);
}
But that's wierd because my URL shows me only one parameter
http:// localhost:20995/Professional/AddNewSkill/1
And when I try to POST it gives me this error:
[ArgumentException: The parameters dictionary contains a null entry for parameter 'professionalId' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult AddNewSkill(Int32)' in 'TCCApplication.Controllers.ProfessionalController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Nome do parâmetro: parameters]
System.Web.Mvc.ActionDescriptor.ExtractParameterFromDictionary(ParameterInfo parameterInfo, IDictionary`2 parameters, MethodInfo methodInfo) +607955
System.Web.Mvc.<>c__DisplayClass1.<Execute>b__0(ParameterInfo parameterInfo) +18
System.Linq.WhereSelectArrayIterator`2.MoveNext() +66
System.Linq.Buffer`1..ctor(IEnumerable`1 source) +216
System.Linq.Enumerable.ToArray(IEnumerable`1 source) +77
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +135
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
System.Web.Mvc.Async.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41() +28
System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +10
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +57
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +48
System.Web.Mvc.Async.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33() +57
System.Web.Mvc.Async.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49() +223
System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeActionMethodWithFilters>b__36(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +57
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +48
System.Web.Mvc.Async.<>c__DisplayClass2a.<BeginInvokeAction>b__20() +24
System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult) +102
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +57
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +43
System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +14
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +57
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +47
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult) +25
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +23
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +47
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9690164
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
Upvotes: 0
Views: 80
Reputation: 6023
Your parameter names do not match between the call and the controller action.
Try changing the call to:
@Html.ActionLink("Add Skill", "AddNewSkill", new { skill = Model, professionalId = ViewBag.professionalId} )
EDIT:
POSTing your form data to your controller action is not easily possible with @Html.ActionLink()
I would recommend that you wrap your existing view html in a BeginForm statement with a standard html submit button:
@using(Html.BeginForm("AddNewSkill","YourControllerName", FormMethod.Post))
{
// ...your existing markup with the properties of the model here...
<button type="submit">Add Skill</button>
}
This should post all of your model properties to your controller action. You should note that the various properties will get 'reassembled' (technically: bound) to the model on the server-side by the MVC ModelBinder.
IOW You don't need to try to send the model as a complete object, like you seemed to be trying to do with the RouteValues -- as in
new { skill = Model...
.
Hope that helps.
Upvotes: 1
Reputation: 195
Where is your Id that mentioned on over the ActionLink
@Html.ActionLink("Add Skill", "AddNewSkill", new { skill = Model, id = ViewBag.professionalId} )
parameters name should match with the action result parameters. so change your action link as following
@Html.ActionLink("Add Skill", "AddNewSkill", new { skill = Model, professionalId = ViewBag.professionalId} )
this should work
cheers
Upvotes: 0