Best way for store data into client - session

My Put method is as follows:
public void Post([FromBody]RavenUserView view)
{
if (ModelState.IsValid)
{
var request = new CreateUserRequest();
request.ID = view.ID;
request.Name = view.Name;
request.UserName = view.UserName;
request.Password = EncryptionDecryption.EncryptString(view.Password);//Encrypt The Password
request.Email = view.Email;
request.Phone = view.Phone;
request.Country = "x";
request.Note = "y";
request.IsActive = view.IsActive;
request.Creator = view.Creator;
request.CreationDate = DateTime.UtcNow;
request.ModificationDate = DateTime.UtcNow;
request.Remarks = "z";
var response = _facade.CreateUser(request);
SaveUserDetailsToCookie(response.RavenUser.ID, response.RavenUser.UserName, EncryptionDecryption.DecryptString(response.RavenUser.Password));//Cookie should be stored Decrypted Format
HttpContext.Current.Session[SessionDataKey.UserId.ToString()] = response.RavenUser.ID.ToString();
HttpContext.Current.Session[SessionDataKey.UserName.ToString()] = response.RavenUser.UserName;
}
}
But When I run my project and try to save my information then it throw me an exception "Object Reference is not set to the reference of an object"
I am using Web Api as my controller class.
After reading various documents I found that Api is stateless. Now how can I store my user information for further use.

Use:
public void Post([Bind(Include = "ID,Name,UserName,....")] CreateUserRequest request)
{
if(ModelState.IsValid)
{
var response = _facade.CreateUser(request);
SaveUserDetailsToCookie(response.RavenUser.ID, response.RavenUser.UserName, EncryptionDecryption.DecryptString(response.RavenUser.Password));//Cookie should be stored Decrypted Format
HttpContext.Current.Session[SessionDataKey.UserId.ToString()] = response.RavenUser.ID.ToString();
HttpContext.Current.Session[SessionDataKey.UserName.ToString()] = response.RavenUser.UserName;
}
}

Related

Rotativa BuildFile not hitting the Action Method

I have two action methods in my Controller class:
DetailsAll: to get some data and display in the view
SaveAsPDF: Called on windows.load of DetailsAll.cshtml which should save DetailsAll view as pdf
My issue is in SaveAsPDF Action method. Here I am trying to use Rotativa ActionAsPdf and subsequently BuildFile methods to generate and save the PDF. However, when executing the line "BuildFile", it is not hitting the breakpoint in my DetailsAll Action method, subsequently causing the PDF to be generated blank.
Could you please help where I am going wrong?
[HttpGet]
public ActionResult DetailsAll()
{
var selectionBuilder = builderFactory.GetGeocodeReportSelectionViewModelBuilder();
var companyList = selectionBuilder.Build();
List<GeocodeReportViewModel> viewModel = new List<GeocodeReportViewModel>();
foreach(SelectListItem record in companyList.Companies)
{
var builder = builderFactory.GetGeocodeReportViewModelBuilder(int.Parse(record.Value));
viewModel.Add(builder.Build());
}
var model = new AllGeocodeReportViewModel
{
GeocodeReports = viewModel
};
return View(model);
}
[HttpGet]
public string SaveAsPDF()
{
var report = new ActionAsPdf("DetailsAll")
{
FileName = "OEM_GeocodeReport_" + System.DateTime.Now.ToString("MMYY") + ".pdf",
PageSize = Size.A4,
PageOrientation = Orientation.Landscape,
PageMargins = { Left = 1, Right = 1 }
};
byte[] pdf = report.BuildFile(ControllerContext);
System.IO.File.WriteAllBytes("C:\\" + report.FileName, pdf);
return "true";
}
Finally found the issue after extensive search. I need to send Authentication cookies along with the BuildFile request for this to work. Added the below code and it generates PDF correctly now:
public void SaveAsPDF()
{
var cookies = Request.Cookies.AllKeys.ToDictionary(k => k, k => Request.Cookies[k].Value);
var report = new ActionAsPdf("DetailsAll")
{
FileName = "OEM_GeocodeReport_" + System.DateTime.Now.ToString("MMyy") + ".pdf",
PageSize = Size.A4,
PageOrientation = Orientation.Portrait,
PageMargins = { Left = 3, Right = 3 },
FormsAuthenticationCookieName = System.Web.Security.FormsAuthentication.FormsCookieName,
Cookies = cookies
};
byte[] pdf = report.BuildFile(ControllerContext);
System.IO.File.WriteAllBytes("C:\\" + report.FileName, pdf);
}

