ASP.NET - Automapper not working on productive IIS - asp.net

I'm mapping data using Automapper in my ASP.NET MVC4 Application's from my domain model onto my view model.
On my development machine with the integrated IIS this works perfectly, however when deploying it to the real IIS, suddenly my code only maps the data seemingly on arbitrary occasions.
It seems that the mapping works once after redeploying the application and sometimes after attaching the remote debugger.
My code is:
iPXE dbCon = new iPXE();
Models.Device bootDevice = dbCon.Devices.SingleOrDefault(d => d.serial == serial);
var imagePredicate = PredicateBuilder.False<Models.Image>();
imagePredicate = imagePredicate.Or(d => d.anyboot == true); // Images everyone can boot
if (bootDevice != null) // If the boot device is in the database
{
imagePredicate = imagePredicate.Or(d => d.Devices.Any(e => e.id == bootDevice.id)); // Retrieve all images assigned to the device
}
IEnumerable<Models.Image> allowedImages = dbCon.Images.AsExpandable().Where(imagePredicate);
Mapper.CreateMap<Models.Category, Category>()
.ForMember(x => x.name, opt => opt.MapFrom(src => src.CategoryTranslations.SingleOrDefault(d => d.locale == locale) == null || // Either no translation row found
src.CategoryTranslations.SingleOrDefault(d => d.locale == locale).name != null ? // Or specific value is null
src.name : // Then use name from main table (untranslated)
src.CategoryTranslations.SingleOrDefault(d => d.locale == locale).name)) // Otherwise use translated value
.ForMember(x => x.images, opt => opt.MapFrom(src => allowedImages.Intersect(src.Images)));
Mapper.CreateMap<Models.Image, Image>()
.ForMember(x => x.description, opt => opt.MapFrom(src => src.ImageTranslations.SingleOrDefault(d => d.locale == locale) == null ||
src.ImageTranslations.SingleOrDefault(d => d.locale == locale).description == null ?
src.description :
src.ImageTranslations.SingleOrDefault(d => d.locale == locale).description))
.ForMember(x => x.code, opt => opt.MapFrom(src => src.ImageTranslations.SingleOrDefault(d => d.locale == locale) == null ||
src.ImageTranslations.SingleOrDefault(d => d.locale == locale).code == null ?
src.code :
src.ImageTranslations.SingleOrDefault(d => d.locale == locale).code));
categories = Mapper.Map<IEnumerable<Models.Category>, List<Category>>(allowedImages.Select(c => c.Category1).Distinct());
public class Category
{
public string name { get; set; }
public List<Image> images { get; set; }
}
public class Image
{
public string tag { get; set; }
public string description { get; set; }
public string code { get; set; }
}
What I'm doing is basically getting a device from the database, getting all assigned images for the device (N:M) and then creating Automapper-Maps for categories and images that belong to the device.
The exact problem is that on the productive server, the images-Lists of the category objects stay empty, even though there is data in allowedImages (5 images), bootDevice (the device data) and allowedImages.Select(c => c.Category1).Distinct() (2 categories).
I'm using the same SQL server for both my machine and the server. If you need any more information, please feel free to ask.

You are calling 'CreateMap' each time the method runs. As I understand, you should only do this once within your application domain. Try moving the CreateMap logic to where it gets called from Application_OnStart to see if that gives you more consistent behavior.
Also, the line:
.ForMember(x => x.images, opt => opt.MapFrom(src => allowedImages.Intersect(src.Images)));
may be troubling you. You may need to change that to an AfterMap that calls a static method that performs the Intersect on your source & destination collections.

Related

Getting null values from Model while there are records

This is where i am doing the Query i am getting null values on using dynamic query
var responsedata = await _elasticClient.SearchAsync<Acquirer>(s => s
.Query(q => q.ConstantScore(cs => cs.Filter(
f =>
f.Term("MERCHANTNO.keyword", MerchantNo)
)))
);
This is my model
public class Acquirer
{
public string MERCHANTNO { get; set; }
}
This is where index mapping is done
client.Map<Acquirer>(m =>
{
var putMappingDescriptor = m.Index(Indices.Index("acquiringdata")).AutoMap();
return putMappingDescriptor;
});
I am getting the exact number of records but i am getting the null values
This Error can be Resolved by using this
[PropertyName("MERCHANTNO")]

Complex LINQ query - multiple table relationships

