An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter - dictionary

I am struck at this code, i get this error when whenever i tried to see a list of articles.
the error is The parameters dictionary contains a null entry for parameter articleId of non-nullable type System.Int32 for method System.Web.Mvc.ActionResult Detail(Int32) in Crossroads.Controllers.ArticleController. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters.
Here is the controller:
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Security;
using Crossroads.Models;
using System.Linq;
using System.Web;
using Crossroads.Models.Repositories;
namespace Crossroads.Controllers
{
[HandleError]
public class ArticleController : BaseController
{
private IArticleRepository _ArticleRepository;
public ArticleController()
: this(new ArticleRepository())
{ }
public ArticleController(IArticleRepository articleRepo)
{
_ArticleRepository = articleRepo;
}
public ActionResult Index(bool? archived)
{
if (archived != null && archived.Value.Equals(true))
{
return View("IndexArchived", _ArticleRepository.ListArchivedArticles());
}
else
{
return View(_ArticleRepository.ListArticles());
}
}
public ActionResult Detail(int Id)
{
var article = _ArticleRepository.GetArticle(Id);
if (article.Published)
{
return View("Details", article);
}
else
{
postStatus = new PostStatusViewModel()
{
Status = Status.Warning,
Message = "I'm sorry, article " + article.Title + " has been deleted. <br />Please update your bookmark."
};
return RedirectToAction("PostStatus", postStatus);
}
}
public ActionResult Details(int id, string articleTitle)
{
return RedirectToAction("Detail", id);
}
[Authorize(Roles = "Manager")]
public ActionResult New()
{
return View("New", new Articles());
}
[Authorize(Roles = "Manager")]
[ValidateInput(false)]
public ActionResult Edit(int id)
{
var viewModel = _ArticleRepository.GetArticle(id);
return View(_ArticleRepository.GetArticle(id));
}
[AcceptVerbs(HttpVerbs.Post)]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
[Authorize(Roles = "Manager")]
public ActionResult Create(Articles model)
{
try
{
model.CreatedBy = Membership.GetUser().UserName;
model.CreatedDate = DateTime.Now;
model.ModifiedBy = Membership.GetUser().UserName;
model.ModifiedDate = DateTime.Now;
_ArticleRepository.CreateArticle(model);
return RedirectToAction("Index");
}
catch
{
return View("Edit", model.Id);
}
}
[AcceptVerbs(HttpVerbs.Post)]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
[Authorize(Roles = "Manager")]
public ActionResult Update(Articles model)
{
try
{
model.ModifiedBy = Membership.GetUser().UserName;
model.ModifiedDate = DateTime.Now;
_ArticleRepository.EditArticle(model);
return RedirectToAction("Details", new { id = model.Id });
}
catch (Exception ex)
{
_DBLogging.LoggError(ex);
postStatus = new PostStatusViewModel()
{
Status = Status.Error,
Message = ""
};
return View("Edit");
}
}
public JsonResult ManageArchiveArticle(int articleId, bool isArchived)
{
var result = new Dictionary<string, string>();
try
{
var article = _ArticleRepository.GetArticle(articleId);
article.IsArchived = isArchived ? false : true;
article.ModifiedBy = Membership.GetUser().UserName;
article.ModifiedDate = DateTime.Now;
if (article.IsArchived) article.ArchiveDate = DateTime.Now;
article = _ArticleRepository.EditArticle(article);
result.Add("isArchived", article.IsArchived.ToString().ToLower());
}
catch (Exception ex)
{
_DBLogging.LoggError(ex);
}
return Json(result);
}
public JsonResult ManagePublishArticle(int articleId, bool isPublished)
{
var result = new Dictionary<string, string>();
try
{
var article = _ArticleRepository.GetArticle(articleId);
article.Published = isPublished ? false : true;
article.ModifiedBy = Membership.GetUser().UserName;
article.ModifiedDate = DateTime.Now;
article = _ArticleRepository.EditArticle(article);
result.Add("isPublished", article.Published.ToString().ToLower());
}
catch (Exception ex)
{
_DBLogging.LoggError(ex);
}
return Json(result);
}
}
}
here is my index
<ul class="menu">
<li><%= Html.ActionLink("Article List", "Index", "Article")%></li>
<li><%= Html.ActionLink("New Article", "New", "Article")%></li>
</ul>

Related

Why does my 'sessions' keep giving error?