Connecting xamarin to woocommerce api

I'm trying to create my first app that will connect to a woocommerce api.
Has anyone any experience in this or can point me in the direction as to how to create a connection to pull in the product list?
Thanks
Since WooCommerce has a REST API, it should be fairly simple to connect using a plain HTTP request, or a library like RestSharp.
There is also a C# client for WooCommerce - I don't know if it plays well with Xamarin, you might need to modify it a bit to get it to build.
var api = new WoocommerceApiClient(StoreUrl, ConsumerKey, ConsumerSecret);
var result = await api.Products.Get();
It's an old post but I had faced a similar issue. I had tries WoocommerceSharp with Xamarin Studio 6.1.1 (mac version); I opened the .sln file, added the missing reference to system.net.http and it worked perfectly.
If you want make it work in PCL you have to use PCLCrypto in WoocommerceApiUrlGenerator.cs , here the updated version:
namespace SharpCommerce.Web
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using PCLCrypto;
internal class WoocommerceApiUrlGenerator
{
private const string SignatureMethod = "HMAC-SHA1";
private const string ApiV3RootEndpoint = "wc-api/v3/";
private readonly string baseURI;
private readonly string consumerKey;
private readonly string consumerSecret;
internal WoocommerceApiUrlGenerator(string storeUrl, string consumerKey, string consumerSecret)
{
if (
string.IsNullOrEmpty(consumerKey) ||
string.IsNullOrEmpty(consumerSecret) ||
string.IsNullOrEmpty(storeUrl))
{
throw new ArgumentException("ConsumerKey, consumerSecret and storeUrl are required");
}
this.consumerKey = consumerKey;
this.consumerSecret = consumerSecret;
// Need 'http://www.example.com' to be 'http://www.example.com/wc-api/v3/'
this.baseURI = String.Format("{0}/{1}", storeUrl.TrimEnd('/'), ApiV3RootEndpoint);
}
internal string GenerateRequestUrl(HttpMethod httpMethod, string apiEndpoint, Dictionary<string, string> parameters = null)
{
parameters = parameters ?? new Dictionary<string, string>();
parameters["oauth_consumer_key"] = this.consumerKey;
// oauth_timestamp = number of seconds since 1/1/1970 00:00:00 GMT
// must be a positive integer
// must be greater than timestamp of previous requests
parameters["oauth_timestamp"] =
Math.Round(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds).ToString(CultureInfo.InvariantCulture);
// oauth_nonce = a unique random string for the timestamp.
// defends against replay attacks
// service provide will know that this request has never been made before.
// Just going to hash the time stamp.
//parameters["oauth_nonce"] = GenerateNonce(parameters["oauth_timestamp"]);
// Create random 32 char alphnumeric to avoid reused nonces
parameters["oauth_nonce"] = GenerateNonce();
// Declare the hashing method your using
parameters["oauth_signature_method"] = SignatureMethod;
//parameters["oauth_version"] = "1.0";
parameters["oauth_signature"] = UpperCaseUrlEncode(this.GenerateSignature(httpMethod, apiEndpoint, parameters));
var sb = new StringBuilder();
foreach (var pair in parameters)
{
sb.AppendFormat("&{0}={1}", SafeUpperCaseUrlEncode(pair.Key), SafeUpperCaseUrlEncode(pair.Value));
}
// Substring removes first '&'
var queryString = sb.ToString().Substring(1);
var url = this.baseURI + apiEndpoint + "?" + queryString;
return url;
}
private string GenerateSignature(HttpMethod httpMethod, string apiEndpoint, Dictionary<string, string> parameters)
{
// 1) Set the HTTP method for the request.
// set through 'method'
//2) Set your base request URI – this is the full request URI without query string parameters – and URL encode according to RFC 3986:
// need 'http://www.example.com/wc-api/v3/orders'
// to become: 'http%3A%2F%2Fwww.example.com%2Fwc-api%2Fv1%2Forders'
var encodedBaseRequestURI = SafeUpperCaseUrlEncode(this.baseURI + apiEndpoint);
// 3) Collect and normalize your query string parameters
// percent(%) characters should be double-encoded (e.g. % becomes %25.
var normalizedParameters = NormalizeParameters(parameters);
// 4) Sort the parameters in byte-order
var orderedNormalizedParameters = normalizedParameters.OrderBy(x => x.Key).ToList();
// 5) Join each parameter with an encoded equals sign (%3D):
//var joinedOrderedNormalizedParameters = orderedNormalizedParameters.ConvertAll(x => x.Key + "%3D" + x.Value);
var joinedOrderedNormalizedParameters = new List<string>();
foreach (var x in orderedNormalizedParameters)
{
joinedOrderedNormalizedParameters.Add(x.Key + "%3D" + x.Value);
}
// 6) Join each parameter key/value pair with an encoded ampersand (%26):
var joinedParameterPairs = String.Join("%26", joinedOrderedNormalizedParameters);
// 7) Form the string to sign by joining the HTTP method, encoded base request URI, and encoded parameter string with an unencoded ampersand symbol (&):
var stringToSign = string.Format("{0}&{1}&{2}", httpMethod.ToString().ToUpper(), encodedBaseRequestURI, joinedParameterPairs);
// 8) Generate the signature using the string to key and your consumer secret key
var preparedStringToSign = Encoding.UTF8.GetBytes(stringToSign);
var secret = this.consumerSecret + "&";
var preparedConsumerKey = Encoding.UTF8.GetBytes(secret);
var signatureHash = Sha1(preparedConsumerKey, preparedStringToSign);
var signatureString = Convert.ToBase64String(signatureHash);
return signatureString;
}
private static byte[] Sha1(byte[] key, byte[] message)
{
var mac = WinRTCrypto.MacAlgorithmProvider.OpenAlgorithm(MacAlgorithm.HmacSha1);
//var keyMaterial = WinRTCrypto.CryptographicBuffer.ConvertStringToBinary(key, Encoding.UTF8);
var cryptoKey = mac.CreateKey(key);
var hash = WinRTCrypto.CryptographicEngine.Sign(cryptoKey, message);
return hash;
//return WinRTCrypto.CryptographicBuffer.CreateFromByteArraymessage);
}
private static Dictionary<string, string> NormalizeParameters(Dictionary<string, string> parameters)
{
var result = new Dictionary<string, string>();
foreach (var pair in parameters)
{
var upperCaseUrlEncodedKey = SafeUpperCaseUrlEncode(pair.Key);
var normalizedKey = upperCaseUrlEncodedKey.Replace("%", "%25");
var upperCaseUrlEncodedValue = SafeUpperCaseUrlEncode(pair.Value);
var normalizedValue = upperCaseUrlEncodedValue.Replace("%", "%25");
result.Add(normalizedKey, normalizedValue);
}
return result;
}
private static string SafeUpperCaseUrlEncode(string stringToEncode)
{
return UpperCaseUrlEncode(System.Net.WebUtility.UrlDecode(stringToEncode));
}
private static string UpperCaseUrlEncode(string stringToEncode)
{
var basicUrlEncodedString = System.Net.WebUtility.UrlEncode(stringToEncode);
if (String.IsNullOrEmpty(basicUrlEncodedString)) return String.Empty;
var upperCaseUrlEncodedString = Regex.Replace(
basicUrlEncodedString,
"(%[0-9a-f][0-9a-f])",
c => c.Value.ToUpper());
return upperCaseUrlEncodedString;
}
private static string GenerateNonce()
{
const string ValidChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var random = new Random();
var nonceString = new StringBuilder();
for (var i = 0; i < 32; i++)
{
nonceString.Append(ValidChars[random.Next(0, ValidChars.Length - 1)]);
}
return nonceString.ToString();
}
}
}
and in WoocommerceApiDriver.cs you will have to replace
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
return await client.GetStringAsync(url);
}
by
using (var client = new HttpClient()) // must use to avoid Android freezes after repeated calls
{
Task<HttpResponseMessage> r = client.GetAsync(url);
HttpResponseMessage m = r.Result;
return await m.Content.ReadAsStringAsync();
}
Et voila ! ca marche ;)