I have a books database, which has an ICollection of authors. I want to return the author object based on the AuthorId using LINQ.
Book db
int BookId
string Name { get; set; }
public ICollection<Author> Authors { get; set; }
Author db
int AuthorId
string Name
ICollection<Quote> Quotes { get; set; }
ICollection<Penname> Pennames { get; set; } - Edit: Added for clarity
I have tried:
var test = _context.Book.Include(x => x.Authors).Include("Authors.Quotes")
.Select(y => y.Authors)
Which gave me:
EntityQueryable<ICollection<Authors>>
[0] {HashSet<Author>} [0]{Author} [1]{Author} [3]{Author}
[1] {HashSet<Author>} [0]{Author} [1]{Author}
[2] {HashSet<Author>} [0]{Author} [1]{Author}
I just can't figure out how to iterate though the Authors in the Authors list. Something like the below:
var id = 2
var test = _context.Book.Include(x => x.Authors).Include("Authors.Quotes")
.Select(y => y.Authors.Select(x => x.Author).Where(x => x.AuthorId == id))
If I ever do a major update I might use elastic...
Update #Marko Papic:
Thanks. Weirdly if I use the below to get a list of books with authors, I get the quotes and pennames lists populated as I expect
var test = _context.Book.Include(x => x.Authors)
.ThenInclude(x => x.Quotes)
.Include(x => x.Authors)
.ThenInclude(x => x.Pennames)
However if I use SelectMany, then the quotes and pennames end up as null
var test = _context.Book.Include(x => x.Authors)
.ThenInclude(x => x.Quotes)
.Include(x => x.Authors)
.ThenInclude(x => x.Pennames)
.SelectMany(x => x.Authors).Where(x => x.AuthorId == id);
Author myauthor
int AuthorId = 2
string Name = "Bob"
ICollection<Quote> Quotes = null
ICollection<Penname> Pennames = null
You can use SelectMany:
var test = _context.Book.Include(x => x.Authors).ThenInclude(x => x.Quotes)
.SelectMany(x => x.Authors).Where(x => x.AuthorId == id);
I think the includes are ignored because the result type of the query is not the same of the type of your dbset with when you start, from the documentation:
If you change the query so that it no longer returns instances of the
entity type that the query began with, then the include operators are
ignored.
I assume the relationship between Books and Authors is many to many, if that is the case then this is how I would do your query:
var query=_context.Authors.Include(a=>a.Books)
.Include(a=>a.Quotes)
.Include(a=>a.Pennames)
.Where(a=> a.AuthorId == id);

PayUMoney - Android: Only getting **paymentId** from payUMoney SDK after successful payment

I'm integrating payUMoney in my Android application. I'm getting only paymentId after successful payment in both environment i.e Test & Production. I need Transaction Details as well from payUMoney. I have also contacted payUMoney technical team but not getting any response.
See image attached for payUMoney response which I have printed in Logcat.
What I have tried is like below.
public void makePayment() {
String phone = "8882434664";
String productName = "product_name";
String firstName = "piyush";
String txnId = "0nf7" + System.currentTimeMillis();
String email = "piyush.jain#payu.in";
String sUrl = AppConstant.BASE_URL + "/mob-payment/success";
String fUrl = AppConstant.BASE_URL + "/mob-payment/failure";
String udf1 = "";
String udf2 = "";
String udf3 = "";
String udf4 = "";
String udf5 = "";
boolean isDebug = true;
String key = "dRQuiA";
String merchantId = "4928174";
PayUmoneySdkInitilizer.PaymentParam.Builder builder = new PayUmoneySdkInitilizer.PaymentParam.Builder();
builder.setAmount(1.0)
.setTnxId(txnId)
.setPhone(phone)
.setProductName(productName)
.setFirstName(firstName)
.setEmail(email)
.setsUrl(sUrl)
.setfUrl(fUrl)
.setUdf1(udf1)
.setUdf2(udf2)
.setUdf3(udf3)
.setUdf4(udf4)
.setUdf5(udf5)
.setIsDebug(isDebug)
.setKey(key)
.setMerchantId(merchantId);
PayUmoneySdkInitilizer.PaymentParam paymentParam = builder.build();
calculateServerSideHashAndInitiatePayment(paymentParam);
}
private void calculateServerSideHashAndInitiatePayment(final PayUmoneySdkInitilizer.PaymentParam paymentParam) {
String url = "https://test.payumoney.com/payment/op/calculateHashForTest";
StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.has(SdkConstants.STATUS)) {
String status = jsonObject.optString(SdkConstants.STATUS);
if (status != null || status.equals("1")) {
String hash = jsonObject.getString(SdkConstants.RESULT);
paymentParam.setMerchantHash(hash);
PayUmoneySdkInitilizer.startPaymentActivityForResult(ActivityConfirmOrder.this, paymentParam);
} else {
Toast.makeText(ActivityConfirmOrder.this,
jsonObject.getString(SdkConstants.RESULT),
Toast.LENGTH_SHORT).show();
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if (error instanceof NoConnectionError) {
Toast.makeText(ActivityConfirmOrder.this,
ActivityConfirmOrder.this.getString(R.string.connect_to_internet),
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ActivityConfirmOrder.this,
error.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
return paymentParam.getParams();
}
};
Volley.newRequestQueue(this).add(jsonObjectRequest);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PayUmoneySdkInitilizer.PAYU_SDK_PAYMENT_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
StringBuilder str = new StringBuilder();
Bundle bundle = data.getExtras();
if (bundle != null) {
Set<String> keys = bundle.keySet();
Iterator<String> it = keys.iterator();
while (it.hasNext()) {
String key = it.next();
str.append(key);
str.append(":");
str.append(bundle.get(key));
str.append("\n\r");
}
Log.e("res: ", str.toString());
}
} else if (resultCode == RESULT_CANCELED) {
} else if (resultCode == PayUmoneySdkInitilizer.RESULT_FAILED) {
if (data != null) {
if (data.getStringExtra(SdkConstants.RESULT).equals("cancel")) {
} else {
}
}
} else if (resultCode == PayUmoneySdkInitilizer.RESULT_BACK) {
}
}
}
PayUMoney SDK-Version: versionName "6.1.0"
I was also facing the same problem, but after little bit of research, I have found that we need to generate invoice separately using different invoice api. You can find the bellow URL for the documentation for invoice api...
https://www.payumoney.com/dev-guide/products/invoicing.html
#MaulikDodia Actually you need to create success url on your own, then the payumoney will send all the data directly like this in your success url...
Array
(
[mihpayid] => 40399371551*******
[mode] => DC
[status] => success
[unmappedstatus] => captured
[key] => d****A
[txnid] => INV0****0531
[amount] => 1000.0
[addedon] => 2017-05-31 13:16:12
[productinfo] => ****
[firstname] => ****
[lastname] =>
[address1] =>
[address2] =>
[city] => null
[state] =>
[country] => null
[zipcode] =>
[email] => ***#test.xxx
[phone] =>
[udf1] =>
[udf2] =>
[udf3] =>
[udf4] =>
[udf5] =>
[udf6] =>
[udf7] =>
[udf8] =>
[udf9] =>
[udf10] =>
[hash] => ***************
[field1] => 715140****61
[field2] => 99***9
[field3] => 8523310*****511
[field4] => -1
[field5] =>
[field6] =>
[field7] =>
[field8] =>
[field9] => SUCCESS
[PG_TYPE] => HDFCPG
[encryptedPaymentId] => DB****EB8****02A****9FE4C****CB3
[bank_ref_num] => 8****016137****
[bankcode] => MAST
[error] => E000
[error_Message] => No Error
[name_on_card] => payu
[cardnum] => 512345XXXXXXXX46
[cardhash] => This field is no longer supported in postback params.
[amount_split] => {"PAYU":"1000.0"}
[payuMoneyId] => 1******0
[discount] => 0.00
[net_amount_debit] => 1000
)
Then you can generate invoice using that on the server side or do whatever you want.
Source: I have done all the code and it is working. Hope it helps... thanks

