Serialize data using Protobuf-Net in asp.net - c#

I am new to web applications and to be hones I am trying to update an old web-application, trying to speed it up.
I analyze the application and see what's the reason of the slow in loading pages..
Of course it's the http-requests and I tried to read how can I speed up the requests and I found that I should serialize the data but I don't know how to do that in my application. So I need someone to tell me how to use serialization or how can I speed up the request please:
first it uses angular-js so the request is like that:
viewModelHelper.apiPost('Book/book_getList', null,
function (result) {
$scope.gridOptions.data = result.data;
});
and I use simillar methods to have the data...
The viewModelHelper.apiPost in the app.js:
self.apiPost = function (uri, data, success, failure, always) {
self.modelIsValid = true;
$http.post(MyApp.rootPath + uri, data)
.then(function (result) {
success(result);
if (always != null)
always();
}, function (result) {
if (failure != null) {
failure(result);
}
else {
var errorMessage = result.status + ':' + result.statusText;
if (result.data != null) {
if (result.data.Message != null)
errorMessage += ' - ' + result.data.Message;
if (result.data.ExceptionMessage != null)
errorMessage += ' - ' + result.data.ExceptionMessage;
}
}
if (always != null)
always();
});
}
And then let's say in the bookController there is book_getList method:
public JsonResult book_getList()
{
List<BookModels> List = obj.book_getList();
return Json(List, JsonRequestBehavior.AllowGet);
}
And the bookModels have properties like this:
public Guid guid_book_id { get; set; }
public string code { get; set; }
public string closet { get; set; }
public string shelf { get; set; }
public string title { get; set; }
And the method get_list:
public List<BookModels> book_getList()
{
try
{
OpenCon();
List<BookModels> List = con.Query<BookModels>("book_getList", param: null, commandType: CommandType.StoredProcedure).ToList();
return List.ToList();
}
catch (Exception)
{
throw;
}
finally
{
CloseCon();
}
}
Thanks

Related

Cannot store values of table within instance fields of a custom class

I have a video class called VideoClass.
And I created a method GetVideoLinkAndDuration() to retrieve 2 values from videos_tbl from DB & store them in instance fields of VideoClass. Just the normal stuff.
Error: Cannot implicitly convert type "project.DataLayer.videos_tbl" to "project.BusinessLayer.VideoClass"
I would've solved it with videos_tbl video = new videos_tbl; But I need to store db values in custom fields of the custom class as usual (embedURL & vid_duration). How to do so?
Below are the Class I have, then the Method I created which has the error.
public class VideoClass
{
public string embedURL { get; set; }
public string vid_duration { get; set; }
}
public Video GetVideoLinkAndDuration(int videoID)
{
testDB db = null;
int postID = videoID;
VideoClass video = null;
try
{
db = new testDB();
video = new VideoClass()
//~~~~ERROR IN BELOW LINE~~~~
video = db.videos_tbl.Where(x => x.pos_id == postID && x.vid_is_active == true && x.vid_is_deleted == false).FirstOrDefault();
if (video != null)
{
if (video.key != null)
{
video.embedURL = video.resolution240;
video.vid_duration = video.resolution360;
}
else
{
video.embedURL = Utils.GetResultIfNotNull(video.mp4);
}
}
}
catch (Exception ex)
{
err.LogErrors(ex.Message, "GetVideoLinkAndDuration", ex.ToString());
}
return video;
}

Iteration cannot operate on variables of type public definition for 'getenumerator'

