I am trying to make a login/signup system with ASP.NET. I saw a tutorial on how to make it and I started following him. But it was sometimes messy and I couldn't understand him. (For the tutorial).
I used the 'new scaffolded item' to create a new 'identity' for login & registration.
I added custom data of my own (at this moment it's only FirstName&LastName) and when I create A user everything looks excellent, in debug mode I could see the data saved in my class but when it transfers to the database it holds as "NULL".
I am still new to this technique so I am not sure if that's all the code that's needed for you to help spot the problem. If the's anything to add, comment down, please.
here's the HTML for the registration (at the moment the login isn't complete) [Directory: Areas/Identity/Pages/Register.cshtml]
#page
#model RegisterModel
#{ ViewData["Title"] = "Register"; }
#{ Layout = "~/Areas/Identity/Pages/_AuthLayout.cshtml"; }
<form asp-route-returnUrl="#Model.ReturnUrl" method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label asp-for="Input.FirstName"></label>
<input asp-for="Input.FirstName" class="form-control" />
<span asp-validation-for="Input.FirstName" class="text-danger"></span>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label asp-for="Input.LastName"></label>
<input asp-for="Input.LastName" class="form-control" />
<span asp-validation-for="Input.LastName" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label asp-for="Input.Password"></label>
<input asp-for="Input.Password" class="form-control" />
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label asp-for="Input.ConfirmPassword"></label>
<input asp-for="Input.ConfirmPassword" class="form-control" />
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
</div>
</div>
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
#section Scripts {
<partial name="_ValidationScriptsPartial"></partial>
}
here's the C# (the backend) [Directory: Areas/Identity/Pages/Register.cshtml.cs]
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging;
using SvivaTeam.Areas.Identity.Data;
namespace SvivaTeam.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class RegisterModel : PageModel
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager;
private readonly ILogger<RegisterModel> _logger;
private readonly IEmailSender _emailSender;
public RegisterModel(
UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager,
ILogger<RegisterModel> logger,
IEmailSender emailSender)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
_emailSender = emailSender;
}
[BindProperty]
public InputModel Input { get; set; }
public string ReturnUrl { get; set; }
public IList<AuthenticationScheme> ExternalLogins { get; set; }
public class InputModel
{
[Required]
[DataType(DataType.Text)]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[DataType(DataType.Text)]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
public async Task OnGetAsync(string returnUrl = null)
{
if (User.Identity.IsAuthenticated)
Response.Redirect("/");
ReturnUrl = returnUrl;
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
}
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
UserName = Input.Email,
Email = Input.Email,
FirstName = Input.FirstName, //Custom Code
LastName = Input.LastName //Cusom Code
};
var result = await _userManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password.");
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = user.Id, code = code, returnUrl = returnUrl },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
if (_userManager.Options.SignIn.RequireConfirmedAccount)
{
return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl = returnUrl });
}
else
{
await _signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
// If we got this far, something failed, redisplay form
return Page();
}
}
}
Here's more C# code that holds the custom info (In the video he said to make it). [Directory: Areas/Identity/Data/ApplicationUser.cshtml]
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
namespace SvivaTeam.Areas.Identity.Data
{
public class ApplicationUser : IdentityUser
{
[PersonalData]
[Column(TypeName = "nvarchar(100)")]
public string FirstName { get; set; }
[PersonalData]
[Column(TypeName = "nvarchar(100)")]
public string LastName { get; set; }
}
}
Related
I'm trying to do a web App with ASP.NET Core 3.1. I have an existing SQL Database with full of users. I have only read access to this database, so I can't change nothing.
My question is, can I somehow use it to authentication to Login instead of AspNetUsers table?
(I don't need registration, nor forget password, etc., just a safety login)
My User database has these columns: Id(varchar),Name(varchar),Rank(int),Password(varchar),Email(varchar),Phone(varchar)
use it to authentication to Login instead of AspNetUsers table
Below is a demo, you can refer to it.
LoginModel
public class LoginModel
{
[Required]
[Display(Name ="Username")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
public bool RememberLogin { get; set; }
public string ReturnUrl { get; set; }
}
UserModel
public class UserModel
{
public int UserId { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Role { get; set; }
}
AccountController
[Note] I set fake data, you can get it directly from the database.
public class AccountController : Controller
{
//Sample Users Data, it can be fetched with the use of any ORM
public List<UserModel> users = null;
public AccountController()
{
users = new List<UserModel>();
users.Add(new UserModel() { UserId = 1, Username = "Anoop", Password = "123", Role = "Admin" });
users.Add(new UserModel() { UserId = 2, Username = "Other", Password = "123", Role = "User" });
}
public IActionResult Login(string ReturnUrl = "/")
{
LoginModel objLoginModel = new LoginModel();
objLoginModel.ReturnUrl = ReturnUrl;
return View(objLoginModel);
}
[HttpPost]
public async Task<IActionResult> Login(LoginModel objLoginModel)
{
if (ModelState.IsValid)
{
var user = users.Where(x => x.Username == objLoginModel.UserName && x.Password == objLoginModel.Password).FirstOrDefault();
if (user == null)
{
//Add logic here to display some message to user
ViewBag.Message = "Invalid Credential";
return View(objLoginModel);
}
else
{
//A claim is a statement about a subject by an issuer and
//represent attributes of the subject that are useful in the context of authentication and authorization operations.
var claims = new List<Claim>() {
new Claim(ClaimTypes.NameIdentifier,Convert.ToString(user.UserId)),
new Claim(ClaimTypes.Name,user.Username),
new Claim(ClaimTypes.Role,user.Role),
new Claim("FavoriteDrink","Tea")
};
//Initialize a new instance of the ClaimsIdentity with the claims and authentication scheme
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
//Initialize a new instance of the ClaimsPrincipal with ClaimsIdentity
var principal = new ClaimsPrincipal(identity);
//SignInAsync is a Extension method for Sign in a principal for the specified scheme.
//await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
// principal, new AuthenticationProperties() { IsPersistent = objLoginModel.RememberLogin });
await HttpContext.SignInAsync(
principal, new AuthenticationProperties() { IsPersistent = objLoginModel.RememberLogin });
return LocalRedirect(objLoginModel.ReturnUrl);
}
}
return View(objLoginModel);
}
public async Task<IActionResult> LogOut() {
//SignOutAsync is Extension method for SignOut
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
//Redirect to home page
return LocalRedirect("/");
}
}
In HomeController, use [Authorize] on ConfidentialData() method
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
[Authorize]
public IActionResult ConfidentialData()
{
return View();
}
}
ConfidentialData view
#{
ViewData["Title"] = "Confidential Data";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Confidential Data</h2>
#if (User.Identity.IsAuthenticated)
{
<table class="table table-bordered">
#foreach (var claim in User.Claims) {
<tr><td>#claim.Type</td><td>#claim.Value</td></tr>
}
</table>
}
Register Authentication in startup
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(x => x.LoginPath = "/account/login");
...
app.UseAuthentication();
app.UseAuthorization();
Result:
Read Use cookie authentication without ASP.NET Core Identity to know more.
Login form
#model LoginModel
#{
ViewData["Title"] = "Login";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Login</h2>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Login">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
#if (!string.IsNullOrEmpty(ViewBag.Message))
{
<span class="text-danger">
#ViewBag.Message
</span>
}
#Html.HiddenFor(x => x.ReturnUrl)
<div class="form-group">
<label asp-for="UserName" class="control-label"></label>
<input asp-for="UserName" class="form-control" />
<span asp-validation-for="UserName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Password" class="control-label"></label>
<input asp-for="Password" class="form-control" />
<span asp-validation-for="Password" class="text-danger"></span>
</div>
<div class="form-group">
<div class="checkbox">
<label>
<input asp-for="RememberLogin" /> #Html.DisplayNameFor(model => model.RememberLogin)
</label>
</div>
</div>
<div class="form-group">
<input type="submit" value="Login" class="btn btn-default" />
</div>
</form>
</div>
</div>
I've tried to pass a list of models to controller but with no luck. I have a problem with generating empty view and then pass values from filled forms to controller. What I have:
Models
public class PostsModel
{
[Required]
[DataType(DataType.DateTime)]
public DateTime PublishDate { get; set; }
[Required]
public List<PostModel> Posts { get; set; }
}
public class PostModel
{
public string Language {get;set;}
public string X {get;set;}
public string Y {get;set;}
// and other properties
}
Controller
public IActionResult New()
{
ViewData["ButtonName"] = "Add";
return View(new PostsModel { PublishDate = DateTime.UtcNow });
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> New(PostsModel model)
{
if (ModelState.IsValid)
{
// some code
// never reaches this point
}
return View(model);
}
Form:
<form method="post">
<h4>XYZ</h4>
<hr />
#{
Model.Posts = new List<PostModel>(2);
for (var i = 0; i < 2; i++)
{
Model.Posts.Add(new PostModel());
}
foreach (var test in Model.Posts)
{
<h4>xyz</h4>
<div class="form-group">
<label asp-for="#test.Subject">Temat</label>
<input asp-for="#test.Subject" class="form-control" />
<span asp-validation-for="#test.Subject" class="text-danger"></span>
</div>
}
}
<button type="submit" class="btn btn-primary">#ViewData["ButtonName"]</button>
</form>
Of course model is never valid. I don't have an idea how to do such functionality.
As #StephenMuecke said, using for-loop is working approach. In this particular problem that I had it's enough to do:
Controller:
public IActionResult New()
{
ViewData["ButtonName"] = "Add";
// example:
return View(new PostsModel { PublishDate = DateTime.UtcNow, Posts = new List<PostModel>(2) { new PostModel(), new PostModel() } });
}
View:
for (var i = 0; i < Model.Posts.Count; i++)
{
<h4>xyz</h4>
<div class="form-group">
<label asp-for="#Model.Posts[i].Subject">Temat</label>
<input asp-for="#Model.Posts[i].Subject" class="form-control" />
<span asp-validation-for="#Model.Posts[i].Subject" class="text-danger"></span>
</div>
#*and so one*#
}
I also want to thank M. Kostrzewski and M. Kaletka who also helped me on some .net group
This is my form in contact class
<form method="POST">
<fieldset>
<div class="form-group">
<input class="form-control" placeholder="E-mail" name="subid" autofocus="">
</div>
<button href="" class="btn btn-gm btn-success">View</button>
</fieldset>
This is my code in controller and i have view called Contact
[HttpGet]
public ActionResult Contact()
{
return View();
}
[HttpPost]
public ActionResult Contact(string subid)
{
try
{
var webClient = new WebClient();
string url = string.Format(BASE_URL + "Subjectstatus/{0}", subid);
var json = webClient.DownloadString(url);
var js = new JavaScriptSerializer();
ViewBag.attendlist = js.Deserialize<List<attendlist>>(json);
return View();
}
catch
{
ViewBag.con = "gg";
return null;
}
}
This is my attendlist class
public class attendlist
{
[Display(Name = "ID")]
public string sid { get; set; }
[Display(Name = "Name")]
public string name { get; set; }
[Display(Name = "Subject")]
public string sub { get; set; }
[Display(Name = "Date")]
public string date { get; set; }
}
This is Contact View im trying to loop it using for each
#foreach (var dd in ViewBag.attendlist)
{
<h3>#dd.ID</h3>
}
This is the error when im try to load contact view
[HttpGet]
public ActionResult Contact()
{
return View( new ViewContact() );
}
[HttpPost]
public ActionResult Contact(ViewContact contact)
{
try
{
var webClient = new WebClient();
string url = string.Format(BASE_URL + "Subjectstatus/{0}", contact.subid);
var json = webClient.DownloadString(url);
var js = new JavaScriptSerializer();
attendlist list= js.Deserialize<attendlist>(json)
contact.attendlist = list;
return View(contact);
}
catch
{
ViewBag.con = "gg";
return null;
}
}
Class ViewContact
public class ViewContact
{
public attendlist list { get; set; }
public string subid { get; set; }
}
And the foreach at the view
foreach(var dd in Model.list){
//your html view code
}
The view
<form method="POST">
<fieldset>
<div class="form-group">
#Html.TextBoxFor(m => m.subid, new { #class = "form-control", #placeholder = "Email" }) >
</div>
<button href="" class="btn btn-gm btn-success">View</button>
</fieldset>
*Note textboxfor , get the model atributte and it bind later it correctly to the action submit
*Note that now you have to pass a contect not a string to Contact(ViewContact contact) action
I would like to know if I can convert my div button group (btn-group) to razor syntax in my asp.net mvc app? I want the razor syntax so I can preselect and pre activate a button label when entering the page. If razor isn't needed, then can someone please show me how to make a button active and selected on the page being entered from my view model data? It seems that without razor I would have to pass my viewmodel data to javascript to perform, but that doesn't seem right. Here is my html
<div class="form-group">
#Html.LabelFor(model => model.Listing.SpaceType, htmlAttributes: new { #class = "control-label" })
<div class="btn-group form-control" data-toggle="buttons" id="SpaceType">
<label id="SpaceTypeLabel0" class="btn btn-primary">
<input type="radio" name="typeoptions" autocomplete="off" id="0"> House
</label>
<label id="SpaceTypeLabel1" class="btn btn-primary">
<input type="radio" name="typeoptions" autocomplete="off" id="1"> Apartment
</label>
<label id="SpaceTypeLabel2" class="btn btn-primary">
<input type="radio" name="typeoptions" autocomplete="off" id="2"> Studio
</label>
<label id="SpaceTypeLabel3" class="btn btn-primary">
<input type="radio" name="typeoptions" autocomplete="off" id="3"> Other
</label>
</div>
</div>
Here is my model
public class Space
{
public int SpaceId { get; set; }
public virtual SpaceOverview Overview { get; set; }
public virtual SpaceDetails Details { get; set; }
public virtual SpaceListing Listing { get; set; }
public virtual SpaceAddress Address { get; set; }
[Required]
public DateTime DateCreated { get; set; }
}
and spacelisting is
public class SpaceListing
{
[Key, ForeignKey("SpaceOf")]
public int SpaceListingId { get; set; }
public SpaceType SpaceType { get; set; }
public SpaceLocation SpaceLocation { get; set; }
public SpaceAccommodation Accommodation { get; set; }
public Space SpaceOf { get; set; } // one-to-one
}
and spacetype is
public enum SpaceType
{
Home,
Apartment,
Studio,
Park,
Beach,
Field,
Backyoard,
FrontYard,
Other
}
Currently you creating a group of radio buttons with name="typeoptions" which have no relationship to the model, and your not even giving the radio buttons a value attribute so nothing would post back anyway.
The syntax should be
#Html.RadioButtonFor(m => m.Listing.SpaceType, "House", new { id = "House" })
#Html.Label("House")
#Html.RadioButtonFor(m => m.Listing.SpaceType, "Apartment", new { id = "Apartment" })
#Html.Label("Apartment")
...
To make this easier, you can create an extension method
public static class RadioButtonHelper
{
public static MvcHtmlString EnumRadioButtonListFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)
{
ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
string name = ExpressionHelper.GetExpressionText(expression);
Type type = Nullable.GetUnderlyingType(metaData.ModelType);
if (type == null || !type.IsEnum)
{
throw new ArgumentException(string.Format("The property {0} is not an enum", name));
}
StringBuilder html = new StringBuilder();
foreach (Enum item in Enum.GetValues(type))
{
string id = string.Format("{0}_{1}", metaData.PropertyName, item);
StringBuilder innerHtml = new StringBuilder();
innerHtml.Append(helper.RadioButtonFor(expression, item, new { id = id }));
innerHtml.Append(helper.Label(id, item.ToDescription()));
TagBuilder div = new TagBuilder("div");
div.AddCssClass("radiobutton");
div.InnerHtml = innerHtml.ToString();
html.Append(div.ToString());
}
TagBuilder container = new TagBuilder("div");
container.AddCssClass("radiobutton-container");
container.InnerHtml = html.ToString();
return MvcHtmlString.Create(container.ToString());
}
}
Note, this uses the following extension method
public static string ToDescription(this Enum value)
{
FieldInfo field = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])field.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Length > 0)
{
return attributes[0].Description;
}
return value.ToString();
}
which allows you to decorate the enum values with a 'friendly' name
public enum SpaceType
{
Home,
[Description("2 bed apartment")]
Apartment,
....
}
and in the view
#Html.EnumRadioButtonListFor(m => m.Listing.SpaceType)
this is my models:
public class Ressource
{
[Key]
public int RessourceId { get; set; }
public string TitreR { get; set; }
public string Link { get; set; }
public string Type { get; set; }
public string Desc { get; set; }
public int Position { get; set; }
public int Rating { get; set; }
public string Tags { get; set; }
public int SectionId { get; set; }
public int UserId { get; set; }
}
public class Section
{
[Key]
public int SectionId { get; set; }
public string Titre { get; set; }
public String Tags { get; set; }
public virtual ICollection<Ressource> Ressources { get; set; }
}
public class structure
{
public Ressource ress;
public List<string> liste;
}
In this view, I enter the resource's title (TitreR), a description (Desc) and I choose from a list of tags which ones I want to link with this resource as well as entering a tag:
#model Mocodis.Models.structure
#{
ViewBag.Title = "AjouterRessource";
}
<h2>AjouterRessource</h2>
#using (Html.BeginForm("AjouterRessource", "Home", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<input type="hidden" name="SectionId" value="#Model.ress.SectionId" />
<legend>Ressource</legend>
<div class="editor-label">
#Html.LabelFor(model => model.ress.TitreR)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ress.TitreR)
#Html.ValidationMessageFor(model => model.ress.TitreR)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ress.Desc)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ress.Desc)
#Html.ValidationMessageFor(model => model.ress.Desc)
</div>
</fieldset>
}
<form id="orderProductForm219" name="orderProductForm219" method="post" >
<b>Choisir les mots clés:</b>
<br /><br />
#foreach (string s in #Model.liste)
{
<input type="checkbox" name="tags[]" value="#s"> #s<br />
}
<input type="text" name="tags" id="tags" value="" />
<p>
<input type="submit" value="Create" />
<input type="hidden" name="tag" value="tags" />
<input type="hidden" name="res" value="#Model.ress" />
</p></form>
(I didnt put the javascript for it)
Finally the controllers are:
public ActionResult AjouterRessource(int SectionId)
{
Ressource res = new Ressource();
res.SectionId = SectionId;
Section sec = _db.Sections.Where(r => r.SectionId == SectionId).FirstOrDefault();
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
List<string> l = new List<string>();
l = sec.Tags.Split(delimiterChars).ToList();
structure s = new structure();
s.ress = res;
s.liste = l;
return View(s);
}
public string Check ( string list, string s)
{
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
List<string> l = new List<string>();
List<string> liste = new List<string>();
l = s.Split(delimiterChars).ToList();
liste = list.Split(delimiterChars).ToList();
foreach (string item in l)
{
if (!liste.Contains(item))
liste.Add(item);
}
return (string.Join(" ", liste.ToArray()));
}
[Authorize]
[HttpPost]
[InitializeSimpleMembership]
public ActionResult AjouterRessource(Ressource res, int SectionId, string tag)
{
if (ModelState.IsValid)
{
res.SectionId = SectionId;
var model = _db.Sections.Where(c => c.SectionId == SectionId).FirstOrDefault();
res.Tags = tag;
model.Tags = Check(model.Tags, tag);
_db.Entry(model).State = EntityState.Modified;
_db.Entry(res).State = EntityState.Added;
_db.SaveChanges();
return RedirectToAction("Section", new { SectionId = SectionId });
}
return View();
}
I keep getting: Object reference not set to an instance of an object on the line: #Html.ValidationSummary(true) in my view. Can you tell me how to fix it please?
Thank you
Every time I have gotten that error it has been from not initializing something. Looking through your code the only spot I am seeing that might need it is when you are setting structure. You might try putting a constructor on that class to initialize the fields and see if that helps. something like
public structure()
{
ress = new Resource();
liste = new List<string>();
}
You probably need to add the { get; set; } to the resource and list under structure as well. Hopefully this helps.