asp.net getting different session values after setting a value - c#

public class Login : IHttpHandler, System.Web.SessionState.IRequiresSessionState
{
public void ProcessRequest(HttpContext context)
{
try
{
var jsonString = String.Empty;
using (var inputStream = new StreamReader(context.Request.InputStream))
{
jsonString = inputStream.ReadToEnd();
}
User user = JsonConvert.DeserializeObject<User>(jsonString);
BusinessEntities.LoginSession ls = new BusinessEntities.LoginSession();
ls = VerifyLoginCredentials(user.Username.Trim(), user.Password.Trim());
context.Session["user"] = null;
context.Session.Clear();
if (ls.isValid)
{
context.Session["user"] = ls;
context.Response.Write("1");
}
else
{
context.Response.Write("0");
}
}
catch (Exception ex)
{
context.Response.Write("0");
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
There are lot of users logs in to the system using this method. sometimes after login session takes another sessions value.
Lets say User A and B logged in and User A send a request to get the product details but User A getting results of User B. This is strange. do i done something wrong ?
EDIT
public static BusinessEntities.LoginSession VerifyLoginCredentials(string username, string password)
{
return DAL.Creadentials.VerifyLoginCredentials(username, password);
}
public class LoginSession
{
public bool isValid { get; set; }
public string Username { get; set; }
public string NewId { get; set; }
public DateTime PasswordLastResetDate { get; set; }
}

Related

Upload File from Angular to .Net

I am trying make a post with my form along with a file. I tried see others posts but without result. If I make the post without the file, works just fine. English is not my native language, sorry for any mistakes.
This is the error:
This is my data:
My code -> .Net
Model:
public class EmailDto
{
public int Id { get; set; }
public string Name { get; set; }
public string Subject { get; set; }
public int? RecurrentDay { get; set; }
public DateTime? SendDate { get; set; }
public short SendHour { get; set; }
public int? GroupId { get; set; }
public int? RecipientTypeId { get; set; }
public int? ListTypeId { get; set; }
public bool SendForce { get; set; }
public string? Recipients { get; set; }
public bool Archived { get; set; }
public bool Active { get; set; }
public int IdTemplate { get; set; }
public TemplateDto Template { get; set; }
public int? IdRecurrence { get; set; }
public IFormFile? File { get; set; }
}
Controller:
[HttpPost("create")]
public async Task<ActionResult> CreateEmail([FromBody] EmailDto email)
Angular ->
Model:
export class EmailModel {
id!: number
idTemplate!: number
idRecurrence!: number
name!: string
subject!: string
active!: boolean
groupId!: number
recipientTypeId!: number
listTypeId! : number
recipients!: string
sendHour!: number
sendForce!: boolean
template!: TemplateModel
file!: File
}
email.component.ts:
onFileSelected(event: any) {
let fileList: FileList = event.target.files;
if (fileList.length > 0) {
this.file = fileList[0];
}
}
async onSubmit() {
if (this.file != null) {
this.email.file = this.file;
let headers = new HttpHeaders();
headers.append('Content-Type', 'multipart/form-data');
headers.append('Accept', 'application/json');
this.createEmail(this.email, headers);
} else {
this.createEmail(this.email);
}
}
createEmail(email: EmailModel, headers?: HttpHeaders) {
if (headers != null) {
this.EmailService.CreateEmail(email, headers).subscribe(() => {
this.isCreated = true;
}), (error: any) => {
console.log(error);
}
} else {
this.EmailService.CreateEmail(email).subscribe(() => {
this.isCreated = true;
}), (error: any) => {
console.log(error);
}
}
}
service:
CreateEmail(data: EmailModel, headers?: HttpHeaders) {
return this.http.post(`${this.emailApi}/create`, data, {headers: headers});
}
The last print:
If I understood your problem correctly, it would seem you are trying to send a JSON object body with a file and, on the .NET side, it can't deserialize it.
You could try to send the file as base64 instead of whatever you are attempting to send it as now:
async onSubmit()
{
if (this.file == null)
{
this.createEmail(this.email);
return;
}
// Create a file reader
const fileReader = new FileReader();
// Tell the file reader what to do once it loads
fileReader.onload = (event) =>
{
// which is to give us the base64 representation of the file
const base64File = event.target.result.toString();
// and assign it to the dto
this.email.file = base64File;
// before sending the request.
this.createEmail(this.email);
};
// Finally, read the file.
fileReader.readAsBinaryString(this.file);
}
Of course, you need to change file to a string in your DTOs.
You can then parse the base64 back to binary and do whatever you want with it. If you need IFormFile, then:
[HttpPost("create")]
public async Task<ActionResult> CreateEmail([FromBody] EmailDto email)
{
var byteArray = Convert.FromBase64String(email.File);
IFormFile file;
using(var memoryStream = new MemoryStream(byteArray))
{
file = new FormFile(memoryStream,
0,
byteArray.Length,
"someName",
"someFileName");
}
...
doWhatever
}

Bad Request from Creating a New Order with Klarna

I'm getting a Bad Request when I'm sending a POST request to the Klarna API to create a new order.
This is my code for sending the POST request:
Cart = new CartManager(_context, HttpContext.Session).GetCart();
Customer = new CustomerManager(HttpContext.Session).GetCustomer()
OrderViewModel order = new OrderViewModel();
order.Reference = DateTime.Now.ToOADate().ToString().Replace(",", string.Empty);
order.Cart = Cart;
order.Customer = Customer;
string url = ApiHelper.KlarnaApiClient.BaseAddress + "checkout/v3/orders";
KlarnaOrderModel klarnaOrderModel = new KlarnaOrderModel
{
purchase_currency = "SEK",
order_amount = (int)order.Cart.TotalCharge,
order_lines = klarnaOrderLines
};
HttpResponseMessage response = await ApiHelper.KlarnaApiClient.PostAsJsonAsync(
url, klarnaOrderModel);
response.EnsureSuccessStatusCode();
KlarnaOrderModel:
public class KlarnaOrderModel
{
public string purchase_country { get { return "SE"; } }
public string purchase_currency { get; set; }
public string locale { get { return "en-GB"; } }
public int order_amount { get; set; }
public int order_tax_amount { get { return 2500; } }
public List<KlarnaOrderLine> order_lines { get; set; }
public KlarnaMerchantUrls merchant_urls { get { return new Models.KlarnaMerchantUrls(); } }
}
KlarnaOrderLine:
public class KlarnaOrderLine
{
public string name { get; set; }
public int quantity { get; set; }
public int unit_price { get; set; }
public int tax_rate { get { return 2500; } }
public int total_amount { get { return unit_price * quantity; } }
public int total_tax_amount { get { return total_amount / 5 ; } }
}
KlarnaMerchantUrls:
public class KlarnaMerchantUrls
{
public string terms { get { return "https://localhost:44316/shop/terms"; } }
public string checkout { get { return "https://localhost:44316/shop/checkout"; } }
public string confirmation { get { return "https://localhost:44316/shop/checkout/confirmation"; }
public string push { get { return "https://localhost:44316/shop/push"; } }
}
Here is a screenshot:
My code for initializing the API:
KlarnaApiClient = new HttpClient();
KlarnaApiClient.BaseAddress = new Uri("https://api.playground.klarna.com/");
KlarnaApiClient.DefaultRequestHeaders.Accept.Clear();
KlarnaApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
KlarnaApiClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes($"{MY KLARNA API KEY UID}:{MY KLARNA API KEY PASSWORD}")));

Correct way to get results from a blocking collection

I have 50 IMountCmd objects from one or more threads and drop them in a blocking collection. Each is executed and some get results or errors. They are put into a ConcurrentDictionary where I loop for ContainsKey and return the objects. Does this seems thread safe and correct way to process a blocking queue?
public class CmdGetAxisDegrees : IMountCommand
{
public long Id { get; }
public DateTime CreatedUtc { get; private set; }
public bool Successful { get; private set; }
public Exception Exception { get; private set; }
public dynamic Result { get; private set; }
private readonly AxisId _axis;
public CmdGetAxisDegrees(long id, AxisId axis)
{
Id = id;
_axis = axis;
CreatedUtc = HiResDateTime.UtcNow;
Successful = false;
Queues.AddCommand(this);
}
public void Execute(Actions actions)
{
try
{
Result = actions.GetAxisDegrees(_axis);
Successful = true;
}
catch (Exception e)
{
Successful = false;
Exception = e;
}
}
}
private static void ProcessCommandQueue(IMountCommand command)
{
command.Execute(_actions);
if (command.Id > 0)
{
_resultsDictionary.TryAdd(command.Id, command);
}
}
public static IMountCommand GetCommandResult(long id)
{
IMountCommand result;
while (true)
{
if (!_resultsDictionary.ContainsKey(id)) continue;
var success = _resultsDictionary.TryRemove(id, out result);
if (!success)
{
//log
}
break;
}
return result;
}
static Queues()
{
_actions = new Actions();
_resultsDictionary = new ConcurrentDictionary<long, IMountCommand>();
_commandBlockingCollection = new BlockingCollection<IMountCommand>();
Task.Factory.StartNew(() =>
{
foreach (var command in _commandBlockingCollection.GetConsumingEnumerable())
{
ProcessCommandQueue(command);
}
});
}
public interface IMountCommand
{
long Id { get; }
DateTime CreatedUtc { get; }
bool Successful { get; }
Exception Exception { get; }
dynamic Result { get; }
void Execute(Actions actions);
}

Xamarin rest web service doesn't deserialize

I want to use rest with get method. My code is below;
public class RegisterPage : ContentPage
{
Label label, l4, label2;
public RegisterPage()
{
Button btn = new Button
{
Text = "register"
};
btn.Clicked += Btn_Clicked;
label = new Label();
l4 = new Label();
label2 = new Label();
Content = new StackLayout
{
Children = {
btn,
label,
l4,
label2
}
};
}
private async void Btn_Clicked(object sender, EventArgs e)
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add(Constants.API_KEY_HEADER_KEY, Constants.API_KEY);
string URL = Constants.URL;
var response = await client.GetAsync(URL);
var content = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<Models.Result>(content);
label.Text = result.Success.ToString();
l4.Text = result.Error.ToString();
label2.Text = ((RegisteredDevice)result.Retval).Clientuuid + " - " + ((RegisteredDevice)result.Retval).Deviceuuid;
}
}
The url is working good. And my content value has json string. But the serialization is not working.
var result = JsonConvert.DeserializeObject(content);
This code doesn't deserilize.
My model is;
public class Result
{
private object retval = null;
private bool success = false;
private Error error = null;
internal Error Error
{
get { return error; }
set { error = value; }
}
public bool Success
{
get { return success; }
set { success = value; }
}
public object Retval
{
get { return retval; }
set { retval = value; }
}
}
Json:
{
"result":{
"retail":{
"#xsi.type":"registeredDevice",
"clientuuid":"28asgargb-acfe‌​-41dfgsdg51",
"deviceuuid":123456
},
"success":true
}
}
I think the problem comes from :
private object retval = null;
So for me the best way to construct serialization objects in C# is to use this web site :
http://json2csharp.com/
This will tell you if your json is correct and he will generate the classes you need for you, here the classes generated by json2csharp
public class Retail
{
public string __invalid_name__#xsi.type { get; set; }
public string clientuuid { get; set; }
public int deviceuuid { get; set; }
}
public class Result
{
public Retail retail { get; set; }
public bool success { get; set; }
}
public class RootObject
{
public Result result { get; set; }
}

Invalid cast when getting custom IPrincipal from HttpContext

After researching FormsAuthentication for a few days, I decided to store a serialized object in the FormsAuth cookie's UserData property and use a custom IPrincipal object for the HttpContext.Current.User.
Most of the guides I've found say to cast the IPrincipal object to your object. I get an invalid cast exception every time though. What am I doing wrong?
MyUserData
public class MyUserData
{
public long UserId { get; set; }
public string Username { get; set; }
public bool IsSuperUser { get; set; }
public string UnitCode { get; set; }
public string EmailAddress { get; set; }
public List<string> Roles { get; set; }
// Serialize
public override string ToString()
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
string result = serializer.Serialize(this);
return result;
}
// Deserialize
public static MyUserData FromString(string text)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Deserialize<MyUserData>(text);
}
}
CustomPlatformPrincipal
public class MyCustomPrincipal : IPrincipal
{
public MyUserData MyUserData { get; set; }
public IIdentity Identity { get; private set; }
public MyCustomPrincipal(MyUserData myUserData)
{
MyUserData = myUserData;
Identity = new GenericIdentity(myUserData.Username);
}
public bool IsInRole(string role)
{
return MyUserData.Roles.Contains(role);
}
}
Global.asax.cs
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie == null || authCookie.Value == "")
{
return;
}
FormsAuthenticationTicket authTicket;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch
{
return;
}
if (Context.User != null)
{
// the from string deserializes the data
MyUserData myUserData = MyUserData.FromString(authTicket.UserData);
Context.User = new MyCustomPrincipal(myUserData);
}
}
My Page
var myUserData = ((MyCustomPrincipal)(HttpContext.Current.User)).MyUserData;
// invalid cast exception (can't cast IPrincipal to MyCustomPrincipal)
Article I was following: http://primaryobjects.com/CMS/Article147.aspx
So it seems the only way I could get my data is to decrypt the auth cookie, then deserialize the authCookie's userData string.
Any suggestions?
Update
Tried following the suggestions on this SO question: Implementing a Custom Identity and IPrincipal in MVC
Code is below, but it didn't work.
[Serializable]
public class MyCustomPrincipal : IPrincipal, ISerializable
{
public CustomUserData CustomUserData { get; set; }
public IIdentity Identity { get; private set; }
//public MyCustomPrincipal (IIdentity identity) { Identity = identity; }
public MyCustomPrincipal(CustomUserData customUserData)
{
CustomUserData = customUserData;
Identity = new GenericIdentity(customUserData.Username);
}
public bool IsInRole(string role)
{
return PlatformUserData.Roles.Contains(role);
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (context.State == StreamingContextStates.CrossAppDomain)
{
MyCustomPrincipal principal = new MyCustomPrincipal (this.CustomUserData );
info.SetType(principal.GetType());
System.Reflection.MemberInfo[] serializableMembers;
object[] serializableValues;
serializableMembers = FormatterServices.GetSerializableMembers(principal.GetType());
serializableValues = FormatterServices.GetObjectData(principal, serializableMembers);
for (int i = 0; i < serializableMembers.Length; i++)
{
info.AddValue(serializableMembers[i].Name, serializableValues[i]);
}
}
else
{
throw new InvalidOperationException("Serialization not supported");
}
}
}
Did you run in the debug mode? You can put break point on HttpContext.Current.User, you will see what type the user was at that moment.
And from your Application_AuthenticateRequest method, there is no guarantee that the User will be your expected type. There are many exit points before reaching your custom type setup.
Even this code: Context.User != null. It was wrong with your expectation. I have not gone through the detail of the Context.User, however, in term of your context, you were expecting the Context.User was your custom user. So the valid check should be:
var custom = Context.Current as MyCustomPrinciple;
if(custom == null)
{
// Your construct code here.
}
My strongly suggestion is: you need to go in debug mode, to see exactly what was going on.

Categories