I am doing a search in which I am making an API call and get the XML response and SerializeXmlNode and DeserializeObject to my root object. Now the problem is when I tried to loop with foreach.
I get this error below:
foreach statement cannot operate on variables of type (Model.AccountLite) because does not contain public instance definition for 'getenumerator'
I have inspected this data = JsonConvert.DeserializeObject(json); and i can see the data.
I have tried to look at this previously asked question
Search API call
public static List<AccountLite> searchAccounts(string searchString)
{
List<AccountLite> result = new List<AccountLite>();
Root data = new Root();
string[] contains = searchString.Split(' ');
RestClient client = new RestClient(baseUrl);
foreach (string contain in contains)
{
if (contain.Length < 3) continue;
RestRequest request = new RestRequest($"/xx/xx/xx/xxx/xxx/account?xx=Lite&searchString={searchString}");
String encoded = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + password));
request.AddHeader("Authorization", "Basic " + encoded);
IRestResponse response = client.Execute(request);
string requestResponse = response.Content;
//Converting data from XML into Json and deserializet json object
try
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(requestResponse);
string json = JsonConvert.SerializeXmlNode(doc);
data = JsonConvert.DeserializeObject<Root>(json);
}
catch (Exception)
{
continue;
}
if (data?.SiebelMessageEnvelope?.ListOfAccountLite?.AccountLite == null)
continue;
//this line is the one showing error.
foreach (AccountLite item in data.SiebelMessageEnvelope.ListOfAccountLite.AccountLite)
{
bool containsBoth = true;
foreach (string contain2 in contains)
{
if (!item.Name.ToLower().Contains(contain2.ToLower()) && !item.Id.ToLower().Contains(contain2.ToLower()))
containsBoth = false;
}
if (containsBoth)
{
if (result.FirstOrDefault(i => i.Id == item.Id) == null)
{
result.Add(item);
}
}
}
}
return result;
}
Model
public class AccountLite
{
public string Id { get; set; }
public string AccountStatus { get; set; }
public string AccountTypeCode { get; set; }
public string Location { get; set; }
public string Name { get; set; }
public string SRIntegrationFlag { get; set; }
}
public class ListOfAccountLite
{
public AccountLite AccountLite { get; set; }
}
public class SiebelMessageEnvelope
{
[JsonProperty("#xmlns")]
public string Xmlns { get; set; }
public ListOfAccountLite ListOfAccountLite { get; set; }
}
public class Root
{
public SiebelMessageEnvelope SiebelMessageEnvelope { get; set; }
}
Json Object
{
"SiebelMessageEnvelope":{
"#xmlns":"",
"ListOfAccountLite":{
"AccountLite":{
"Id":"",
"AccountStatus":"",
"AccountTypeCode":"",
"Location":"",
"Name":"",
"SRIntegrationFlag":""
}
}
}
}
Your ListOfAccountLite just contains a single AccountLite. It doesn't make sense to foreach over a single object, where that object is not enumerable (meaning: implemented IEnumerable[<T>] or contains an explicit GetEnumerator() method).
There's only one object, so... just take it. Instead of
if (data?.SiebelMessageEnvelope?.ListOfAccountLite?.AccountLite == null)
continue;
foreach (AccountLite item in data.SiebelMessageEnvelope.ListOfAccountLite.AccountLite)
{
// ... do the thing
}
simply
var item = data?.SiebelMessageEnvelope?.ListOfAccountLite?.AccountLite;
if (item is null)
continue;
// ... do the thing
That said: you should probably investigate whether ListOfAccountLite in the JSON etc is meant to be an array rather than a single object.