WebAPI HttpContext is Null Inside ContinueWith() => tast

I'm just wondering if someone could explain what is happening here.
Given this Post method on an API controller:
public HttpResponseMessage PostImage()
{
var request = HttpContext.Current.Request;
var c = SynchronizationContext.Current;
var result = new HttpResponseMessage(HttpStatusCode.OK);
if (Request.Content.IsMimeMultipartContent())
{
Request.Content.ReadAsMultipartAsync(new MultipartMemoryStreamProvider()).ContinueWith((task) =>
{
MultipartMemoryStreamProvider provider = task.Result;
foreach (HttpContent content in provider.Contents)
{
Stream stream = content.ReadAsStreamAsync().Result;
Image image = Image.FromStream(stream);
var uploadFileName = content.Headers.ContentDisposition.FileName;
var requestInside = HttpContext.Current.Request; // this is always null
string filePath = Path.Combine(HostingEnvironment.MapPath(ConfigurationManager.AppSettings["UserFilesRootDir"]), userprofile.UserCode);
//string[] headerValues = (string[])Request.Headers.GetValues("UniqueId");
string fileName = userprofile.UserCode + ".jpg";
string fullPath = Path.Combine(filePath, fileName);
image.Save(fullPath);
}
});
return result;
}
}
Why would var requestInside = HttpContext.Current.Request; be null?
I've checked all the relevant settings:
<compilation debug="true" targetFramework="4.5">
...
<httpRuntime targetFramework="4.5"
And SynchronizationContext.Current is the newer AspNetSynchronizationContext rather than LegacyAspNetSynchronizationContext.
I'm presuming at the moment that it's because I'm on a different thread, is this a correct assumption?
ContinueWith is not guaranteed to run on the same thread hence the synchronization context could be lost. You could change your call to specify to resume on the current thread with parameter TaskScheduler.Current. See this previous SO answer.
If you use await/async pattern it will automatically capture the current syncronization context on resume once an awaitable operation completes. This is done by resuming the operation on the same thread which is bound to that context. An added benefit, IMHO, is cleaner looking code.
You can change your code to this which uses that pattern. I have not made any other changes to it other than use async/await.
public async Task<HttpResponseMessage> PostImage()
{
var request = HttpContext.Current.Request;
var c = SynchronizationContext.Current;
var result = new HttpResponseMessage(HttpStatusCode.OK);
if (Request.Content.IsMimeMultipartContent())
{
MultipartMemoryStreamProvider provider = await Request.Content.ReadAsMultipartAsync(new MultipartMemoryStreamProvider());
foreach (HttpContent content in provider.Contents)
{
Stream stream = await content.ReadAsStreamAsync();
Image image = Image.FromStream(stream);
var uploadFileName = content.Headers.ContentDisposition.FileName;
var requestInside = HttpContext.Current.Request; // this is always null
string filePath = Path.Combine(HostingEnvironment.MapPath(ConfigurationManager.AppSettings["UserFilesRootDir"]), userprofile.UserCode);
//string[] headerValues = (string[])Request.Headers.GetValues("UniqueId");
string fileName = userprofile.UserCode + ".jpg";
string fullPath = Path.Combine(filePath, fileName);
image.Save(fullPath);
}
}
return result;
}

