So in my global.asax, I've got the following code:
Inventory.BusinessTier bt = new Inventory.BusinessTier();
string UserLogin = bt.ExtractLogin (Request.ServerVariables ["AUTH_USER"]);
Inventory.User myUser = new Inventory.User (UserLogin);
Session ["User"] = myUser;
It works just fine on one development PC, but using the same version of Visual Studio, it craps out on the third line with this error:
System.TypeInitializationException: 'The type initializer for
'Inventory.DataTier' threw an exception.'
Inner Exception
NullReferenceException: Object reference not set to an instance of an
object.
Other than a line adding impersonation in my web.config (it has to be there now), I haven't changed a single thing. Is there a way to get more info on this? I can't even trace it, because if I put a debug line in the User object constructor, it never hits it. I'm at a bit of a loss. Would appreciate any advice.
EDIT to answer questions below:
InventoryUser is a very simple user object that reads the current from the database and stores some basic user info in properties, such as UserID, Role, RoleID, and IsAdmin.
The DataTier class is a class that interacts with the database. It is used in multiple projects, so I'm quite sure it's not the problem. I tried to paste in the code anyway, but it exceeded the limit for a post.
I'm reasonably sure the problem is related to the user class. It's short, so I can paste it in here:
using System;
using System.Data;
// This is the user business object. It contains information pertaining to the current user of the application. Notably, it
// contains the department ID, which determines what inventory items the user will see when using the application. Only
// specified employees with admin access can see all items for all departments, and that is determined by a specific department ID.
namespace Inventory {
public class User {
private Guid _UserID;
private Guid _RoleID;
private Guid _UserDepartmentID;
private string _UserRole = "";
private string _UserName = "";
private bool _IsAuthorizedUser = false;
private bool _IsAdmin = false;
// Attribute declarations
public Guid UserID {
get {
return _UserID;
}
set {
_UserID = value;
}
}
public string UserRole {
get {
return _UserRole;
}
set {
_UserRole = value;
}
}
public Guid RoleID {
get {
return _RoleID;
}
set {
_RoleID = value;
}
}
public string UserName {
get {
return _UserName;
}
set {
_UserName = value;
}
}
public Guid UserDepartmentID {
get {
return _UserDepartmentID;
}
set {
_UserDepartmentID = value;
}
}
public bool IsAdmin {
get {
return _IsAdmin;
}
set {
_IsAdmin = value;
}
}
public bool IsAuthorizedUser {
get {
return _IsAuthorizedUser;
}
set {
_IsAuthorizedUser = value;
}
}
// -----------------
// - Constructor -
// -----------------
public User (string UserLogin) {
string ShortUserLogin = ExtractLogin (UserLogin);
GetUser (ShortUserLogin);
}
// ------------------
// - ExtractLogin -
// ------------------
public string ExtractLogin (string Login) {
// The domain and "\" symbol must be removed from the string, leaving only the user name.
int pos = Login.IndexOf (#"\");
return Login.Substring (pos + 1, Login.Length - pos - 1);
}
// -------------
// - GetUser -
// -------------
// This method is called to fill the user object based on the user's login. It ultimately gets authorized user data
// from the user table.
public void GetUser (string UserName) {
DataTier dt1 = new DataTier();
DataTable dt = dt1.GetUserInfo (UserName);
int RecordCount = dt.Rows.Count;
switch (RecordCount) {
case 1: // There is one user name match, as there should be. This is the likely situation.
DataRow dr = dt.Rows[0];
UserID = (Guid)dr ["UserID"];
UserRole = (string)dr ["UserRole"];
RoleID = (Guid)dr ["RoleID"];
this.UserName = UserName;
UserDepartmentID = (Guid)dr ["DepartmentID"];
IsAdmin = (bool)dr ["IsAdmin"];
IsAuthorizedUser = true;
break;
case 0: // There are no user name matches (unauthorized use).
IsAdmin = false;
IsAuthorizedUser = false;
break;
default: // There are multiple user name matches (problem!).
IsAdmin = false;
IsAuthorizedUser = false;
break;
}
}
}
}
Related
I have a quiz app and I would like to display scores on last screen, however I have an issue how to do it.
Here' how my score script looks like:
{
//Zliczanie punktów i wyświetlanie wyniku
public static int pointssum = 0;
public Text points;
private string user;
private Text scoresboard;
USers users = new USers();
void Start()
{
points = GetComponent<Text>();
Posttodb();
}
void Update()
{
points.text = "Poprawne odpowiedzi: " + pointssum;
}
private void Posttodb()
{
user = nazwagracza.Playernick;
if (user!= null)
{
USers users = new USers();
RestClient.Put("https://quizgame-inz.firebaseio.com/" + user + ".json", users);
}
}
private void Getdata()
{
RestClient.GetArray<USers>("https://quizgame-inz.firebaseio.com/.json?orderBy='scores'&startAt=0").Then(response =>
{
users = response;
});
}
}
I tried to assign this data to user value but I'm getting error cannot implicitly convert type.
Can you please help we with this?
users is of type USers .. it is not an array.
You did probably mean e.g.
// Returns an array of USers
RestClient.GetArray<USers>("https://quizgame-inz.firebaseio.com/.json?orderBy='scores'&startAt=0").Then(response =>
{
// get the first instance
users = response[0];
});
or make users of type
USers[] users;
depending on your needs.
Due to the naming and description it sounds like you would want to do the latter since you want to display all scores, not only the best one.
Look at the code below. There's two DelegateCommand that are set in Views's constructor:
public DelegateCommand DeletePromotionCommand { get; set; }
public DelegateCommand EditPromotionCommand { get; set; }
public PromotionDetailViewModel(INavigationService navigationService, IPageDialogService pageDialogService)
: base(navigationService, pageDialogService)
{
Title = "Promoção";
DeletePromotionCommand = new DelegateCommand(DeletePromotion, CanDeletePromotion);
EditPromotionCommand = new DelegateCommand(EditPromotion, CanEditPromotion);
}
The CanEditPromotion is called when the EditPromotionCommand is set in the constructor. CanEditPromotion method is shown below:
private bool CanEditPromotion()
{
var userString = Preferences.Get("user", string.Empty);
if (userString == string.Empty)
return false;
var userId = (Guid)JObject.Parse(userString)["id"];
if (userId == Promotion.CreatedBy)
return true;
else
return false;
}
Note that on the 4th sentence I need the Promotion property. This property need to be set before the Views's constructor, so it will be null and, at exactly line, it will break the app.
Before I should use the code below to set Promotion property, but Prism doesn't have OnNavigatingTo method anymore. Promotion info comes from the Page before and is passed as a parameter navigation:
public override async void OnNavigatingTo(INavigationParameters parameters)
{
base.OnNavigatedTo(parameters);
try
{
IsBusy = true;
Promotion = parameters["promotion"] as Promotion;
var marketService = new Service<Market>();
Market = await marketService.GetAsync(Promotion.MarketId);
IsBusy = false;
}
catch (Exception)
{
IsBusy = false;
}
}
When I try to use INavigatingTo at my BaseViewModel, it is show to me a message saying to use IInitialize instead. I tried but the Initialize method is still fired after the View's constructor.
As is indicated in the official release notes for Prism 7.2 OnNavigatingTo was deprecated due after a lot of consideration and feedback from the Prism community. This was in part due to the fact that OnNavigatingTo was expected to run to Initialize your ViewModel prior to the View being pushed onto the Navigation Stack. The issue is that over time its intent was getting lost and people were trying to misuse the API. The only way for us to move forward was to remove the reference to INavigatingAware from INavigationAware which unfortunately creates a soft break in which OnNavigatingTo simply isn't called. In the case where you have a direct reference to INavigatingAware you will get a hard compilation error.
To migrate your code you should use the new initialization API with either IInitialize, IInitializeAsync or IAutoInitialize. Assuming that you simply use IInitialize you'll update your legacy code from:
public void OnNavigatingTo(INavigationParameters parameters)
{
// your code here
}
to the new IInitialize version
public void Initialize(INavigationParameters parameters)
{
// your code here
}
Keep in mind that if you use the Async version of this the long running task will have to complete before the page is pushed thus causing a noticeable delay in navigation. It may often be more desirable therefore to simply use async void to avoid blocking the Navigation.
You can read more in the Prism 7.2 Release Notes here
I resolved this way:
At CanEditPromotion I put a null verification for Promotion property:
private bool CanEditPromotion()
{
var userString = Preferences.Get("user", string.Empty);
if (userString == string.Empty)
return false;
var userId = (Guid)JObject.Parse(userString)["id"];
if (Promotion != null && userId == Promotion.CreatedBy)
return true;
else
return false;
}
And I observe the Promotion property when the EditPromotionCommand is set:
public DelegateCommand DeletePromotionCommand { get; set; }
public DelegateCommand EditPromotionCommand { get; set; }
public PromotionDetailViewModel(INavigationService navigationService, IPageDialogService pageDialogService)
: base(navigationService, pageDialogService)
{
Title = "Promoção";
DeletePromotionCommand = new DelegateCommand(DeletePromotion, CanDeletePromotion)
.ObservesProperty(() => Promotion);
EditPromotionCommand = new DelegateCommand(EditPromotion, CanEditPromotion)
.ObservesProperty(() => Promotion);
}
And I used the OnNavigatedTo method to set Promotion property:
public override async void OnNavigatedTo(INavigationParameters parameters)
{
try
{
IsBusy = true;
Promotion = parameters["promotion"] as Promotion;
var marketService = new Service<Market>();
Market = await marketService.GetAsync(Promotion.MarketId);
IsBusy = false;
}
catch (Exception)
{
IsBusy = false;
}
}
I am using asp.net core to build API. I have a request that allow user to upload profile image using this code
[HttpPost("{company_id}/updateLogo")]
public async Task<IActionResult> updateCompanyLogo(IFormFile imgfile,int company_id)
{
string imageName;
// upload file
if (imgfile == null || imgfile.Length == 0)
imageName = "default-logo.jpg";
else
{
imageName = Guid.NewGuid() + imgfile.FileName;
var path = _hostingEnvironment.WebRootPath + $#"\Imgs\{imageName}";
if (imgfile.ContentType.ToLower().Contains("image"))
{
using (var fileStream = new FileStream(path, FileMode.Create))
{
await imgfile.CopyToAsync(fileStream);
}
}
}
.
.
but it keeps returning this exception: Form key or value length limit 2048 exceeded
The Request
http://i.imgur.com/25B0qkD.png
Update:
I have tried this code but it doesn't work
services.Configure<FormOptions>(options =>
{
options.ValueLengthLimit = int.MaxValue; //not recommended value
options.MultipartBodyLengthLimit = long.MaxValue; //not recommended value
});
By default, ASP.NET Core enforces key/value length limit of 2048 inside FormReader as constant and applied in FormOptions as shown below:
public class FormReader : IDisposable
{
public const int DefaultValueCountLimit = 1024;
public const int DefaultKeyLengthLimit = 1024 * 2; // 2048
public const int DefaultValueLengthLimit = 1024 * 1024 * 4; // 4194304
// other stuff
}
public class FormOptions
{
// other stuff
public int ValueCountLimit { get; set; } = DefaultValueCountLimit;
public int KeyLengthLimit { get; set; } = FormReader.DefaultKeyLengthLimit;
public int ValueLengthLimit { get; set; } = DefaultValueLengthLimit;
// other stuff
}
Hence, you may create a custom attribute to explicitly set key/value length limit on your own by using KeyValueLimit and ValueCountLimit property (also ValueLengthLimit etc.):
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class RequestSizeLimitAttribute : Attribute, IAuthorizationFilter, IOrderedFilter
{
private readonly FormOptions _formOptions;
public RequestSizeLimitAttribute(int valueCountLimit)
{
_formOptions = new FormOptions()
{
// tip: you can use different arguments to set each properties instead of single argument
KeyLengthLimit = valueCountLimit,
ValueCountLimit = valueCountLimit,
ValueLengthLimit = valueCountLimit
// uncomment this line below if you want to set multipart body limit too
// MultipartBodyLengthLimit = valueCountLimit
};
}
public int Order { get; set; }
// taken from /a/38396065
public void OnAuthorization(AuthorizationFilterContext context)
{
var contextFeatures = context.HttpContext.Features;
var formFeature = contextFeatures.Get<IFormFeature>();
if (formFeature == null || formFeature.Form == null)
{
// Setting length limit when the form request is not yet being read
contextFeatures.Set<IFormFeature>(new FormFeature(context.HttpContext.Request, _formOptions));
}
}
}
Usage example in action method:
[HttpPost("{company_id}/updateLogo")]
[RequestSizeLimit(valueCountLimit: 2147483648)] // e.g. 2 GB request limit
public async Task<IActionResult> updateCompanyLogo(IFormFile imgfile, int company_id)
{
// contents removed for brevity
}
NB: If latest version of ASP.NET Core is being used, change property named ValueCountLimit to KeyCountLimit.
Update: The Order property must be included on attribute class because it is a member of implemented interface IOrderedFilter.
Similar issues:
Form submit resulting in "InvalidDataException: Form value count limit 1024 exceeded."
Request.Form throws exception
For my case adding the [DisableRequestSizeLimit] attribute solved error; this can be helpful when you are not sure about the maximum length of request. This is formal documentation.
[HttpPost("bulk")]
[ProducesResponseType(typeof(IEnumerable<Entry>), (int)HttpStatusCode.Created)]
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
[ProducesResponseType((int)HttpStatusCode.InternalServerError)]
[DisableRequestSizeLimit]
public async Task<IActionResult> BulkCreateEntry([FromBody] IEnumerable<CreateStockEntryFromCommand> command)
{
// do your work
}
This answer was really helpful, thanks.
But since .Net Core 2.1 there are built-in attributes for this purpose, e.g. RequestFormLimitsAttribute or RequestSizeLimitAttribute
services.Configure<FormOptions>(options =>
{
options.ValueLengthLimit = int.MaxValue;
options.MultipartBodyLengthLimit = int.MaxValue;
options.MultipartHeadersLengthLimit = int.MaxValue;
});
it solved my problem
I'm on .Net6 and this is all I needed. (In my startup file inside ConfigureServices(services).)
services.Configure<FormOptions>(options =>
{
options.KeyLengthLimit = int.MaxValue;
});
Using VS2012/.NET 4.5 I am creating a custom activity which implements a Receive child activity (as an implementation child). The parameters are in the example below fixed to just one: OutValue of type Guid.
I really would love to access the value of incoming parameter value in ReceiveDone, because I need to work with it and transform it before returning it from the activity. Please ignore that I am currently using a Guid, it still fails to access the value with and InvalidOperationException:
An Activity can only get the location of arguments which it owns. Activity 'TestActivity' is trying to get the location of argument 'OutValue' which is owned by activity 'Wait for
workflow start request [Internal for TestActivity]'
I have tried everything I could think of, but am stupefied. There must be a way to do this very simple thing?
public class TestActivity : NativeActivity<Guid>
{
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
var content = ReceiveParametersContent.Create(new Dictionary<string, OutArgument>()
{
// How to access the runtime value of this inside TestActivity?
{"OutValue", new OutArgument<Guid>()}
});
startReceiver = new Receive()
{
DisplayName = string.Format("Wait for workflow start request [Internal for {0}]", this.DisplayName),
CanCreateInstance = true,
ServiceContractName = XName.Get("IStartService", Namespace),
OperationName = "Start",
Content = content
};
foreach (KeyValuePair<string, OutArgument> keyValuePair in content.Parameters)
{
metadata.AddImportedChild(keyValuePair.Value.Expression);
}
metadata.AddImplementationChild(startReceiver);
}
protected override void Execute(NativeActivityContext context)
{
context.ScheduleActivity(startReceiver, ReceiveDone);
}
private void ReceiveDone(NativeActivityContext context, ActivityInstance completedInstance)
{
var receive = completedInstance.Activity as Receive;
ReceiveParametersContent content = receive.Content as ReceiveParametersContent;
try
{
// This causes InvalidOperationException.
// An Activity can only get the location of arguments which it owns.
// Activity 'TestActivity' is trying to get the location of argument 'OutValue'
// which is owned by activity 'Wait for workflow start request [Internal for TestActivity]'
var parmValue = content.Parameters["OutValue"].Get(context);
}
catch (Exception)
{ }
}
private Receive startReceiver;
private const string Namespace = "http://company.namespace";
}
Use internal variables to pass values between internal activities.
Although not directly related to your code, see the example below which should give you the idea:
public sealed class CustomNativeActivity : NativeActivity<int>
{
private Variable<int> internalVar;
private Assign<int> internalAssign;
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
base.CacheMetadata(metadata);
internalVar = new Variable<int>("intInternalVar", 10);
metadata.AddImplementationVariable(internalVar);
internalAssign = new Assign<int>
{
To = internalVar,
Value = 12345
};
metadata.AddImplementationChild(internalAssign);
}
protected override void Execute(NativeActivityContext context)
{
context.ScheduleActivity(internalAssign, (activityContext, instance) =>
{
// Use internalVar value, which was seted by previous activity
var value = internalVar.Get(activityContext);
Result.Set(activityContext, value);
});
}
}
Calling the above activity:
WorkflowInvoker.Invoke<int>(new CustomNativeActivity());
Will output:
12345
Edit:
In your case your OutArgument will be the internalVar
new OutArgument<int>(internalVar);
You need to use OutArgument and them to variables. See the code example with the documentation.
I may have tried everything I thought of, but I am stubborn and refuse to give up, so I kept on thinking ;)
I here have changed my example to use a Data class as a parameter instead (it does not change anything in itself, but I needed that in my real world example).
This code below is now a working example on how to access the incoming data. The use of an implementation Variable is the key:
runtimeVariable = new Variable<Data>();
metadata.AddImplementationVariable(runtimeVariable);
And the OutArgument:
new OutArgument<Data>(runtimeVariable)
I can then access the value with:
// Here dataValue will get the incoming value.
var dataValue = runtimeVariable.Get(context);
I haven't seen an example elsewhere, which does exactly this. Hope it will be of use to any one but me.
The code:
[DataContract]
public class Data
{
[DataMember]
Guid Property1 { get; set; }
[DataMember]
int Property2 { get; set; }
}
public class TestActivity : NativeActivity<Guid>
{
public ReceiveContent Content { get; set; }
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
runtimeVariable = new Variable<Data>();
metadata.AddImplementationVariable(runtimeVariable);
Content = ReceiveParametersContent.Create(new Dictionary<string, OutArgument>()
{
{"OutValue", new OutArgument<Data> (runtimeVariable)}
});
startReceiver = new Receive()
{
DisplayName = string.Format("Wait for workflow start request [Internal for {0}]", this.DisplayName),
CanCreateInstance = true,
ServiceContractName = XName.Get("IStartService", Namespace),
OperationName = "Start",
Content = Content
};
metadata.AddImplementationChild(startReceiver);
}
protected override void Execute(NativeActivityContext context)
{
context.ScheduleActivity(startReceiver, ReceiveDone);
}
private void ReceiveDone(NativeActivityContext context, ActivityInstance completedInstance)
{
// Here dataValue will get the incoming value.
var dataValue = runtimeVariable.Get(context);
}
private Receive startReceiver;
private Variable<Data> runtimeVariable;
private const string Namespace = "http://company.namespace";
}
I have this code below. Gets data and sets data property to the values gathered.
public struct TrblShootData
{
public List<string> Logins;
public IEnumerable<Hieracrhy> Hierarchy;
public IEnumerable<EmployeeTeam> EmpTeam;
}
public TrblShootData TroubleShootData
{
get;
private set;
}
class DataGetter
{
public void GetData(string FirstName, string LastName, string Login, string Email, bool isFirstName, bool isLastName, bool isLogin, bool isEmail)
{
List<string> logins = null;
IEnumerable<Hieracrhy> hier = null;
IEnumerable<EmployeeTeam> tmemp = null;
TrblShootData tsData = new TrblShootData();
queries q = BuildQuery(FirstName, LastName, Login, Email, isFirstName, isLastName, isLogin, isEmail);
if (q.isValidQueries)
{
DataContext1 mscDB = new DataContext1 ();
using (DataContext2 opsDB = new DataContext2 ())
{
tmemp = opsDB.ExecuteQuery<EmployeeTeam>(q.qryEmployeeTeam);
}
using (DataContext3 rptDB = new DataContext3 ())
{
hier = rptDB.ExecuteQuery<Hieracrhy>(q.qryHierarchy);
if (hier != null)
{
logins = hier.Select(s => s.SalesRepLogin).Distinct().ToList();
}
}
tsData.EmpTeam = tmemp.Select(r=>r);
tsData.Hierarchy = hier.Select(r => r);
tsData.Logins = logins.Select(r => r).ToList();
TroubleShootData = tsData;
}//if
}
}
From another class I attempt to do this:
tshtr.GetData(txtFirstName.Text, txtLastName.Text, txtLogin.Text, txtEmail.Text, chkFirstName.Checked, chkLastName.Checked, chkLogin.Checked, chkEmail.Checked);
gvEmpTeams.DataSource = tshtr.TroubleShootData.EmpTeam;
gvHierarchy.DataSource = tshtr.TroubleShootData.Hierarchy;
gvEmpTeams.DataBind();
gvHierarchy.DataBind();
But at the DataBind() I get an error saying that I cannot read from a closed reader.
I'm not seeing why it would throw this error when I've set my property as above after I've assigned the values in the usings. So I'm not seeing how this is trying to use a closed reader.
Thanks for any help!
Because of deferred execution, your query only executes when the data-binding engine enumerates its results, after you close the DataContext.
You need to call .ToList() before closing the DataContext to force it to be evaluated immediately.