Here we have a controller:
public class CollegeController : Controller
{
private ICollegeRepository repository;
public int pageSize = 10;
public CollegeController(ICollegeRepository repo)
{
repository = repo;
}
public ViewResult List(string region,
string area,
string localityType, int page = 1)
{
CollegeListViewModel model = new CollegeListViewModel
{
Colleges = repository.Colleges
.Where(p => (region == null || p.Area.Region.Name == region)
&& (localityType == null || p.LocalityType.Name == localityType))
.Where(p => area == null || p.Area.Name == area)
.OrderBy(college => college.CollegeId)
.Skip((page - 1) * pageSize)
.Take(pageSize),
PagingInfo = new PagingInfo
{
CurrentPage = page,
ItemsPerPage = pageSize,
TotalItems = ((region == null) && (localityType == null)) ?
repository.Colleges.Count() :
repository.Colleges.Where(college => college.Area.Region.Name == region)
.Where(college => college.Area.Name == area)
.Where(college => college.LocalityType.Name == localityType).Count()
},
CurrentLocalityType = localityType,
CurrentRegion = region,
CurrentArea = area,
};
return View(model);
}
}
The whole problem is that when you start if you pass the first region, and then localityType, everything is fine.
But if you try to pass localityType, when in the region passed null, localityType also sends null.
In other words, before sending localityType must pass region
How such to correct?
And Sorry for my English
Related
I am using this code for authorization on controllers.
with [Authorize(Policy = "CustomRole")]
The thing happened that after 3 or 4 request it fails with
A second operation started on this context before a previous operation completed
public class CustomRoleRequirement : AuthorizationHandler<CustomRoleRequirement>, IAuthorizationRequirement
{
public CMSContext _context = new CMSContext();
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomRoleRequirement requirement)
{
var routeobj = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext;
var c = routeobj.RouteData.Values.Values.ToList();
var keys = routeobj.RouteData.Values.Keys.ToList();
string area = "";
string id = "";
string controller = "";
string action = "";
string module = "";
foreach (var item in keys)
{
if (item=="area")
{
int indexs = keys.FindIndex(cc => cc == "area");
area = c[indexs].ToString();
}
else if (item == "id")
{
int indexs = keys.FindIndex(cc => cc == "id");
id = c[indexs].ToString();
}
else if (item == "controller")
{
int indexs = keys.FindIndex(cc => cc == "controller");
controller = c[indexs].ToString();
}
else if (item == "module")
{
int indexs = keys.FindIndex(cc => cc == "module");
module = c[indexs].ToString();
}
else if (item == "action")
{
int indexs = keys.FindIndex(cc => cc == "action");
action = c[indexs].ToString();
}
}
string modulelink = controller;
if (!string.IsNullOrEmpty(module))
{
modulelink = modulelink + "/" + module;
}
List<string> Roles = new List<string>();
int UserId = Auth.UserID;
string UserName = Auth.UserName;
if (UserName == "superadmin")
{
context.Succeed(requirement);
return Task.CompletedTask;
}
else
{
// apparently the error occurred here
var moduleobj = _context.AppModules.FirstOrDefault(q => q.Link == modulelink);
if (moduleobj != null)
{ // 69 role is assessing news module
//60 role is accessing page module
var RolesModulesobj = _context.AppRolesModules.FirstOrDefault(q => q.ModuleId == moduleobj.ModuleId && q.RolesId == Auth.RoleId);
if (RolesModulesobj != null)
{
string permissionsobj = RolesModulesobj.Permissions;
List<string> PermissionsListobj = permissionsobj.Split(',').Select(x => x.Trim()).ToList();
var FindFullAccess = PermissionsListobj.FirstOrDefault(q => q.Contains("FullAccess:true"));
if (FindFullAccess != null)
{
context.Succeed(requirement);
return Task.CompletedTask;
}
else
{
var abc = PermissionsListobj.FirstOrDefault(q => q.Contains(action + ":true"));
if (abc != null)
{
context.Succeed(requirement);
return Task.CompletedTask;
}
else
{
context.Fail();
return Task.CompletedTask;
}
}
}
}
}
The error occurred at this line above
var moduleobj = _context.AppModules.FirstOrDefault(q => q.Link == modulelink);
How can I make task wait before the second operation started in the method above?
You can't use a singleton DB context. You either create one each time you need one or you pool them.
I cant figured out how perform sort in a details page. I have a classic page with list of order and for each row i have a actionlink to return details view of that order.
i try this
public ActionResult Details(int? anno,int? nr, string centro, string sortOrder)
{
ViewBag.Codice = String.IsNullOrEmpty(sortOrder) ? "Articolo_desc" : "";
if (anno == null && nr == null && string.IsNullOrEmpty(centro))
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
else
{
string s = "anno=" + Request.QueryString["anno"] + "&nr=" + Request.QueryString["nr"] + "¢ro=" + Request.QueryString["centro"];
ViewBag.search = s.Replace("search=", "").Replace("%3D", "=");
}
var righe = from d in db.DETAILS
where d.Anno == anno && d.Num == nr && d.Centro == centro
select new DetailsOrdersView
{
Articolo = r.Codice,
...
};
if (righe == null)
return HttpNotFound();
switch(sortOrder)
{
case "Articolo_desc":
righe = righe.OrderByDescending(i => i.Articolo);
break;
default:
righe = righe.OrderBy(i => i.Articolo);
break;
}
return View(righe);
}
}
and in details view
#Html.ActionLink("codice","Details", new { sortOrder = ViewBag.Codice, ViewBag.search })
but i on sorting I get bad request and this is the route
Orders/Details?sortOrder=Articolo_desc&search=anno%3D2017%26nr%3D6%26centro%3D1
#Html.ActionLink("codice", "Details", new { sortOrder = ViewBag.Codice, anno = ViewBag.Anno, centro = ViewBag.Centro , nr= ViewBag.Numero })
i solved as above
I have an MVC 5 web app which talks to my class library for db needs and the class library uses Entity Framework 6 for that.
Below are 2 methods from the class library.
Both of them are initiating a new context. How do I make 'em use only one context instead, without using class level variable?
Also, if these 2 methods were to save stuff, context.SaveChanges(), how can I wrap them both into one transaction, even if the save happens in different classes?
public int FindUnknownByName(string name, string language)
{
using (var context = new ScriptEntities())
{
int languageId = this.FindLanguage(language);
var script = context.scripts.Where(l => l.Name == name && l.Unknown == true && l.LanguageId == languageId).FirstOrDefault();
if (script != null)
{
return script.Id;
}
return 0;
}
}
public int FindLanguage(string language)
{
using (var context = new ScriptEntities())
{
var lang = context.languages.Where(l => l.Name == language).FirstOrDefault();
if (lang != null)
{
return lang.Id;
}
return 0;
}
}
Make the context a private class variable.
private ScriptEntities context = new ScriptEntities()
public int FindUnknownByName(string name, string language)
{
int languageId = this.FindLanguage(language);
var script = context.scripts.Where(l => l.Name == name && l.Unknown == true && l.LanguageId == languageId).FirstOrDefault();
if (script != null)
{
return script.Id;
}
return 0;
}
public int FindLanguage(string language)
{
var lang = context.languages.Where(l => l.Name == language).FirstOrDefault();
if (lang != null)
{
return lang.Id;
}
return 0;
}
Also implement IDisposable and dispose context.
You can use extension methods:
public int FindUnknownByName(this ScriptEntities context, string name, string language)
{
int languageId = context.FindLanguage(language);
var script = context.scripts.Where(l => l.Name == name && l.Unknown == true && l.LanguageId == languageId).FirstOrDefault();
if (script != null)
{
return script.Id;
}
return 0;.
}
public int FindLanguage(this ScriptEntities context, string language)
{
var lang = context.languages.Where(l => l.Name == language).FirstOrDefault();
if (lang != null)
{
return lang.Id;
}
return 0;
}
then:
using (var context = new ScriptEntities())
{
var language = context.FindUnknownByName('name', 'language')
}
I have applied search method in my project but , I have also Action index()
and getting erorr. (The current request for action 'Index' on controller type 'AdultLiteracyTeachersController' is ambiguous between the following action methods:)
public ViewResult Index(string searchstring, string currentFilter, int? page)
{
if (searchstring != null)
{
page = 1;
}
else
{
searchstring = currentFilter;
}
ViewBag.CurrentFilter = searchstring;
var teachers = from r in db.AdulLiteracyTeachers select r;
if (!string.IsNullOrEmpty(searchstring))
{
teachers = teachers.Where(r => r.ALTName.ToUpper().Contains(searchstring.ToUpper()));
}
teachers = teachers.OrderBy(r => r.ALTName);
int pagesize = 10;
int pageNo = (page ?? 1);
return View(teachers.ToPagedList(pageNo, pagesize));
}
The other ActionResult.index()
public ActionResult Index()
{
var adulliteracyteachers = db.AdulLiteracyTeachers.Include(a => a.District);
return View(adulliteracyteachers.ToList());
}
Action result is used for calling all data how can I aplly in single index ?
Combine them:
public ViewResult Index(string searchstring, string currentFilter, int? page)
{
if (searchString == null && currentFilter == null && !page.HasValue)
{
// No parameters
var adulliteracyteachers = db.AdulLiteracyTeachers.Include(a => a.District);
return View(adulliteracyteachers.ToList());
}
// Regular code here down
if (searchstring != null)
{
page = 1;
}
else
{
searchstring = currentFilter;
}
ViewBag.CurrentFilter = searchstring;
var teachers = from r in db.AdulLiteracyTeachers select r;
if (!string.IsNullOrEmpty(searchstring))
{
teachers = teachers.Where(r => r.ALTName.ToUpper().Contains(searchstring.ToUpper()));
}
teachers = teachers.OrderBy(r => r.ALTName);
int pagesize = 10;
int pageNo = (page ?? 1);
return View(teachers.ToPagedList(pageNo, pagesize));
}
I have two methods for a database entity which gets the translation for selected language if it has one, or the default language translation.
public string GetName(int? LanguageId, int? DefaultLanguageId)
{
string retval = "";
var textInSelectedLanguage = this.CategoryTexts.Where(w => w.LanguageId == LanguageId).SingleOrDefault();
if (textInSelectedLanguage == null)
{
retval = this.CategoryTexts.Where(w => w.LanguageId == DefaultLanguageId).SingleOrDefault().Name;
}
else
{
retval = textInSelectedLanguage.Name;
}
return retval;
}
public string GetDescription(int? LanguageId, int? DefaultLanguageId)
{
string retval = "";
var textInSelectedLanguage = this.CategoryTexts.Where(w => w.LanguageId == LanguageId).SingleOrDefault();
if (textInSelectedLanguage == null)
{
retval = this.CategoryTexts.Where(w => w.LanguageId == DefaultLanguageId).SingleOrDefault().Description;
}
else
{
retval = textInSelectedLanguage.Description;
}
return retval;
}
As you can see they are very similar. If I have more properties to translate, this won't be a good implementation. The behavior is similar for the other translations.
How can reduce this code to one method?
I tried to use reflection but I didn't had any results.
Later...
I reduced my code to one method which return me the an entity instance with all the properties in the selected language or default language:
public CategoryText GetTranslation(int? DesiredLanguageId, int? DefaultLanguageId)
{
CategoryText retval = null;
var textInSelectedLanguage = this.CategoryTexts.Where(w => w.LanguageId == DesiredLanguageId).SingleOrDefault();
if (textInSelectedLanguage == null)
{
retval = this.CategoryTexts.Where(w => w.LanguageId == DefaultLanguageId).SingleOrDefault();
}
else
{
retval = textInSelectedLanguage;
}
return retval;
}
I think this method can be easily made generic by trying to find a way to replace my CategoryTexts Dbset with any other DbSet database entity. How can I do this?
Assuming you have an appropriate base class you could write it:-
public T GetTranslation<T>(DbSet<T> set, int? DesiredLanguageId, int? DefaultLanguageId)
where T:SomeBaseClassThatHasPropertyLanguageId
{
return
set.SingleOrDefault(w => w.LanguageId == DesiredLanguageId) ??
set.SingleOrDefault(w => w.LanguageId == DefaultLanguageId);
}
I somehow solved this.
I have an Internationalization class which with the following method:
public static T GetDbEntityTranslation<T>(ITranslatable Entity)
{
return (T)Entity.GetTranslation<T>(GetDefaultLanguage().Id, GetChosenLanguage().Id);
}
The ITranslatable interface:
public interface ITranslatable
{
T GetTranslation<T>(int? DesiredLanguageId, int? DefaultLanguageId);
}
My category class:
public partial class Category : ITranslatable
{
private LSEntities db = new LSEntities();
public T GetTranslation<T>(int? DesiredLanguageId, int? DefaultLanguageId)
{
CategoryText retval = null;
retval = db.CategoryTexts.Where(w => w.LanguageId == DesiredLanguageId && w.CategoryId == this.Id).SingleOrDefault()
?? this.CategoryTexts.Where(w => w.LanguageId == DefaultLanguageId && w.CategoryId == this.Id).SingleOrDefault()
?? this.CategoryTexts.Where(w => w.CategoryId == this.Id).FirstOrDefault();
if (retval == null)
throw new Exception("No translation found for this object");
return (T)(object)retval;
}
}
The problem was that I need to get my translation based on my category ID which is stored in Category class. My translations are searched in CategoryTexts property.