How can improve this Linq query expressions performance?

public bool SaveValidTicketNos(string id,string[] ticketNos, string checkType, string checkMan)
{
bool result = false;
List<Carstartlistticket>enties=new List<Carstartlistticket>();
using (var context = new MiniSysDataContext())
{
try
{
foreach (var ticketNo in ticketNos)
{
Orderticket temp = context.Orderticket.ByTicketNo(ticketNo).SingleOrDefault();
if (temp != null)
{
Ticketline ticketline= temp.Ticketline;
string currencyType = temp.CurrencyType;
float personAllowance=GetPersonCountAllowance(context,ticketline, currencyType);
Carstartlistticket carstartlistticket = new Carstartlistticket()
{
CsltId = Guid.NewGuid().ToString(),
Carstartlist = new Carstartlist(){CslId = id},
LeaveDate = temp.LeaveDate,
OnPointName = temp.OnpointName,
OffPointName = temp.OffpointName,
OutTicketMan = temp.OutBy,
TicketNo = temp.TicketNo,
ChekMan = checkMan,
Type = string.IsNullOrEmpty(checkType)?(short?)null:Convert.ToInt16(checkType),
CreatedOn = DateTime.Now,
CreatedBy = checkMan,
NumbserAllowance = personAllowance
};
enties.Add(carstartlistticket);
}
}
context.BeginTransaction();
context.Carstartlistticket.InsertAllOnSubmit(enties);
context.SubmitChanges();
bool changeStateResult=ChangeTicketState(context, ticketNos,checkMan);
if(changeStateResult)
{
context.CommitTransaction();
result = true;
}
else
{
context.RollbackTransaction();
}
}
catch (Exception e)
{
LogHelper.WriteLog(string.Format("CarstartlistService.SaveValidTicketNos({0},{1},{2},{3})",id,ticketNos,checkType,checkMan),e);
context.RollbackTransaction();
}
}
return result;
}
My code is above. I doubt these code have terrible poor performance. The poor performance in the point
Orderticket temp = context.Orderticket.ByTicketNo(ticketNo).SingleOrDefault();
,actually, I got an string array through the method args,then I want to get all data by ticketNos from database, here i use a loop,I know if i write my code like that ,there will be cause performance problem and it will lead one more time database access,how can avoid this problem and improve the code performance,for example ,geting all data by only on databse access
I forget to tell you the ORM I use ,en ,the ORM is PlinqO based NHibernate
i am looking forward to having your every answer,thank you
using plain NHibernate
var tickets = session.QueryOver<OrderTicket>()
.WhereRestrictionOn(x => x.TicketNo).IsIn(ticketNos)
.List();
short? type = null;
short typeValue;
if (!string.IsNullOrEmpty(checkType) && short.TryParse(checkType, out typeValue))
type = typeValue;
var entitiesToSave = tickets.Select(ticket => new Carstartlistticket
{
CsltId = Guid.NewGuid().ToString(),
Carstartlist = new Carstartlist() { CslId = id },
LeaveDate = ticket.LeaveDate,
OnPointName = ticket.OnpointName,
OffPointName = ticket.OffpointName,
OutTicketMan = ticket.OutBy,
TicketNo = ticket.TicketNo,
ChekMan = checkMan,
CreatedOn = DateTime.Now,
CreatedBy = checkMan,
Type = type,
NumbserAllowance = GetPersonCountAllowance(context, ticket.Ticketline, ticket.CurrencyType)
});
foreach (var entity in entitiesToSave)
{
session.Save(entity);
}
to enhance this further try to preload all needed PersonCountAllowances