Showing linked table items in a controller/view

I have a room class, which has 3 linked tables, Property, Sex (as in Male/Female), Stage.
I can get the Index controller to return the linked table items, by using Include:
var rooms = db.Rooms.Include(r => r.Property).Include(r => r.Sex).Include(r => r.Stage);
What I don't know is, how to you include these linked table items in the Details controller:
Room room = db.Rooms.Find(id);
The full controllers are listed below:
//
// GET: /Room/
public ActionResult Index()
{
var rooms = db.Rooms.Include(r => r.Property).Include(r => r.Sex).Include(r => r.Stage);
return View(rooms.ToList());
}
//
// GET: /Room/Details/5
public ActionResult Details(int id = 0)
{
Room room = db.Rooms.Find(id);
if (room == null)
{
return HttpNotFound();
}
return View(room);
}
Thanks for any help,
Mark
After Include statments you could use LINQ's SingleOrDefault method
Like this:
Room room = db.Rooms.Include(r => r.Property)
.Include(r => r.Sex)
.Include(r => r.Stage)
.SingleOrDefault(r => r.Id = id);

get all the values in Sql table using foreach

I need to get all the Ids' from the table "StaffSectionInCharge", it has only two columns StaffId and SectionId, I have values of StaffId and StudentId.....the problem is I can't get the records directly to this table.....am using entity framework and the design of this table is
[EdmRelationshipNavigationPropertyAttribute("Model", "StaffSectionInCharge", "Section")]
public EntityCollection<Section> Sections
{
get
{
return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<Section>("Model.StaffSectionInCharge", "Section");
}
set
{
if ((value != null))
{
((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<Section>("Model.StaffSectionInCharge", "Section", value);
}
}
}
I can access this table through staff table like
Staff staff = buDataEntities.Staffs.First(s => s.StaffId == StaffId);
Section section = buDataEntities.Sections.First(s => s.SectionId == SectionId);
staff.Sections.Add(section);
buDataEntities.savechanges();
like this I can add the records to this StaffSectionInCharge table....
here I want to get all the StaffIds for the corresponding SectionId
I tried getting like
DataAccess.Staff staffs = new DataAccess.Staff();
foreach (int staff in staffs.Sections.Select(s=>s.SectionId))
{
}
but its not working, can anyone help me here
var staffIds = buDataEntities.Staffs
.Where(st => st.Sections.Any(se => se.SectionId == SectionId))
.Select(st => st.StaffId)
.ToList();
or
var staffIds = buDataEntities.Sections
.Where(se => se.SectionId == SectionId)
.SelectMany(se => se.Staffs.Select(st => st.StaffId))
.Distinct()
.ToList();
Both options should work. If SectionId is the primary key of Section you can smplify the second code to:
var staffIds = buDataEntities.Sections
.Where(se => se.SectionId == SectionId)
.Select(se => se.Staffs.Select(st => st.StaffId))
.SingleOrDefault();

Resources