I am trying to integrate the google authenticator app with my asp.net core web app but my Session in my home controller keeps giving errors. I'm looking for possible fixes.
using Google.Authenticator;
using Microsoft.AspNetCore.Mvc;
namespace QAService.Controllers
{
public class HomeController : Controller
{
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(FormCollection fc)
{
if (fc["username"] == "Admin" && fc["password"] == "Admin123")
{
Session["sampleid"] = fc["username"];
return RedirectToAction("VerifyAuth");
}
else
{
return View();
}
}
public ActionResult VerifyAuth()
{
if (Session["sampleid"] != null)
{
return RedirectToAction("Login");
}
else
{
return View();
}
}
string key = "test123!##)(*";
[HttpPost]
public ActionResult VerifyAuth(FormCollection fc)
{
if (Session["sampleid"] == null)
{
return RedirectToAction("Admin_Login");
}
var token = fc["passcode"];
TwoFactorAuthenticator tfa = new TwoFactorAuthenticator();
string UserUniqueKey = (Convert.ToString(Session["sampleid"]) + key);
bool isValid = tfa.ValidateTwoFactorPIN(UserUniqueKey, token);
if (isValid)
{
Session["id"] = Convert.ToString(Session["sampleid"]);
return RedirectToAction("Myprofile");
}
return RedirectToAction("Login");
}
public ActionResult AdminQR()
{
if (Session["sampleid"] != null)
{
TwoFactorAuthenticator tfa = new TwoFactorAuthenticator();
string UserUniqueKey = (Convert.ToString(Session["sampleid"]) + key);
Session["UserUniqueKey"] = UserUniqueKey;
var setupInfo = tfa.GenerateSetupCode("Google Auth Test", Convert.ToString(Session["sampleid"]), UserUniqueKey, 300, 300);
ViewBag.BarcodeImageUrl = setupInfo.QrCodeSetupImageUrl;
ViewBag.SetupCode = setupInfo.ManualEntryKey;
return View();
}
else
{
return RedirectToAction("Login");
}
}
public ActionResult Myprofile()
{
if (Session["id"] != null)
{
return View();
}
else
{
return RedirectToAction("Login");
}
}
}
}

How to populate ViewDataDictionary inside an ExceptionFilter

How to retrieve the ViewModel from within an exception filter?
I have an ExceptionFilter, which I am using for a global error handler in an asp .net core 3.1 MVC application. I am trying to get the exception filter to redirect back to the View when there is an error and show validation errors, ie the equivalent of saying:
return View(viewModel)
in the controller
I can redirect to the View, but am a little stuck on how to populate the Model in the ViewResult
ExceptionFilter code
public void OnException(ExceptionContext context)
{
string controller = context.RouteData.Values["controller"].ToString();
string action = context.RouteData.Values["action"].ToString();
if (context.Exception is WebServiceException && context.Exception.IsUnauthorized())
{
context.Result = new RedirectToActionResult("fetchtoken", "Home", new { path = $"/{controller}/{action}" });
}
//other type of exception, return the view displaying errors
else
{
context.ModelState.Clear();
context.ModelState.AddModelError(action, $"error in {action}");
m_Logger.LogError(context.Exception, $"error in {action}");
context.ExceptionHandled = true;
context.ModelState
context.Result = new ViewResult{
ViewName = action,
ViewData = // ??????????????
};
}
}
In the controller:
[Authorize]
[HttpPost]
public async Task<IActionResult> AuthoriseApiUser(AuthoriseApiViewModel viewModel)
{
await m_ApiUserService.AuthoriseUser(viewModel.TenantId, viewModel.UserId); //error thrown here
return View(viewModel);
}
Through obtaining the value of each key in the form data, the value is compared with the property of the model. Then, assign value to model. For example.
public void OnException(ExceptionContext context)
{
string controller = context.RouteData.Values["controller"].ToString();
string action = context.RouteData.Values["action"].ToString();
//start
var viewModel = new ViewModel();
var list = context.HttpContext.Request.Form.AsEnumerable();
foreach (var meta in list)
{
if (meta.Key == "addr")
{
viewModel.addr = meta.Value;
}
}
//end
if (context.Exception is WebServiceException && context.Exception.IsUnauthorized())
{
context.Result = new RedirectToActionResult("fetchtoken", "Home", new { path = $"/{controller}/{action}" });
}
//other type of exception, return the view displaying errors
else
{
//...
var modelMetadata = new EmptyModelMetadataProvider();
context.Result = new ViewResult
{
ViewName = action,
ViewData = ViewData = new ViewDataDictionary(modelMetadata, context.ModelState)
{
Model = viewModel
}
};
}
}
Model
public class ViewModel
{
public int id { get; set; }
[MinLength(2)]
public string addr { get; set; }
}

ASP NET Entity Framework primary key Duplicate resolution