C# reference Error while setting value using GetType().GetTypeInfo().GetDeclaredProperty for existing Property [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 3 years ago.
I have a relatively simple console app (framework) which has a tightly coupled classes with properties and my main triggers an async task. These are my property classes:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net.Http; //for HTTP client
using System.Reflection;
using System.Threading.Tasks; //for Async Request/Response
using Newtonsoft.Json; //for JSON properties
namespace PSD2
{
[Serializable]
public class PS
{
public System.Uri BaseURL { get; set; } = new System.Uri("http://192.999.999.999:8888/some/url/here/");
public ConsHeaders Headers { get; set; }
public ConsBody Body { get; set; }
public consAttributes Attributes { get; set; }
}
[Serializable]
public partial class ConsHeaders
{
[JsonProperty("Core-ID")]
public string corID { get; set; }
[JsonProperty("PS-Token")]
public string PS_Token { get; set; }
[JsonProperty("Req-ID")]
public string reqID { get; set; }
}
[Serializable]
public partial class consAttributes
{
[JsonProperty("consId")]
public string consId { get; set; } = String.Empty;
[JsonProperty("consStatus")]
public string consStatus { get; set; } = String.Empty;
[JsonProperty("userName")]
public string userName { get; set; } = String.Empty;
};
[Serializable]
public partial class consBody
{
[JsonProperty("access")]
public AccessHeaders access { get; internal set; }
[JsonProperty("combinedServiceIndicator")]
public Boolean CombinedServiceIndicator { get; set; } = false;
[JsonProperty("frequencyPerDay")]
public int FrequencyPerDay { get; set; } = 4;
[JsonProperty("recurringIndicator")]
public Boolean RecurringIndicator { get; set; } = false;
[JsonProperty("validUntil")]
public string ValidUntil { get; set; } = "9999-12-31";
}
...
Now, my Program class creates an object and in Main I call a class called testing who has my logic behind, nothing more than populating the object properties with values, and calls a Task asycn which is also present inside. Code continues from above as:
public class Program
{
public static PS cnsnt = new PS();
public static void Main(string[] args)
{
Testing test = new Testing();
test.createCONS();
}
public class Testing
{
public void createCONS()
{
try
{
cnsnt.Headers = new ConsHeaders
{
corID = "Something",
reqID = "AnotherThing",
PS_Token = "myTokenValue"
};
cnsnt.Body = new ConsBody
{
access = new AccessHeaders
{
AllPsd2 = "allAccounts",
AvailableAccounts = "YES"
},
CombinedServiceIndicator = false,
FrequencyPerDay = 10,
ValidUntil = "2020-12-31"
};
cnsnt.Attributes = new consAttributes
{
consId = "",
_links_self_href = "",
consStatus = "",
status_href = "",
userName = ""
};
}
catch (System.Exception e)
{
throw new System.Exception("Error - Aborting..");
}
myConsAsync(cnsnt.BaseURL, cnsnt, HttpMethod.Post).GetAwaiter().GetResult();
}
public async static Task myConsAsync(Uri HTTPaddress, PS ConSent, HttpMethod httpMethod)
{
try
{
HttpClient client = new HttpClient();
System.Text.UTF8Encoding utf8 = new System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
using (HttpRequestMessage request = new HttpRequestMessage(httpMethod, HTTPaddress))
{
client.BaseAddress = HTTPaddress;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Connection", "keep-alive");
client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
//...
client.DefaultRequestHeaders.Add("Core-ID", ConSent.Headers.corID);
client.DefaultRequestHeaders.Add("Req-ID", ConSent.Headers.reqID);
client.DefaultRequestHeaders.Add("PS-Token", ConSent.Headers.PS_Token);
//...
request.Content = new StringContent(JsonConvert.SerializeObject(ConSent, Formatting.Indented), utf8, "application/json");
using (HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false))
{
response.EnsureSuccessStatusCode();
Int32 code = (Int32)response.StatusCode;
string responseBody = response.Content.ReadAsStringAsync().Result.ToString();
try
{
if (responseBody.Contains("consId"))
{
try
{
string responseValues = JSONtoKeyValue(responseBody);
var dict = responseValues.Split('|')
.Select(x => x.Split('='))
.Where(x => x.Length > 1
&& !String.IsNullOrEmpty(x[0].Trim())
&& !String.IsNullOrEmpty(x[1].Trim()))
.ToDictionary(x => x[0].Trim(), x => x[1].Trim());
foreach (KeyValuePair<string, string> entry in dict)
{
if (entry.Value == null)
{
dict.Remove(entry.Key);
}
else
{
string key = entry.Key;
string value = entry.Value;
try
{
if (cnsnt.Attributes.GetType().GetTypeInfo().GetDeclaredProperty(key) != null)
{
// ---> ERROR: Object reference not set to an instance of an object.
cnsnt.GetType().GetTypeInfo().GetDeclaredProperty(key).SetValue(cnsnt, entry.Value);
}
}
catch (System.Exception e)
{
Console.WriteLine("Failed during processing Property: " + e.Message);
}
}
}
Console.ReadLine();
}
catch (System.Exception e)
{
Console.WriteLine(e.StackTrace + "\r\n" + e.Message);
}
}
else
{
throw new System.Exception("Fatal error reading response body for the consent Id. Aborting..");
};
}
catch (System.Exception e)
{
Environment.Exit(13);
}
}
}
}
catch (Exception e)
{
//whatever, Console.WriteLine("Error in " + e.TargetSite + "\r\n" + e.Message + "\r\n" + e.Data);
}
//return
}
// this works as intended.. included just for completion
public static string JSONtoKeyValue(string pString)
{
pString.Trim();
if (pString == null)
{
return "";
}
else
{
pString = pString.Replace("\r\n", "|").Replace(":", "=").Replace("\"", "").Replace("{", "").Replace("}", "").Replace(",", "");
int j = 0, inputlen = pString.Length;
char[] newarr = new char[inputlen];
for (int i = 0; i < inputlen; ++i)
{
char tmp = pString[i];
if (!char.IsWhiteSpace(tmp))
{
newarr[j] = tmp; ++j;
}
}
return new String(newarr, 0, j).Replace("||", "|").Replace("||", "|").Replace("=|", "_").Trim('|');
}
}
}
}
}
Notice in the Task that I want to read a string separated with pipes (a small method does the work nicely) and I try to see if I have this property in my object, and if yes, to populate the value.
However, in line
ConSent.GetType().GetTypeInfo().GetDeclaredProperty(key).SetValue(cnsnt, entry.Value);
I get the error "Object reference not set to an instance of an object."
I struggle on this one, could someone help me?
You have made a simple mistake.
You check for
(cnsnt.Attributes.GetType().GetTypeInfo().GetDeclaredProperty(key) != null)
But then you assign with
ConSent.GetType().GetTypeInfo().GetDeclaredProperty(key).SetValue(cnsnt, entry.Value)
Just replace it with,
cnsnt.GetType().GetTypeInfo().GetDeclaredProperty(key).SetValue(cnsnt, entry.Value).
Note its cnsnt. Not ConSent.
and you'll be fine. Happy reflecting!
edit:
saw your edit, same thing.
cnsnt.Attributes.GetType().GetTypeInfo().GetDeclaredProperty(key)
cnsnt.GetType().GetTypeInfo().GetDeclaredProperty(key)
you are basically checking on a different bject if it has a property and then you try to set it on another.
Suggestion.
Why not go:
var keyProperty = cnsnt.Attributes.GetType().GetTypeInfo().GetDeclaredProperty(key);
if(keyProperty != null)
{
keyProperty.SetValue(cnsnt, entry.Value);
}
this way it will not fail, ever.