how to send multiple variables from servlet as response to ajax post?

I am developing a testing system with jsp and java
At client side i have the following code:
var xmlhttp = new getXmlHttpRequestObject(); //xmlhttp holds the ajax object
function servletPost() {
if(xmlhttp) {
//var txtname = document.getElementById("testForm");
var form = $('#testForm');
xmlhttp.open("POST","servlet/TestingController",true);
xmlhttp.onreadystatechange = handleServletPost;
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlhttp.send(form.serialize());
}
}
function handleServletPost() {
//var qComplexity = document.getElementsByName("qComplexity")[0].value;
if (xmlhttp.readyState == 4) {
if(xmlhttp.status == 200) {
var respText = xmlhttp.responseText;
document.getElementById("fullQuestion").innerHTML = respText;
// here i also should change the content of the answer options
// so i should get from servlet multiple variables
// which allows me to change div contents in my jsp like as respText.question or respText.answer[0]
} else {
alert("Ajax calling error");
}
}
}
At server side: (my Servlet)
public void doPost (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
.........................................................
.........................................................
PrintWriter out = res.getWriter();
String complex = null;
int categ_id = -1;
String asked_by = null;
String Qtext = null;
int qid = -1;
q_numb = 1;
q_numb++;
String sqlSelect = "SELECT * FROM questions WHERE complexity = '" + complexity
+ "'ORDER BY RANDOM() LIMIT 1;";
ResultSet r = myConnection.runQuery( sqlSelect );
session.setAttribute("member", tempMem);
while (r.next()) {
complex = r.getString(5);
categ_id = r.getInt(4);
asked_by = r.getString(3);
Qtext = r.getString(2);
qid = r.getInt(1);
String sqlA = "select * from answers where question_id = '" + qid
+ "' ORDER by RANDOM();";
ResultSet result = myConnection.runQuery( sqlA );
session.setAttribute("member", tempMem); }
So i need to send values of complex, Qtext, qid, categ_id and so on.
Is there any structures to send like from ajax to servlet, but visa versa?
And how to handle sent data in client side?
Thanks in advance!!!!
Use JSON. There are a myriad of free Java JSON marshallers. And JSON is natively supported by JavaScript.

Resources