[HttpGet]
public ActionResult Create()
{
Articles article = new Articles();
return View(article);
}
[HttpPost]
public ActionResult Create(Articles article)
{
try
{
article.ViewCount = 0;
article.IPAddress = Request.ServerVariables["REMOTE_ADDR"].ToString();
article.RegistDate = DateTime.Now;
article.RegistMemberID = "admin";
article.ModifyDate = DateTime.Now;
article.ModifyMemberID = "admin";
db.Articles.Add(article);
db.SaveChanges();
if (Request.Files.Count > 0)
{
var attachFile = Request.Files[0];
if (attachFile != null && attachFile.ContentLength > 0)
{
var fileName = Path.GetFileName(attachFile.FileName);
var path = Path.Combine(Server.MapPath("~/Upload/"), fileName);
attachFile.SaveAs(path);
ArticleFiles file = new ArticleFiles();
file.ArticleIDX = article.ArticleIDX;
file.FilePath = "/Upload/";
file.FileName = fileName;
file.FileFormat = Path.GetExtension(attachFile.FileName);
file.FileSize = attachFile.ContentLength;
file.UploadDate = DateTime.Now;
db.ArticleFiles.Add(file);
db.SaveChanges();
}
}
ViewBag.Result = "OK";
}
catch (Exception ex)
{
Debug.WriteLine("Board");
Debug.WriteLine(ex.ToString());
ViewBag.Result = "FAIL";
}
return View(article);
//return RedirectToAction("ArticleList");
}
The controller writes a message. But if you write a message (through a POST request) on a bulletin board, it will work normally when you try to post it the first time. But when you try to post again, it fails. I think the cause is a duplicate primary key.
Please let me know what you can do in case of a duplication of the primary key.
namespace HeadHomePage1.Models
{
public class ArticlesEditViewModel
{
public Articles Article { get; set; }
public List<ArticleFiles> Files { get; set; }
}
}
모델부분입니다.

Web API 2. Register method returns error