How to check if duplicate data is present in the database using asp.net mvc

I want to show a message saying that the JourneyID already exists in the database.
The model is :
using System.Web.Mvc;
namespace Project_Final.Models
{
using System;
public partial class sp_FMS_Group6_Module3_ViewBonusMilesRequesttt_Result
{
public int RequestID { get; set; }
public Nullable<long> CustomerID { get; set; }
[Remote("Check", "Home", ErrorMessage = "Bonus Miles Request has already been sent!")]
public Nullable<int> JourneyID { get; set; }
public Nullable<System.DateTime> RequestDate { get; set; }
public string Status { get; set; }
}
}
The following are the actions in my controller :
[HttpPost]
public ActionResult Index(string Create)
{
FMS_Group6_Module3_BonusMilesRequestt objProd = new FMS_Group6_Module3_BonusMilesRequestt();
objProd.CustomerID = int.Parse(Request.Form["CustomerID"].ToString());
objProd.JourneyID = int.Parse(Request.Form["JourneyID"].ToString());
objProd.RequestDate = DateTime.Parse(Request.Form["RequestDate"].ToString());
objProd.Status = "Pending";
objDB.FMS_Group6_Module3_BonusMilesRequestt.Add(objProd);
int i = objDB.SaveChanges();
if (i > 0)
ViewBag.Message = "Product details saved successfully";
return Content("<script language='javascript' type='text/javascript'>alert('Your Bonus Miles Request has been successfully sent!');window.location='/Home/GetID'</script>");
//return Redirect("GetID");
}
public ActionResult Check(string Crreate)
{
FMS_Group6_Module3_BonusMilesRequestt objProd = new FMS_Group6_Module3_BonusMilesRequestt();
bool ifJourneyIDExist = false;
try
{
ifJourneyIDExist = Crreate.Equals(objProd.JourneyID) ? true : false;
return Json(!ifJourneyIDExist, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
return Json(false, JsonRequestBehavior.AllowGet);
}
}
Any kind of help would be greatly appreciated. Thanks.
Before you insert, you can check in the DB, if the JourneyID is exists.
if (objDB.FMS_Group6_Module3_BonusMilesRequestt.Any(x => x.JourneyID == objProd.JourneyID))
{
// Exists
}
LINQ query to make sure all values (ex enumerable) are not duplicated
var noDuplicationVariable = enumerableValues.GroupBy(a => a.Key).All(b => b.Count() == 1);
use it as an assertion condition before your function

Get exception details

I would like to have a function that when an exception is given to it, it will extract all the information about that exception and then write it to a database.
Before going to .NET Core 2, I was able to do this in the following manner:
var details = new ErrorDetails();
if (ex == null) return details;
var st = new StackTrace(ex, true);
var frames = st.GetFrames();
if (frames != null && frames.Length > 0)
{
var errorDetails = frames.Select(frame => new ErrorDetails
{
FileName = frame.GetFileName(),
LineNumber = frame.GetFileLineNumber().ToString(),
MethodName = frame.GetMethod().Name,
ClassName = frame.GetMethod().DeclaringType.FullName
});
return errorDetails.FirstOrDefault();
}
return details;
Ever since switching my project to .NET Core 2, this code comes back with most of this information being null/default; I took a look at the frames that I extract, and they don't have the information anymore. For things like FileName and LineNumber, the values are null. For things like MethodName and ClassName, the value is there but wrong.
I would crash my project with code such as this:
public class TestController : Controller
{
[HttpGet]
[AllowAnonymous]
public string ErrorHandling()
{
var a = int.Parse("fail parsing on purpose");
return a.ToString();
}
}
The value for MethodName ends up being StringToNumber and for ClassName is System.Number
I can't seem to find any information on the web as to why this is and how I can go about retrieving the details for the exception.
EDIT:
I thought it might also be useful to list how I am handling exceptions. I have written a custom middleware error exception handler very similar to the one in this SO post:
https://stackoverflow.com/a/48625298/2371128
EDIT 2:
This is being run in DEBUG mode.
Add the following to your Startup.cs
app.UseExceptionHandler(
options =>
{
options.Run(
async context =>
{
var ex = context.Features.Get<IExceptionHandlerFeature>();
if (ex != null)
{
try
{
await System.Threading.Tasks.Task.Run(async () =>
{
var builder = new DbContextOptionsBuilder<DBContext>();
builder.UseSqlServer(_config["ConnectionStrings:ContextConnection"]);
var _context = new DBContext(_config, builder.Options, httpContextAccessor);
//Log to DB
await repository.LogError(_context, ex.Error.Message, $"{ex.Error.InnerException?.Message}<br/>{ex.Error.StackTrace}");
});
}
finally
{
//Optional
await repository.SendMailToAdmin(ex.Error.Message, $"{ex.Error.InnerException?.Message}<br/>{ex.Error.StackTrace}");
}
context.Response.Redirect("/app/Errors/500");
}
});
}
);
//ErrorLog.cs
public class ErrorLog
{
public int Id { get; set; }
[Required]
[StringLength(500)]
public string Error { get; set; }
[Required]
[StringLength(4000)]
public string Details { get; set; }
public int? UserId { get; set; }
public int CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
}
Here is my suggestion:
public class ExceptionDetail
{
public string Message { get; set; }
public string InnerExceptionMessage { get; set; }
public string StackTrace { get; set; }
public IEnumerable<string> StackTraceLines { get; set; }
public string Target { get; set; }
public string Source { get; set; }
}
var exDetail = new ExceptionDetail
{
Message = exception.Message,
InnerExceptionMessage = exception.InnerException?.Message,
Source = exception.Source,
StackTrace = exception.StackTrace,
StackTraceLines = exception.StackTrace.Split(new[] { Environment.NewLine }, StringSplitOptions.None).ToList(),
Target = exception.TargetSite.ToString()
};

Categories

Resources