Unit testing file upload fails - asp.net-mvc

I have an action that inserts a file in a database. It works fine. But the unit test fails when the insert is successful. The RedirectToRouteResult is null. This is the code for the action:
[HttpPost]
public ActionResult FileUpload(FileUploadViewModel model)
{
try
{
if (ModelState.IsValid)
{
var uploadFile = new byte[model.File.InputStream.Length];
model.File.InputStream.Read(uploadFile, 0, uploadFile.Length);
//var file = new FilesUpload();
var fileExt = Path.GetExtension(model.File.FileName);
if (fileExt == ".txt" || fileExt == ".docx")
{
//file.FileName = model.File.FileName;
//file.FileSize = model.File.ContentLength;
//file.ContentType = fileExt;
//file.FileData = uploadFile;
//file.UploadedOn = DateTime.Now;
//var user = _userRepository.GetUserId(User.Identity.Name);
//file.UserId = user.UserId;
bool result = _userRepository.UploadFile(model, User.Identity.Name, fileExt, uploadFile);
//file.User = (from u in _context.Users where u.UserId == 29 select u).FirstOrDefault();
//_context.FilesUploads.Add(file);
//int result = _context.SaveChanges();
if (result)
{
return RedirectToAction("Index");
}
else
{
ModelState.AddModelError("", "An error occured");
return View(model);
}
}
else
{
ModelState.AddModelError("", "You can upload only files with extensions .txt and .docx");
}
}
return View(model);
}
catch (Exception ex)
{
throw(ex);
}
}
And this is the code for the unit test:
private SuperUserController _controller;
private Mock<IUserRepository> _repositoryMock;
private Mock<IIntrinsicObjects> _intrinsicMock;
private Mock<ControllerContext> _contextMock;
private string username = "test#abv.bg";
private FileUploadViewModel _fileUpload;
[SetUp]
public void Setup()
{
_fileUpload = new FileUploadViewModel();
_repositoryMock = new Mock<IUserRepository>();
_intrinsicMock = new Mock<IIntrinsicObjects>();
_contextMock = new Mock<ControllerContext>();
_contextMock.SetupGet(c => c.HttpContext.User.Identity.Name).Returns(username);
_contextMock.SetupGet(c => c.HttpContext.User.Identity.IsAuthenticated).Returns(true);
_controller = new SuperUserController(_repositoryMock.Object, _intrinsicMock.Object);
_controller.ControllerContext = _contextMock.Object;
}
[Test]
public void FileUpload_ShouldRedirectToIndexOnSuccess()
{
string filePath = Path.GetFullPath(#"C:\Users\Test\Desktop\test.txt");
var fileStream = new FileStream(filePath, FileMode.Open);
var fileExt = Path.GetExtension(filePath);
var fileToUpload = new Mock<HttpPostedFileBase>();
fileToUpload.Setup(f => f.ContentLength).Returns(10);
fileToUpload.Setup(f => f.FileName).Returns("test.txt");
fileToUpload.Setup(f => f.ContentType).Returns(fileExt);
fileToUpload.Setup(f => f.InputStream).Returns(fileStream);
//var model = new FileUploadViewModel();
_fileUpload.File = fileToUpload.Object;
var fileData = new byte[fileToUpload.Object.InputStream.Length];
_repositoryMock.Setup(m => m.UploadFile(_fileUpload, _controller.ControllerContext.HttpContext.User.Identity.Name, fileToUpload.Object.ContentType, fileData)).Returns(true);
var result = _controller.FileUpload(_fileUpload) as RedirectToRouteResult;
Assert.IsNotNull(result);
}
The problem is that UploadFile always returns false.
I will be very grateful if somebody helps me.

Your controller action creates a new array with the file data:
var uploadFile = new byte[model.File.InputStream.Length];
That is never going to match the fileData argument set on the UploadFile of your _repositoryMock:
_repositoryMock.Setup(m => m.UploadFile(_fileUpload, _controller.ControllerContext.HttpContext.User.Identity.Name, fileToUpload.Object.ContentType, fileData)).Returns(true);
By default the array will match by reference, not if the contents are the same. As the controller creates a new instance, uploadFile is a different reference than fileData.
You want to setup moq so when the expected data array is submitted your UploadFile function returns true. For that you can use an custom matcher that matches all elements in an enumerable:
public T[] MatchCollection<T>(T[] expectation)
{
//This checks all elements in input are find in destination, regardless of order or duplicates
return Match.Create<T[]>(inputCollection => (expectation.All((i) => inputCollection.Contains(i))));
//This will check the arrays are exactly the same
return Match.Create<T[]>(inputCollection => StructuralComparisons.StructuralEqualityComparer.Equals(inputCollection, expectation) );
}
And setup your mock using that matcher for the data array:
_repositoryMock.Setup(m => m.UploadFile(_fileUpload, _controller.ControllerContext.HttpContext.User.Identity.Name, fileToUpload.Object.ContentType, MatchCollection(fileData))).Returns(true);
Hope it helps!
EDIT
I have tried with the following test based on your code that passes a valid array data to the mock setup and doesn´t need to actually read a file in the unit test:
public void FileUpload_ShouldRedirectToIndexOnSuccess()
{
var fileData = UTF8Encoding.UTF8.GetBytes("This is a test");
var fileStream = new MemoryStream(fileData);
var fileToUpload = new Mock<HttpPostedFileBase>();
fileToUpload.Setup(f => f.ContentLength).Returns((int)fileStream.Length);
fileToUpload.Setup(f => f.FileName).Returns("test.txt");
fileToUpload.Setup(f => f.ContentType).Returns("txt");
fileToUpload.Setup(f => f.InputStream).Returns(fileStream);
_fileUpload.File = fileToUpload.Object;
_repositoryMock
.Setup(m => m.UploadFile(_fileUpload, username, ".txt", MatchCollection(fileData)))
.Returns(true);
var result = _controller.FileUpload(_fileUpload) as RedirectToRouteResult;
Assert.IsNotNull(result);
}

This is the final version of the test:
[Test]
public void FileUpload_ShouldRedirectToIndexOnSuccess()
{
string filePath = Path.GetFullPath(#"C:\Users\Yordanka\Desktop\test.txt");
var fileStream = new FileStream(filePath, FileMode.Open);
var fileExt = Path.GetExtension(filePath);
var testarray = new byte[414];
var fileToUpload = new Mock<HttpPostedFileBase>();
fileToUpload.Setup(f => f.ContentLength).Returns(414);
fileToUpload.Setup(f => f.FileName).Returns("test.txt");
fileToUpload.Setup(f => f.ContentType).Returns(fileExt);
fileToUpload.Setup(f => f.InputStream).Returns(fileStream);
fileToUpload.Setup(f => f.InputStream.Length).Returns(testarray.Length);
_fileUpload.File = fileToUpload.Object;
var fileData = new byte[414];
_fileUpload.File.InputStream.Read(fileData, 0, fileData.Length);
_repositoryMock.Setup(
m =>
m.UploadFile(_fileUpload, _controller.ControllerContext.HttpContext.User.Identity.Name,
fileToUpload.Object.ContentType, MatchCollection(fileData))).Returns(true);
var result = _controller.FileUpload(_fileUpload) as RedirectToRouteResult;
Assert.IsNotNull(result);
Assert.AreEqual("Index", result.RouteValues["Action"]);
Assert.AreEqual("SuperUser", result.RouteValues["Controller"]);
}
Once again, thank you Daniel J.G.!!!

Related

Using a string to call a table in Entity Framework

Here's my old code.
public override Task ExecuteAsync(string generator, WebHookHandlerContext context)
{
DatawarehouseEntities db = new DatawarehouseEntities();
// Get JSON from WebHook
JObject data = context.GetDataOrDefault<JObject>();
var tableName = data["Table_Name"].ToString();
var columnNames = db.Database.SqlQuery<string>(String.Format("SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('{0}'); ", tableName)).ToList();
var table = db.GetType().GetProperty(tableName).GetValue(db, null);
var assembly = AppDomain.CurrentDomain.GetAssemblies()
.SingleOrDefault(a => a.GetName().Name == "DSI.Data");
var type = assembly.GetTypes().FirstOrDefault(t => t.Name == tableName);
var dbset = Activator.CreateInstance(type);
//var dbset = db.Set(type);
var jsonParams = data.Properties().Select(x => x.Name).ToList();
var selectedColumnNames = columnNames.Intersect(jsonParams);
foreach (var columnName in selectedColumnNames)
{
var property = dbset.GetType().GetProperties().FirstOrDefault(x => x.Name == columnName);
property.SetValue(dbset, data[columnName].ToString(), null);
}
db.Set(type).Add(dbset);
db.SaveChanges();
return Task.FromResult(true);
}
Here's what I try to post http://localhost:port/api/webhooks/incoming/genericjson?code=secret&Table_Name=Table_Name. The type always comes back null. How can I select a table using the string that I pass in?
To make this easier, faster and less error-prone enumerate your entity types and add them to a lookup. EG
public static Dictionary<string, Type> EntityTypesByName { get; } = new Dictionary<string, Type>();
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
foreach (var et in modelBuilder.Model.GetEntityTypes())
{
EntityTypesByName.Add(et.Name, et.ClrType);
}
}
This is what finally worked for me.
public override Task ExecuteAsync(string generator, WebHookHandlerContext context)
{
DatawarehouseEntities db = new DatawarehouseEntities();
// Get JSON from WebHook
JObject data = context.GetDataOrDefault<JObject>();
var tableName = data["Table_Name"].ToString();
var columnNames = db.Database.SqlQuery<string>(String.Format("SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('{0}'); ", tableName)).ToList();
var table = db.GetType().GetProperty(tableName).GetValue(db, null);
var assembly = AppDomain.CurrentDomain.GetAssemblies()
.SingleOrDefault(a => a.GetName().Name == "DSI.Data");
var type = assembly.GetTypes().FirstOrDefault(t => t.Name == tableName);
var dbset = Activator.CreateInstance(type);
var jsonParams = data.Properties().Select(x => x.Name).ToList();
var selectedColumnNames = columnNames.Intersect(jsonParams);
foreach (var columnName in selectedColumnNames)
{
var property = dbset.GetType().GetProperties().FirstOrDefault(x => x.Name == columnName);
property.SetValue(dbset, data[columnName].ToString(), null);
}
db.Set(type).Add(dbset);
db.SaveChanges();
return Task.FromResult(true);
}

ASP.NET & Angular 7:POST a picture into database

I'm trying to upload an image using an API but the same error shows every time:
"Error reading bytes. Unexpected token: StartObject. Path 'picture'"
the picture is declared as a byte[] in the ASP.NET entity
and I use the formdata to post the picture in angular
Angular code:
onFileChanged(event) {
this.selectedFile = event.target.files[0]
}
adduser() {
this.fd = new FormData();
this.fd.append('picture', this.selectedFile)
this.user.firstname = this.firstname;
this.user.lastname = this.lastname;
this.user.password = this.pass;
this.user.userName = this.email;
this.user.type = this.role;
this.user.picture = this.fd;
alert(this.user.picture)
this.auth.adduser(this.user).subscribe(Response => {
console.log(Response);
this.route.navigate(['login']);
}, error => {
console.log(error)
});
}
.Net code:
[HttpPost]
public async Task < Object > PostAdmin([FromBody] UserModel model) {
{
var profile = new Profile() {
UserName = model.UserName,
lastname = model.lastname,
address = model.address,
firstname = model.firstname,
picture = model.picture,
phone = model.phone,
university = model.university,
Type = model.Type
};
using(var stream = new MemoryStream()) {
profile.picture = stream.ToArray();
}
var user = await _userManager.FindByNameAsync(profile.UserName);
if (user != null) {
return Ok(new {
status = false
});
}
try {
var result = await _userManager.CreateAsync(profile, model.Password);
var role = await _userManager.AddToRoleAsync(profile, model.Type);
return Ok(result);
}
catch (Exception e) {
return BadRequest(new {
status = false, message = e.Message
});
}

How to mock the Request.form for only a few values on Controller in ASP.Net MVC?

I am new to Nunit and Moq framework and am totally stuck in testing for one of my controller as it fetches some of the values from Request.Form["Something"]. I am able to test for the other part of the controller method using nunit but the code is breaking wherever Request.form values are fetched in the same controller.
Below is the test controller code using nunit and Moq:
[Test]
public void SaveRequest()
{
TestController test = new TestController();
TestModel model = new TestModel();
model = PopulateRequestModel();
Mail = model.Mail;
HttpContext.Current = new HttpContext(new HttpRequest("", "https://localhost", ""), new HttpResponse(new System.IO.StringWriter()));
System.Web.SessionState.SessionStateUtility.AddHttpSessionStateToContext(HttpContext.Current, new HttpSessionStateContainer("", new SessionStateItemCollection(), new HttpStaticObjectsCollection(), 20000, true, HttpCookieMode.UseCookies, SessionStateMode.InProc, false));
System.Web.HttpContext.Current.Session["__RequestVerificationTokenError"] = false;
var httpContext1 = (new Mock<HttpContextBase>());
var routeData = new RouteData();
httpContext1.Setup(c => c.Request.RequestContext.RouteData).Returns(routeData);
httpContext1.Setup(c => c.Request.Form).Returns(delegate()
{
var nv = new NameValueCollection();
nv.Add("Firstname", "Dave");
nv.Add("LastName", "Smith");
nv.Add("Email", "jsmith#host.com");
nv.Add("Comments", "Comments are here...");
nv.Add("ReceiveUpdates", "true");
return nv;
});
if (LoggedInEnterpriseId != null)
{
ViewResult result = test.SaveRequest(model, mail) as ViewResult;
Assert.IsNotNull(result);
}
}
PopulateRequestModel :
private RequestModel PopulateRequestModel ()
{
RequestModel model = new RequestModel ();
model.Firstname = "Dave";
model.LastName = "Smith";
model.Email = "jsmith#host.com";
model.Comments = "Comments are here...";
model.ReceiveUpdates = true;
return model;
}
Below is the actual controller method to be tested :
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SaveRequest(TestModel model, HttpPostedFileBase Mail)
{
string Name = Request.Form["Firstname"].ToString();
model.Mail = Mail;
//Start Adding Request to DB
Logger.Write("Start: Adding new request..");
try
{
using (db = new DatabaseContext())
{
NewRequest newRequest = new NewRequest();
if (RequestNumber != 0)
{
newRequest.Name = Convert.ToInt16(Request.Form["Firstname"]);
newRequest.LastName = Request.Form["LastName"];
newRequest.Email = Request.Form["Email"];
newRequest.Comments = Request.Form["Comments"];
newRequest.ReceiveUpdates = Convert.ToBoolean(Request.Form["ReceiveUpdates"]);
}
else
{
newRequest.Name = model.Firstname;
newRequest.LastName = model.LastName;
newRequest.Email = model.Email;
newRequest.Comments = model.Comments;
newRequest.ReceiveUpdates = model.ReceiveUpdates;
}
db.NewRequests.Add(newRequest);
int save = db.SaveChanges();
}
The code is getting blocked wherever request.form is used.

Error while running unit test on ASP.Net MVC registraton code which uses ASP.Net Identity

I am new to ASP.Net MVC and Identity.
I have following unit test method.
[TestMethod]
public void SignUp()
{
try
{
var dummyUser = new ApplicationUser() { UserName = "xyz", Email = "xyz#gmail.com" };
ViewModels.RegisterViewModel rvm = new ViewModels.RegisterViewModel { Name = "abc", Email = "abc#yahoo.com", Password = "123456" };
var store = new Mock<IUserStore<ApplicationUser>>();
store.As<IUserPasswordStore<ApplicationUser>>()
.Setup(x => x.FindByIdAsync(It.IsAny<string>()))
.ReturnsAsync(new ApplicationUser() { Id = "id" });
store.Setup(x => x.CreateAsync(dummyUser)).Returns(Task.FromResult(IdentityResult.Success));
store.As<IUserRoleStore<ApplicationUser>>().Setup(x => x.AddToRoleAsync(It.IsAny<ApplicationUser>(), It.IsAny<string>())).Returns(Task.FromResult(IdentityResult.Success));
store.As<IUserRoleStore<ApplicationUser>>().Setup(x => x.IsInRoleAsync(It.IsAny<ApplicationUser>(), It.IsAny<string>())).ReturnsAsync(true);
store.As<IRoleStore<IdentityRole>>().Setup(x => x.CreateAsync(new IdentityRole("I"))).Returns(Task.FromResult(IdentityResult.Success));
//var roleStore = new Mock<IRoleStore<IdentityRole>>();
//roleStore.As<IRoleStore<IdentityRole>>();
//roleStore.Setup(x => x.CreateAsync(new IdentityRole("I"))).Returns(Task.FromResult(IdentityResult.Success));
//var testRoleManager = new ApplicationRoleManager(roleStore.Object);
//to register usertokenprovider as it is needed to send confirmation email
var provider = new Microsoft.Owin.Security.DataProtection.DpapiDataProtectionProvider("Sample");
var testUserManager = new ApplicationUserManager(store.Object);
testUserManager.UserTokenProvider =new DataProtectorTokenProvider<ApplicationUser>(provider.Create("ASP.NET Identity"));
// mocking IAuthenticationManager
var mockAuthenticationManager = new Mock<IAuthenticationManager>();
mockAuthenticationManager.Setup(am => am.SignOut());
mockAuthenticationManager.Setup(am => am.SignIn());
//mocking Context
var routes = new System.Web.Routing.RouteCollection();
ProChartSiteMVC.RouteConfig.RegisterRoutes(routes);
var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
request.SetupGet(x => x.ApplicationPath).Returns("/");
request.SetupGet(x => x.Url).Returns(new Uri("http://localhost:1431/a", UriKind.Absolute));
request.SetupGet(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection());
var response = new Mock<HttpResponseBase>(MockBehavior.Strict);
response.Setup(x => x.ApplyAppPathModifier("/post1")).Returns("http://localhost:1431/post1");
var context = new Mock<HttpContextBase>(MockBehavior.Strict);
context.SetupGet(x => x.Request).Returns(request.Object);
context.SetupGet(x => x.Response).Returns(response.Object);
var testSignInManager = new ApplicationSignInManager(testUserManager,mockAuthenticationManager.Object);
BussinessLayer bussinessLayer = new BussinessLayer(db);
AccountController controller = new AccountController(testUserManager,testSignInManager, bussinessLayer);
var UrlHelperMock = new Mock<UrlHelper>();
controller.Url = UrlHelperMock.Object;
controller.ControllerContext = new ControllerContext(context.Object, new System.Web.Routing.RouteData(), controller);
var result = controller.SignUp(rvm) as Task<ActionResult>;
var viewresult = result.Result;
Assert.IsNotNull(result);
}
catch (Exception ex) { string str = ex.ToString(); }
}
Original SignUp method which works fine when I run it debug mode but gives error if executed from unit test.
[HttpPost]
public async Task<ActionResult> SignUp(RegisterViewModel rvm)
{
if (ModelState.IsValid)
{
var appUser = new ApplicationUser();
appUser.UserName = bLayer.GenerateInvestarID(rvm.Email);
appUser.Email = rvm.Email;
appUser.Name = rvm.Name;
appUser.LockoutEnabled = true;
appUser.InstituteCode = "10";
try
{
var result = await UserManager.CreateAsync(appUser, rvm.Password);
if (result.Succeeded)
{
IdentityResult addResult = await UserManager.AddToRoleAsync(appUser.Id, "I");
await SignInManager.SignInAsync(appUser, isPersistent: false, rememberBrowser: false);
string code = await UserManager.GenerateEmailConfirmationTokenAsync(appUser.Id);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = appUser.Id, code = code }, protocol: Request.Url.Scheme);
await UserManager.SendEmailAsync(appUser.Id, "Confirm your account", "Please confirm your account by clicking here");
return RedirectToAction("Thankyou");
}
else
{
AddErrors(result);
return PartialView("_PartialSignUp", rvm);
}
}
catch(Exception ex)
{
ModelState.AddModelError("CredentialError", ex.Message);
return PartialView("_PartialSignUp", rvm);
}
}
else
{
ModelState.AddModelError("CredentialError", "Invalid Details");
return PartialView("_PartialSignUp", rvm);
}
}
I get following error while IdentityResult addResult = await UserManager.AddToRoleAsync(appUser.Id, "I") is executed from above code through unit test.
System.NullReferenceException was caught
_HResult=-2147467261
_message=Object reference not set to an instance of an object.
HResult=-2147467261
IsTransient=false
Message=Object reference not set to an instance of an object.
Source=Microsoft.AspNet.Identity.Core
StackTrace:
at Microsoft.AspNet.Identity.UserManager`2.<AddToRoleAsync>d__83.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at SiteMVC.Controllers.AccountController.<SignUp>d__0.MoveNext()
What is going wrong here which causes above error.
To me it looks like you need to Setup result for IUserStore.GetRolesAsync method.
UserManager.AddToRoleAsync method calls IUserStore.GetRolesAsync and calls 'Contains' method on the returned collection of the roles.
Since there is no result is setup for this method in unit test it returns null as the default which caused this exception to happen.
Following is the code I have setup the result for IUserStore.GetRolesAsync to return empty list of roles.
[TestMethod]
public void SignUp()
{
try
{
var dummyUser = new ApplicationUser() { UserName = "xyz", Email = "xyz#gmail.com" };
ViewModels.RegisterViewModel rvm = new ViewModels.RegisterViewModel { Name = "abc", Email = "abc#yahoo.com", Password = "123456" };
var store = new Mock<IUserStore<ApplicationUser>>();
var roles = new List<string>(); // Populate this list as per your need.
store.As<IUserPasswordStore<ApplicationUser>>()
.Setup(x => x.FindByIdAsync(It.IsAny<string>()))
.ReturnsAsync(new ApplicationUser() { Id = "id" });
store.Setup(x => x.CreateAsync(dummyUser)).Returns(Task.FromResult(IdentityResult.Success));
//Setting up the result for GetRoleAsync method to return roles collection.
store.As<IUserRoleStore<ApplicationUser>>().Setup(x => x.GetRolesAsync(It.IsAny<ApplicationUser>())).ReturnsAsync(roles);
//Rest of the unit test code
}
catch (Exception ex) { string str = ex.ToString(); }
}

Delete a context record from grid in kendo UI using LINQ

Hi Im using kendo ui grid in my project.
This is my code to insert records in database.
public static void Insert(StudentViewModel student)
{
student.StudentId = All().OrderByDescending(p => p.StudentId).First().StudentId + 1;
//All().Insert(0, student);
UniRegEntities uniRegEntities = new UniRegEntities();
Student stu =new Student();
stu.FName = student.FirstName;
stu.LName = student.LastName;
stu.Gender = uniRegEntities.Genders.Where(x => x.Title == student.Gender).FirstOrDefault();
stu.Id = student.StudentId;
uniRegEntities.Students.Add(stu);
uniRegEntities.SaveChanges();
}
And this is my update statement.
public static void Update(StudentViewModel student)
{
UniRegEntities context = new UniRegEntities();
var studentToUpdate = context.Students.Where(x => x.Id == student.StudentId).FirstOrDefault();
studentToUpdate.FName = student.FirstName;
studentToUpdate.LName = student.LastName;
studentToUpdate.Gender = context.Genders.Where(x => x.Title == student.Gender).FirstOrDefault();
context.SaveChanges();
}
Anyone can suggest me the delete method?
You can either get an entity from the DB and then delete it or create one and then delete it.
So:
var e = // Get
ctx.DeleteObject(e);
ctx.SaveChanges();
or
var e = new Foo() { FooId = id };
ctx.Entity.Attach(e);
ctx.DeleteObject(e);
ctx.SaveChanges();
Applied to your situation:
You are getting a record so you want to use DeleteObject()
public static void Update(StudentViewModel student)
{
UniRegEntities context = new UniRegEntities();
var studentToDelete = context.Students.Where(x => x.Id == student.StudentId).FirstOrDefault();
context.Students.DeleteObject(studentToUpdate);
context.SaveChanges();
}
context.Students.Remove(context.students.Single(x=>x.Id==student.Id));
Can you please try with below code snippet?
using (var db= new AppContext(ConnectionStr))
{
try
{
con.Configuration.AutoDetectChangesEnabled = false;
var o = new Student { StudentId = student.StudentId };
db.Students.Attach(o);
db.Students.Remove(o);
db.SaveChanges();
}
catch (Exception ex)
{
throw new Exception(ex.InnerException.Message);
}
finally
{
con.Configuration.AutoDetectChangesEnabled = true;
}
}

Resources