I've created a simple web api 2 service from default template (asp.net mvc 5) with basic authentication.
I use Unity.WebAPI for IoC. And when I try send a POST request to /api/account/register method I get an error:
An error occurred when trying to create a controller of type 'AccountController'.
Make sure that the controller has a parameterless public constructor.
Googling didn't help me because all example are more specific, but I'm too new in Web API and Unity.
I found that link but didn't understood all from #Horizon_Net's answer :(
Can anyone show me the example "for dummies"?
Edit:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.ModelBinding;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OAuth;
using NewMMC.Models;
using NewMMC.Providers;
using NewMMC.Results;
namespace NewMMC.Controllers
{
[Authorize]
[RoutePrefix("api/Account")]
public class AccountController : ApiController
{
private const string LocalLoginProvider = "Local";
public AccountController()
: this(Startup.UserManagerFactory(), Startup.OAuthOptions.AccessTokenFormat)
{
}
public AccountController(UserManager<IdentityUser> userManager,
ISecureDataFormat<AuthenticationTicket> accessTokenFormat)
{
UserManager = userManager;
AccessTokenFormat = accessTokenFormat;
}
public UserManager<IdentityUser> UserManager { get; private set; }
public ISecureDataFormat<AuthenticationTicket> AccessTokenFormat { get; private set; }
// GET api/Account/UserInfo
[HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
[Route("UserInfo")]
public UserInfoViewModel GetUserInfo()
{
ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);
return new UserInfoViewModel
{
UserName = User.Identity.GetUserName(),
HasRegistered = externalLogin == null,
LoginProvider = externalLogin != null ? externalLogin.LoginProvider : null
};
}
// POST api/Account/Logout
[Route("Logout")]
public IHttpActionResult Logout()
{
Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);
return Ok();
}
// GET api/Account/ManageInfo?returnUrl=%2F&generateState=true
[Route("ManageInfo")]
public async Task<ManageInfoViewModel> GetManageInfo(string returnUrl, bool generateState = false)
{
IdentityUser user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
if (user == null)
{
return null;
}
List<UserLoginInfoViewModel> logins = new List<UserLoginInfoViewModel>();
foreach (IdentityUserLogin linkedAccount in user.Logins)
{
logins.Add(new UserLoginInfoViewModel
{
LoginProvider = linkedAccount.LoginProvider,
ProviderKey = linkedAccount.ProviderKey
});
}
if (user.PasswordHash != null)
{
logins.Add(new UserLoginInfoViewModel
{
LoginProvider = LocalLoginProvider,
ProviderKey = user.UserName,
});
}
return new ManageInfoViewModel
{
LocalLoginProvider = LocalLoginProvider,
UserName = user.UserName,
Logins = logins,
ExternalLoginProviders = GetExternalLogins(returnUrl, generateState)
};
}
// POST api/Account/ChangePassword
[Route("ChangePassword")]
public async Task<IHttpActionResult> ChangePassword(ChangePasswordBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword,
model.NewPassword);
IHttpActionResult errorResult = GetErrorResult(result);
if (errorResult != null)
{
return errorResult;
}
return Ok();
}
// POST api/Account/SetPassword
[Route("SetPassword")]
public async Task<IHttpActionResult> SetPassword(SetPasswordBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
IHttpActionResult errorResult = GetErrorResult(result);
if (errorResult != null)
{
return errorResult;
}
return Ok();
}
// POST api/Account/AddExternalLogin
[Route("AddExternalLogin")]
public async Task<IHttpActionResult> AddExternalLogin(AddExternalLoginBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
AuthenticationTicket ticket = AccessTokenFormat.Unprotect(model.ExternalAccessToken);
if (ticket == null || ticket.Identity == null || (ticket.Properties != null
&& ticket.Properties.ExpiresUtc.HasValue
&& ticket.Properties.ExpiresUtc.Value < DateTimeOffset.UtcNow))
{
return BadRequest("External login failure.");
}
ExternalLoginData externalData = ExternalLoginData.FromIdentity(ticket.Identity);
if (externalData == null)
{
return BadRequest("The external login is already associated with an account.");
}
IdentityResult result = await UserManager.AddLoginAsync(User.Identity.GetUserId(),
new UserLoginInfo(externalData.LoginProvider, externalData.ProviderKey));
IHttpActionResult errorResult = GetErrorResult(result);
if (errorResult != null)
{
return errorResult;
}
return Ok();
}
// POST api/Account/RemoveLogin
[Route("RemoveLogin")]
public async Task<IHttpActionResult> RemoveLogin(RemoveLoginBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
IdentityResult result;
if (model.LoginProvider == LocalLoginProvider)
{
result = await UserManager.RemovePasswordAsync(User.Identity.GetUserId());
}
else
{
result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(),
new UserLoginInfo(model.LoginProvider, model.ProviderKey));
}
IHttpActionResult errorResult = GetErrorResult(result);
if (errorResult != null)
{
return errorResult;
}
return Ok();
}
// GET api/Account/ExternalLogin
[OverrideAuthentication]
[HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)]
[AllowAnonymous]
[Route("ExternalLogin", Name = "ExternalLogin")]
public async Task<IHttpActionResult> GetExternalLogin(string provider, string error = null)
{
if (error != null)
{
return Redirect(Url.Content("~/") + "#error=" + Uri.EscapeDataString(error));
}
if (!User.Identity.IsAuthenticated)
{
return new ChallengeResult(provider, this);
}
ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);
if (externalLogin == null)
{
return InternalServerError();
}
if (externalLogin.LoginProvider != provider)
{
Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
return new ChallengeResult(provider, this);
}
IdentityUser user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider,
externalLogin.ProviderKey));
bool hasRegistered = user != null;
if (hasRegistered)
{
Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
ClaimsIdentity oAuthIdentity = await UserManager.CreateIdentityAsync(user,
OAuthDefaults.AuthenticationType);
ClaimsIdentity cookieIdentity = await UserManager.CreateIdentityAsync(user,
CookieAuthenticationDefaults.AuthenticationType);
AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);
}
else
{
IEnumerable<Claim> claims = externalLogin.GetClaims();
ClaimsIdentity identity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType);
Authentication.SignIn(identity);
}
return Ok();
}
// GET api/Account/ExternalLogins?returnUrl=%2F&generateState=true
[AllowAnonymous]
[Route("ExternalLogins")]
public IEnumerable<ExternalLoginViewModel> GetExternalLogins(string returnUrl, bool generateState = false)
{
IEnumerable<AuthenticationDescription> descriptions = Authentication.GetExternalAuthenticationTypes();
List<ExternalLoginViewModel> logins = new List<ExternalLoginViewModel>();
string state;
if (generateState)
{
const int strengthInBits = 256;
state = RandomOAuthStateGenerator.Generate(strengthInBits);
}
else
{
state = null;
}
foreach (AuthenticationDescription description in descriptions)
{
ExternalLoginViewModel login = new ExternalLoginViewModel
{
Name = description.Caption,
Url = Url.Route("ExternalLogin", new
{
provider = description.AuthenticationType,
response_type = "token",
client_id = Startup.PublicClientId,
redirect_uri = new Uri(Request.RequestUri, returnUrl).AbsoluteUri,
state = state
}),
State = state
};
logins.Add(login);
}
return logins;
}
// POST api/Account/Register
[AllowAnonymous]
[Route("Register")]
public async Task<IHttpActionResult> Register(RegisterBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
IdentityUser user = new IdentityUser
{
UserName = model.UserName
};
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
IHttpActionResult errorResult = GetErrorResult(result);
if (errorResult != null)
{
return errorResult;
}
return Ok();
}
// POST api/Account/RegisterExternal
[OverrideAuthentication]
[HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
[Route("RegisterExternal")]
public async Task<IHttpActionResult> RegisterExternal(RegisterExternalBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);
if (externalLogin == null)
{
return InternalServerError();
}
IdentityUser user = new IdentityUser
{
UserName = model.UserName
};
user.Logins.Add(new IdentityUserLogin
{
LoginProvider = externalLogin.LoginProvider,
ProviderKey = externalLogin.ProviderKey
});
IdentityResult result = await UserManager.CreateAsync(user);
IHttpActionResult errorResult = GetErrorResult(result);
if (errorResult != null)
{
return errorResult;
}
return Ok();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
UserManager.Dispose();
}
base.Dispose(disposing);
}
#region Helpers
private IAuthenticationManager Authentication
{
get { return Request.GetOwinContext().Authentication; }
}
private IHttpActionResult GetErrorResult(IdentityResult result)
{
if (result == null)
{
return InternalServerError();
}
if (!result.Succeeded)
{
if (result.Errors != null)
{
foreach (string error in result.Errors)
{
ModelState.AddModelError("", error);
}
}
if (ModelState.IsValid)
{
// No ModelState errors are available to send, so just return an empty BadRequest.
return BadRequest();
}
return BadRequest(ModelState);
}
return null;
}
private class ExternalLoginData
{
public string LoginProvider { get; set; }
public string ProviderKey { get; set; }
public string UserName { get; set; }
public IList<Claim> GetClaims()
{
IList<Claim> claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.NameIdentifier, ProviderKey, null, LoginProvider));
if (UserName != null)
{
claims.Add(new Claim(ClaimTypes.Name, UserName, null, LoginProvider));
}
return claims;
}
public static ExternalLoginData FromIdentity(ClaimsIdentity identity)
{
if (identity == null)
{
return null;
}
Claim providerKeyClaim = identity.FindFirst(ClaimTypes.NameIdentifier);
if (providerKeyClaim == null || String.IsNullOrEmpty(providerKeyClaim.Issuer)
|| String.IsNullOrEmpty(providerKeyClaim.Value))
{
return null;
}
if (providerKeyClaim.Issuer == ClaimsIdentity.DefaultIssuer)
{
return null;
}
return new ExternalLoginData
{
LoginProvider = providerKeyClaim.Issuer,
ProviderKey = providerKeyClaim.Value,
UserName = identity.FindFirstValue(ClaimTypes.Name)
};
}
}
private static class RandomOAuthStateGenerator
{
private static RandomNumberGenerator _random = new RNGCryptoServiceProvider();
public static string Generate(int strengthInBits)
{
const int bitsPerByte = 8;
if (strengthInBits % bitsPerByte != 0)
{
throw new ArgumentException("strengthInBits must be evenly divisible by 8.", "strengthInBits");
}
int strengthInBytes = strengthInBits / bitsPerByte;
byte[] data = new byte[strengthInBytes];
_random.GetBytes(data);
return HttpServerUtility.UrlTokenEncode(data);
}
}
#endregion
}
}
Edit 2: If I comment UnityConfig.RegisterComponents(); string in my WebApiConfig class registration works good.
Edit 3:
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
// e.g. container.RegisterType<ITestService, TestService>();
container.RegisterType<Data.Interfaces.IRepository, MemoryRepository>(new ContainerControlledLifetimeManager());
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}
}

