i have two tables aspNetUser and Tutorial i want a registered aspNetUser to to be able to create a tutorial and i want return the tutorial data to their page and other pages but i am strugling with saving the tutorial with the aspNetUser'id, i have been looking at one to many articles but they only show how to do one to many but what i want is the code for controller or view to save the tutorial with the aspNetUser id I would appreciate any help, here is my code below:
Tutorial model
[Table("Tutorial")]
public class Tutorial
{
[Key]
public int TutorialId { get; set; }
public string Topic { get; set; }
[Required(ErrorMessage = "Course Name is required")]
[Display(Name = "Course Name")]
public string CoursesName { get; set; }
[Required(ErrorMessage = "Discription is required")]
public string Description { get; set; }
[AllowHtml]
public string Content { get; set; }
public ApplicationUser User { get; set; }
}
Identity model i modified it like this
public class ApplicationUser : IdentityUser
{
public ICollection<Tutorial> Tutorials { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
and in my Controller Create and edit
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "TutorialId,Topic,CoursesName,Description,Content")] Tutorial tutorial)
{
if (ModelState.IsValid)
{
db.Tutorials.Add(tutorial);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(tutorial);
}
// GET: Tutorial/Edit/5
public async Task<ActionResult> Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Tutorial tutorial = await db.Tutorials.FindAsync(id);
if (tutorial == null)
{
return HttpNotFound();
}
return View(tutorial);
}
And lastly my Create view
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Tutorial</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Topic, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Topic, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Topic, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.CoursesName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.CoursesName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.CoursesName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Description, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Description, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Content, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Content, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Content, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
Tutorial data has a null foreign key
So i have been trying this while waiting for any help. I came up with this
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Create(Tutorial Tutorial)
{
var user = new ApplicationUser();
if (ModelState.IsValid)
{
db.Tutorials.Add(new Tutorial {
UserId = user.Id//i get the current user id but i cant insert it with the other data
});
db.SaveChanges();
return RedirectToAction("Index");
}
return View(Tutorial);
}
and i changed my models like this IdentityModels i put the virtual
public virtual ICollection<Tutorial> Tutorials { get; set; }
Tutorial model
[ForeignKey("User")]
public string UserId { get; set; }
public virtual ApplicationUser User { get; set; }
Create View
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Tutorial</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Topic, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Topic, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Topic, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.CoursesName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.CoursesName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.CoursesName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Description, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Description, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Content, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Content, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Content, "", new { @class = "text-danger" })
</div>
</div>
@*@Html.HiddenFor(model => model.User.Id)*@
@*<div class="form-group">
@Html.LabelFor(model => model.UserId, "UserId", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("UserId", null, htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.UserId, "", new { @class = "text-danger" })
</div>
</div>*@
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
but i get this error
> System.Data.Entity.Validation.DbEntityValidationException
HResult=0x80131920
Message=Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
Source=EntityFramework
StackTrace:
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()
at System.Data.Entity.DbContext.SaveChanges()
at KLUE_Inc.Controllers.TutorialController.Create(Tutorial Tutorial) in C:\Users\raliq\Music\KLUE Inc\KLUE Inc\Controllers\TutorialController.cs:line 40
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()
hello i found the answer
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(Tutorial tutorial)
{
if (ModelState.IsValid)
{
var UserId = User.Identity.GetUserId();
Tutorial.UserId = UserId;
db.Tutorials.Add(tutorial);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(tutorial);
}
at first i was putting this code: var UserId = User.Identity.GetUserId();out of the if( ModelState.isvalid) and it did not work it was giving me a null refrence. I want to thank Brendan Green,
ahmed-abdi and pathan-faisal for helping me thanks.
User contributions licensed under CC BY-SA 3.0