CRUD Operations in MVC 5

I am developing an application in MVC 5 and perform CRUD operations on it.
I have successfully added Northwind database as an Entity Data Model and taking Customer in the Model. Now with the help of Scaffolding I generated the CustomersController.
When I create a new record in a Customer Table. There is no problem.
But when I click on that new record, Edit, Details and Delete are not working. After clicking any of these:
The following page occurs:
My Controller Code:
namespace MvcNorthwindSample.Controllers
{
public class CustomersController : Controller
{
private NORTHWNDEntities db = new NORTHWNDEntities();
// GET: Customers
public ActionResult Index()
{
return View(db.Customers.ToList());
}
// GET: Customers/Details/5
public ActionResult Details(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Customer customer = db.Customers.Find(id);
if (customer == null)
{
return HttpNotFound();
}
return View(customer);
}
// GET: Customers/Create
public ActionResult Create()
{
return View();
}
// POST: Customers/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "CustomerID,CompanyName,ContactName,ContactTitle,Address,City,Region,PostalCode,Country,Phone,Fax")] Customer customer)
{
if (ModelState.IsValid)
{
db.Customers.Add(customer);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(customer);
}
// GET: Customers/Edit/5
public ActionResult Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Customer customer = db.Customers.Find(id);
if (customer == null)
{
return HttpNotFound();
}
return View(customer);
}
// POST: Customers/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "CustomerID,CompanyName,ContactName,ContactTitle,Address,City,Region,PostalCode,Country,Phone,Fax")] Customer customer)
{
if (ModelState.IsValid)
{
db.Entry(customer).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(customer);
}
// GET: Customers/Delete/5
public ActionResult Delete(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Customer customer = db.Customers.Find(id);
if (customer == null)
{
return HttpNotFound();
}
return View(customer);
}
// POST: Customers/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(string id)
{
Customer customer = db.Customers.Find(id);
db.Customers.Remove(customer);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
My View Part:
My Create Code Result view while debugging:
EDIT: After you posted your controller:
Customer customer = db.Customers.Find(id);
if (customer == null)
{
return HttpNotFound();
}
Are you sure that you have a customer with an id of 1994? If not, your logic would return HttpNotFound().
In the screenshot you posted, I can read HTTP 404 error message and the requested URL was /Customer/Edit/1994.
So for that I assume you must be have the following controller/action:
public class CustomerController
{
public ActionResult Edit(int id)
{
return View();
}
}
Now the most common mistake most people make (including me) is properly passing id in the URL. You have id specified as an optional parameter in your route pattern:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
So if you don't want to use id you could pass something else as a key name in the the query component, e.g., /Customer/Edit?year=1994.
The error is a 404 Error.
It is looking in the Controller Customers for an Edit action.
Also pointed out in the comments the Id 1994 has a encoded space character following it. If the id is suppose to be strings, you can change the parameter to type string instead of int
public class CustomersController
{
public ActionResult Edit(int id)
{
return View();
}
}
I solved it. I changed the table at last. There is a problem on the table named Customers of the Northwind database. I download database backup file. The Customer ID column is adding a space as a default with the inserted value.
First create your models and Dbcontext.
public class TaskManagerContext : DbContext
{
public TaskManagerContext()
: base("TaskManagerDB")
{
}
public DbSet<User> Users { get; set; }
public DbSet<Task> Tasks { get; set; }
}
Then allow migrations and update the database from the PM. Create a folder Repositories with a BaseRepo that the rest must inherit.
public class BaseRepository<T> where T:BaseModel, new()
{
protected TaskManagerContext context;
protected DbSet<T> dbSet;
public BaseRepository()
{
this.context = new TaskManagerContext();
this.dbSet = this.context.Set<T>();
}
public void Insert(T item)
{
this.dbSet.Add(item);
this.context.SaveChanges();
}
public void Update(T item)
{
this.context.Entry(item).State = EntityState.Modified;
this.context.SaveChanges();
}
public void Delete(int id)
{
this.dbSet.Remove(this.dbSet.Find(id));
this.context.SaveChanges();
}
public IEnumerable<T> GetAll()
{
return this.dbSet;
}
}
like this:
public class UsersRepository : BaseRepository<User>
{
public UsersRepository()
: base()
{
}
}
Then you create the controllers in which you use the methods from the repos.
public class UsersController : Controller
{
//
// GET: /Users/
public ActionResult List()
{
List<User> users = new List<User>();
users = new UsersRepository().GetAll().ToList();
return View(users);
}
public ActionResult Edit(int id)
{
User user = new UsersRepository().GetAll().FirstOrDefault(u => u.ID == id);
return View(user);
}
[HttpPost]
public ActionResult Edit(User user)
{
UsersRepository repo = new UsersRepository();
repo.Update(user);
return RedirectToAction("List");
}
public ActionResult Delete(int id)
{
UsersRepository repo = new UsersRepository();
repo.Delete(id);
return RedirectToAction("List");
}
public ActionResult Create()
{
User u = new User();
return View(u);
}
[HttpPost]
public ActionResult Create(User user)
{
UsersRepository repo = new UsersRepository();
repo.Insert(user);
return RedirectToAction("List");
}
}
The actions for the TaskContr are simillar exept the List in which you connect the 2 models by ID:
public ActionResult List(int? id)
{
TasksRepository repo = new TasksRepository();
List<Task> tasks = new List<Task>();
tasks = repo.GetAll().Where(t => t.UserID == id).ToList();
return View(tasks);
}
Don't forget to generate views(on the Get methods) and change the List view for the Users:
#Html.ActionLink("Details", "List", "Tasks", new { id=item.ID }, null) |
That way when clicking Details you can see the tasks for that user.
public ActionResult Index()
{
using (DevExam db = new DevExam())
{
var intern = from m in db.Interns
select m;
return View(intern.ToList());
}
/* using (DevExam db = new DevExam())
{
var interns = db.Interns
.Include(s => s.InternID)
.Select(s => new Intern
{
InternID = s.InternID,
lname = s.lname,
fname = s.fname
});
return View(interns);
}
*/
}
// GET: CRUD/Details/5
public ActionResult Details(int id)
{
using (DevExam db = new DevExam())
{
return View(db.Interns.Where(x => x.InternID == id).FirstOrDefault());
}
}
// GET: CRUD/Create
public ActionResult Create()
{
return View();
}
// POST: CRUD/Create
[HttpPost]
public ActionResult Create(Intern intern)
{
try
{
// TODO: Add insert logic here
using (DevExam db = new DevExam())
{
db.Interns.Add(intern);
db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
// GET: CRUD/Edit/5
public ActionResult Edit(int id)
{
using (DevExam db = new DevExam())
{
return View(db.Interns.Where(x => x.InternID == id).FirstOrDefault());
}
}
// POST: CRUD/Edit/5
[HttpPost]
public ActionResult Edit(int id,Intern intern)
{
try
{
// TODO: Add update logic here
using (DevExam db = new DevExam())
{
db.Entry(intern).State = EntityState.Modified;
db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
// GET: CRUD/Delete/5
public ActionResult Delete(int id)
{
using (DevExam db = new DevExam())
{
return View(db.Interns.Where(x => x.InternID == id).FirstOrDefault());
}
}
// POST: CRUD/Delete/5
[HttpPost]
public ActionResult Delete(int id, FormCollection collection)
{
try
{
// TODO: Add delete logic here
using (DevExam db = new DevExam())
{
Intern intern = db.Interns.Where(x => x.InternID == id).FirstOrDefault();
db.Interns.Remove(intern);
db.SaveChanges();
}
return RedirectToAction("Index");
}
catch
{
return View();
}
}
create table tblemployee(
EmpId int NOT NULL identity(1,1),
EmpName varchar(100),
PhoneNumber varchar(10),
Country int,
State int,
maritalstetus varchar(50),
isvoting varchar(50),
dob datetime,
doj datetime
primary key (EmpId)
)
create table tblCountry(
Id int NOT NULL identity(1,1),
Name varchar(100),
primary key (Id)
)
insert into tblCountry(Name) values ('India')
insert into tblCountry(Name) values ('US')
insert into tblCountry(Name) values ('UK')
create table tblstate(
Id int NOT NULL identity(1,1),
Name varchar(100),
countryId int,
primary key (Id)
)
insert into tblstate(Name ,countryId) values ('Delhi',1)
insert into tblstate(Name , countryId) values ('Bihar' ,1)
insert into tblstate(Name , countryId) values ('Up',1)
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Xml.Linq;
namespace webTest.Models
{
public class Employee
{
public int id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string PhoneNumber { get; set; }
[Required]
public int Country { get; set; }
[Required]
public int State { get; set; }
[Required]
public bool MarritalStatus { get; set; }
public bool IsVoting { get; set; }
[Required]
[DataType(DataType.Date)]
public DateTime DOB { get; set; }
[Required]
[DataType(DataType.Date)]
public DateTime DOJ { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using webTest.Models;
namespace webTest.Controllers
{
public class EmpController : Controller
{
// GET: Emp
public static string constr = "Data Source=DIVYANSHU;Initial Catalog=EmployeeData;Integrated Security=True";
SqlConnection conn = new SqlConnection(constr);
public ActionResult ViewList()
{
List<Employee> employees = new List<Employee>();
try
{
conn.Open();
string sqlquery = "select * from tblEmployee";
SqlCommand cmd = new SqlCommand(sqlquery, conn);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Employee emp = new Employee()
{
id = Convert.ToInt32(dr["Empid"].ToString().Trim()),
Name = dr["EmpName"].ToString(),
PhoneNumber = dr["PhoneNumber"].ToString(),
Country = Convert.ToInt32(dr["Country"].ToString().Trim()),
State = Convert.ToInt32(dr["State"].ToString().Trim()),
MarritalStatus = Convert.ToBoolean(dr["maritalstetus"].ToString().Trim()),
IsVoting = Convert.ToBoolean(dr["isvoting"]),
DOB = Convert.ToDateTime(dr["dob"].ToString().Trim()),
DOJ = Convert.ToDateTime(dr["doj"].ToString().Trim()),
};
employees.Add(emp);
}
conn.Close();
}
catch (Exception ex)
{
}
return View(employees);
}
public ActionResult Create()
{
SqlDataAdapter _da = new SqlDataAdapter("Select * From tblCountry", constr);
DataTable _dt = new DataTable();
_da.Fill(_dt);
ViewBag.Country = ToSelectList(_dt, "Id", "Name");
_da.Dispose();
SqlDataAdapter _da1 = new SqlDataAdapter("Select * From tblState", constr);
DataTable _dt1 = new DataTable();
_da1.Fill(_dt1);
ViewBag.State = ToSelectList(_dt1, "Id", "Name");
_da1.Dispose();
Employee emp = new Employee();
return View(emp);
}
public SelectList ToSelectList(DataTable table, string valueField, string textField)
{
List<SelectListItem> list = new List<SelectListItem>();
foreach (DataRow row in table.Rows)
{
list.Add(new SelectListItem()
{
Text = row[textField].ToString(),
Value = row[valueField].ToString()
});
}
return new SelectList(list, "Value", "Text");
}
[HttpPost]
public ActionResult Create(Employee empmodel)
{
List<Employee> employees = new List<Employee>();
try
{
conn.Open();
string sqlquery = "insert into tblEmployee(EmpName,PhoneNumber,Country,State,maritalstetus,isvoting,dob,doj) values('" + empmodel.Name + "','" + empmodel.PhoneNumber + "'," + empmodel.Country + "," + empmodel.State + ",'" + empmodel.MarritalStatus + "','" + empmodel.IsVoting + "','" + empmodel.DOB + "','" + empmodel.DOJ + "')";
SqlCommand cmd = new SqlCommand(sqlquery, conn);
cmd.ExecuteNonQuery();
conn.Close();
employees = listEmployee();
}
catch (Exception ex)
{
}
return View("ViewList", employees);
}
public ActionResult Edit(int id)
{
Employee emp = new Employee();
try
{
SqlDataAdapter _da = new SqlDataAdapter("Select * From tblCountry", constr);
DataTable _dt = new DataTable();
_da.Fill(_dt);
ViewBag.Country = ToSelectList(_dt, "Id", "Name");
_da.Dispose();
SqlDataAdapter _da1 = new SqlDataAdapter("Select * From tblState", constr);
DataTable _dt1 = new DataTable();
_da1.Fill(_dt1);
ViewBag.State = ToSelectList(_dt1, "Id", "Name");
_da1.Dispose();
conn.Open();
string sqlquery = "select * from tblemployee where empid=" + id + "";
SqlCommand cmd = new SqlCommand(sqlquery, conn);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
emp = new Employee()
{
id = Convert.ToInt32(dr["Empid"].ToString().Trim()),
Name = dr["EmpName"].ToString(),
PhoneNumber = dr["PhoneNumber"].ToString(),
Country = Convert.ToInt32(dr["Country"].ToString().Trim()),
State = Convert.ToInt32(dr["State"].ToString().Trim()),
MarritalStatus = Convert.ToBoolean(dr["maritalstetus"].ToString().Trim()),
IsVoting = Convert.ToBoolean(dr["isvoting"]),
DOB = Convert.ToDateTime(dr["dob"].ToString().Trim()),
DOJ = Convert.ToDateTime(dr["doj"].ToString().Trim()),
};
}
conn.Close();
}
catch (Exception ex)
{
}
return View(emp);
}
[HttpPost]
public ActionResult Edit(Employee empmodel)
{
try
{
conn.Open();
string sqlquery = "update tblEmployee set EmpName='" + empmodel.Name + "',PhoneNumber='" + empmodel.PhoneNumber + "',Country=" + empmodel.Country + ",State=" + empmodel.State + ",maritalstetus='" + empmodel.MarritalStatus + "',isvoting='" + empmodel.IsVoting + "',dob='" + empmodel.DOB + "',doj='" + empmodel.DOJ + "' where empid=" + empmodel.id + "";
SqlCommand cmd = new SqlCommand(sqlquery, conn);
cmd.ExecuteNonQuery();
conn.Close();
}
catch (Exception ex)
{
}
List<Employee> list = listEmployee();
return View("ViewList", list);
}
public ActionResult Delete(int id)
{
try
{
conn.Open();
string sqlquery = "Delete from tblEmployee where empid=" + id + "";
SqlCommand cmd = new SqlCommand(sqlquery, conn);
cmd.ExecuteNonQuery();
conn.Close();
}
catch (Exception ex)
{
}
List<Employee> list = listEmployee();
return View("ViewList", list);
}
public List<Employee> listEmployee()
{
List<Employee> employees = new List<Employee>();
conn.Open();
string sqlquery = "select * from tblEmployee";
SqlCommand cmd = new SqlCommand(sqlquery, conn);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Employee emp = new Employee()
{
id = Convert.ToInt32(dr["Empid"].ToString().Trim()),
Name = dr["EmpName"].ToString(),
PhoneNumber = dr["PhoneNumber"].ToString(),
Country = Convert.ToInt32(dr["Country"].ToString().Trim()),
State = Convert.ToInt32(dr["State"].ToString().Trim()),
MarritalStatus = Convert.ToBoolean(dr["maritalstetus"].ToString().Trim()),
IsVoting = Convert.ToBoolean(dr["isvoting"]),
DOB = Convert.ToDateTime(dr["dob"].ToString().Trim()),
DOJ = Convert.ToDateTime(dr["doj"].ToString().Trim()),
};
employees.Add(emp);
}
conn.Close();
return employees;
}
}
}
//in Edit view and in create view replace edit for to
#Html.DropDownListFor(model => model.Country, ViewBag.Country as SelectList, new { #class = "form-control" })
#Html.DropDownListFor(model => model.State, ViewBag.State as SelectList, new { #class = "form-control" })

Resources