It throws an stackoverflow exception when I user PropertyInfo.SetValue() - asp.net

When I use PropertyInfo.SetValue in asp.net , it throws a stackoverflow exception.
That I write this code:
for (int i = 0; i < rivalSeriesIDList.Count; i++)
{
cardb_series rivalSeries = seriesBll.GetSeriesInfoByID(rivalSeriesIDList[i].ToString());
this.GetType().GetProperty("brandid" + (i + 1)).SetValue(this, rivalSeries.brand_id, null);
this.GetType().GetProperty("seriesid" + (i + 1)).SetValue(this, rivalSeries.series_id, null);
}
And brandid+number and seriesid+number is a property of aspx_page. like this:
public int brandid1
{
get
{
if (Request.Form["brandid1"] != null)
return int.Parse(Request.Form["brandid1"]);
if (Request["brandid1"] != null)
return int.Parse(Request["brandid1"]);
return 0;
}
set
{
brandid1 = value;
}
}
when I test the code in a Console Application ,It is all right . But when I test it in a Web Application ,it will cause a stack overflow exception .
I don't know why. Because of web is no-state?
Thanks.

cause you call your property recursively, and will get the same exception even if you will call the property directly
public int brandid1 <- this one
{
get
{
if (Request.Form["brandid1"] != null)
return int.Parse(Request.Form["brandid1"]);
if (Request["brandid1"] != null)
return int.Parse(Request["brandid1"]);
return 0;
}
set
{
and this one -> brandid1 = value;
}
}
I don't know what do you want to do, but try this
private int _brandid1;
public int brandid1 <- this one
{
get
{
if (Request.Form["brandid1"] != null)
return int.Parse(Request.Form["brandid1"]);
if (Request["brandid1"] != null)
return int.Parse(Request["brandid1"]);
return 0;
}
set
{
_brandid1 = value;
}
}

Related

Wso2 Stream Processor : Error occurred while processing eventByteBufferQueue

I have two nodes of wso2-am analytics server (2.6.0) which is Wso2 Stream processors. I see following error on passive node of cluster. The active node is fine and I don't see any error. Analytics result has no impact for users who is viewing data on API Publisher or Store. however there is an error in passive node.
please advise what is causing following issue..
2019-02-26 17:06:09,513] ERROR {org.wso2.carbon.stream.processor.core.ha.tcp.EventSyncServer} - Error occurred while processing eventByteBufferQueue null java.nio.BufferUnderflowException
Just meet the same issue, here is my problem and solution.
1) Using the WSO2 SP HA deployment.
2) When Event come in active node and according the source mapping of the streaming, some fields are NULL
3) Active Node would like sync this event to passive node
4) passive node pick up the event data from the 'eventByteBufferQueue' to meet the standby-take over mechanism
5) passive node cannot parse the data from active node and reports error exception.
the root cause is SP only support NULL String by default, when NULL with LONG, INTEGER.. the error occurred. but for me, Long fields have NULL is the normal case, you can change data type to string.
here is my solution:
org.wso2.carbon.stream.processor.core_2.0.478.jar
Add logic to support NULL
BinaryMessageConverterUtil.java for sending event data from active node
public final class BinaryMessageConverterUtil {
public static int getSize(Object data) {
if (data instanceof String) {
return 4 + ((String) data).length();
} else if (data instanceof Integer) {
return 4;
} else if (data instanceof Long) {
return 8;
} else if (data instanceof Float) {
return 4;
} else if (data instanceof Double) {
return 8;
} else if (data instanceof Boolean) {
return 1;
} else if (data == null) {
return 0;
}else {
//TODO
return 4;
}
}
public static EventDataMetaInfo getEventMetaInfo(Object data) {
int eventSize;
Attribute.Type attributeType;
if (data instanceof String) {
attributeType = Attribute.Type.STRING;
eventSize = 4 + ((String) data).length();
} else if (data instanceof Integer) {
attributeType = Attribute.Type.INT;
eventSize = 4;
} else if (data instanceof Long) {
attributeType = Attribute.Type.LONG;
eventSize = 8;
} else if (data instanceof Float) {
attributeType = Attribute.Type.FLOAT;
eventSize = 4;
} else if (data instanceof Double) {
attributeType = Attribute.Type.DOUBLE;
eventSize = 8;
} else if (data instanceof Boolean) {
attributeType = Attribute.Type.BOOL;
eventSize = 1;
} else if (data == null){
attributeType = Attribute.Type.OBJECT;
eventSize = 0; //'no content between the HA nodes for NULL fields'
} else {
//TODO
attributeType = Attribute.Type.OBJECT;
eventSize = 1;
}
return new EventDataMetaInfo(eventSize, attributeType);
}
public static void assignData(Object data, ByteBuffer eventDataBuffer) throws IOException {
if (data instanceof String) {
eventDataBuffer.putInt(((String) data).length());
eventDataBuffer.put((((String) data).getBytes(Charset.defaultCharset())));
} else if (data instanceof Integer) {
eventDataBuffer.putInt((Integer) data);
} else if (data instanceof Long) {
eventDataBuffer.putLong((Long) data);
} else if (data instanceof Float) {
eventDataBuffer.putFloat((Float) data);
} else if (data instanceof Double) {
eventDataBuffer.putDouble((Double) data);
} else if (data instanceof Boolean) {
eventDataBuffer.put((byte) (((Boolean) data) ? 1 : 0));
} else if (data == null){
//put nothing into he Buffer
} else {
eventDataBuffer.putInt(0);
}
}
public static String getString(ByteBuf byteBuf, int size) throws UnsupportedEncodingException {
byte[] bytes = new byte[size];
byteBuf.readBytes(bytes);
return new String(bytes, Charset.defaultCharset());
}
public static String getString(ByteBuffer byteBuf, int size) throws UnsupportedEncodingException {
byte[] bytes = new byte[size];
byteBuf.get(bytes);
return new String(bytes, Charset.defaultCharset());
}
}
SiddhiEventConverter.java for processing event data at passive node
static Object[] toObjectArray(ByteBuffer byteBuffer,
String[] attributeTypeOrder) throws UnsupportedEncodingException {
if (attributeTypeOrder != null) {
Object[] objects = new Object[attributeTypeOrder.length];
for (int i = 0; i < attributeTypeOrder.length; i++) {
switch (attributeTypeOrder[i]) {
case "INT":
objects[i] = byteBuffer.getInt();
break;
case "LONG":
objects[i] = byteBuffer.getLong();
break;
case "STRING":
int stringSize = byteBuffer.getInt();
if (stringSize == 0) {
objects[i] = null;
} else {
objects[i] = BinaryMessageConverterUtil.getString(byteBuffer, stringSize);
}
break;
case "DOUBLE":
objects[i] = byteBuffer.getDouble();
break;
case "FLOAT":
objects[i] = byteBuffer.getFloat();
break;
case "BOOL":
objects[i] = byteBuffer.get() == 1;
break;
case "OBJECT":
//for NULL fields
objects[i] = null;
break;
default:
// will not occur
}
}
return objects;
} else {
return null;
}
}

ASP.NET MVC - Session Variables are null in Callback from server ActionResult method

I am implementing CoinPayments IPN in my application and I have trouble with passing data to the method that take their Callback. I have tried like everything I could find: TempData, SessionVariables, tried to implement it somewhere in forms and maybe Request it but that didn`t work for me. So I also tried to implement it with Global static variables. And it worked! But then came another issue: if more than one user were to buy something from website at the same time or even in between any callbacks their data will get mixed. So here I am, trying again to make Session Variables work and have no clue why they are not working as I used them before. Probably what I can think of is that because its a callback from CoinPayments and I handle something wrongly.
Here is the code I have right now: Tho I tried different variations like implementing Session in Get Payment method. Now I ended up with it and it still comes out as null in POST METHOD.
Class for handling Session Variables:
public static class MyGlobalVariables
{
public static int TokenChoice
{
get
{
if (System.Web.HttpContext.Current.Session["TokenChoice"] == null)
{
return -1;
}
else
{
return (int)System.Web.HttpContext.Current.Session["TokenChoice"];
}
}
set
{
System.Web.HttpContext.Current.Session["TokenChoice"] = value;
}
}
public static int PaymentChoice
{
get
{
if (System.Web.HttpContext.Current.Session["PaymentChoice"] == null)
{
return -1;
}
else
{
return (int)System.Web.HttpContext.Current.Session["PaymentChoice"];
}
}
set
{
System.Web.HttpContext.Current.Session["PaymentChoice"] = value;
}
}
public static string CurrentUser
{
get
{
System.Web.HttpContext.Current.Session["CurrentUser"] = System.Web.HttpContext.Current.User.Identity.Name;
return (string)System.Web.HttpContext.Current.Session["CurrentUser"];
}
}
}
Class that returns view where you click on CoinPayments button:
public ActionResult Payment(int tokenChoice, int paymentChoice)
{
ViewBag.Payment = paymentChoice;
MyGlobalVariables.PaymentChoice = paymentChoice;
MyGlobalVariables.TokenChoice = tokenChoice;
return View();
}
Callback class that handles Callback from CoinPayments:
[HttpPost]
public ActionResult Payment()
{
NameValueCollection nvc = Request.Form;
var merchant_id = id;
var ipn_secret = secret;
var order_total = MyGlobalVariables.PaymentChoice;
if (String.IsNullOrEmpty(nvc["ipn_mode"]) || nvc["ipn_mode"] != "hmac")
{
Trace.WriteLine("IPN Mode is not HMAC");
return View();
}
if (String.IsNullOrEmpty(HTTP_HMAC))
{
Trace.WriteLine("No HMAC signature sent");
return View();
}
if (String.IsNullOrEmpty(nvc["merchant"]) || nvc["merchant"] != merchant_id.Trim())
{
Trace.WriteLine("No or incorrect Merchant ID passed");
return View();
}
//var hmac = hash_hmac("sha512", request, ipn_secret.Trim());
var txn_id = nvc["txn_id"];
var item_name = nvc["item_name"];
var item_number = nvc["item_number"];
var amount1 = nvc["amount1"];
var amount2 = float.Parse(nvc["amount2"], CultureInfo.InvariantCulture.NumberFormat);
var currency1 = nvc["currency1"];
var currency2 = nvc["currency2"];
var status = Convert.ToInt32(nvc["status"]);
var status_text = nvc["status_text"];
Trace.WriteLine(status);
if (currency1 != "USD") {
Trace.WriteLine("Original currency mismatch!");
return View();
}
if (Convert.ToInt32(amount1) < Convert.ToInt32(order_total))
{
Trace.WriteLine("Amount is less than order total!");
return View();
}
if (status >= 100 || status == 2) {
using (MyDatabaseEntities1 dc = new MyDatabaseEntities1())
{
var account = dc.Users.Where(a => a.Username == MyGlobalVariables.CurrentUser).FirstOrDefault();
if (account != null && account.Paid == 0)
{
Trace.WriteLine("Payment Completed");
Trace.WriteLine("Tokens to add: " + MyGlobalVariables.TokenChoice);
account.Tokens += MyGlobalVariables.TokenChoice;
account.Paid = 1;
dc.Configuration.ValidateOnSaveEnabled = false;
dc.SaveChanges();
}
}
} else if (status < 0)
{
Trace.WriteLine(
"payment error, this is usually final but payments will sometimes be reopened if there was no exchange rate conversion or with seller consent");
} else {
using (MyDatabaseEntities1 dc = new MyDatabaseEntities1())
{
var account = dc.Users.Where(a => a.Username == MyGlobalVariables.CurrentUser).FirstOrDefault();
if (account != null)
{
account.Paid = 0;
dc.Configuration.ValidateOnSaveEnabled = false;
dc.SaveChanges();
}
}
Trace.WriteLine("Payment is pending");
}
return View();
}
As you can see there are only 3 variables I need to handle.
Also someone might ask why I use Session Variable for Current.User?
Well for some reason Callback method can not read Current.User as it return null. And well... nothing really changed as for now.
If you have ever experienced something like that or can find an issue I would be so thankful since I wasted already over 2 days on that issue.
EDIT:
After some testing I found out variables works fine if I run Post method on my own. So the problem is with handling callback from CoinPayments. Is there a specific way to deal with this?

I'm trying to dispose of an object when the system is low on memory - is there a better way than this?

What I am doing currently is adding an item to the Cache and disposing of my object when that object is removed from the Cache. The logic being that it gets removed when memory consumption gets too high. I'm open to outher suggestions but I would like to avoid creating a thread than continually measures memory statistics if possible. Here is my code:
public class WebServiceCache : ConcurrentDictionary<string, WebServiceCacheObject>, IDisposable
{
private WebServiceCache()
{
if (HttpContext.Current != null && HttpContext.Current.Cache != null)
{
HttpContext.Current.Cache.Add("CacheTest", true, null, DateTime.Now.AddYears(1), System.Web.Caching.Cache.NoSlidingExpiration,
System.Web.Caching.CacheItemPriority.Low,
(key, obj, reason) => {
if (reason != System.Web.Caching.CacheItemRemovedReason.Removed)
{
WebServiceCache.Current.ClearCache(50);
}
});
}
}
private static WebServiceCache _current;
public static WebServiceCache Current
{
get
{
if (_current != null && _current.IsDisposed)
{
// Might as well clear it fully
_current = null;
}
if (_current == null)
{
_current = new WebServiceCache();
}
return _current;
}
}
public void ClearCache(short percentage)
{
try
{
if (percentage == 100)
{
this.Dispose();
return;
}
var oldest = _current.Min(c => c.Value.LastAccessed);
var newest = _current.Max(c => c.Value.LastAccessed);
var difference = (newest - oldest).TotalSeconds;
var deleteBefore = oldest.AddSeconds((difference / 100) * percentage);
// LINQ doesn't seem to work very well on concurrent dictionaries
//var toDelete = _current.Where(c => DateTime.Compare(c.Value.LastAccessed,deleteBefore) < 0);
var keys = _current.Keys.ToArray();
foreach (var key in keys)
{
if (DateTime.Compare(_current[key].LastAccessed, deleteBefore) < 0)
{
WebServiceCacheObject tmp;
_current.TryRemove(key, out tmp);
tmp = null;
}
}
keys = null;
}
catch
{
// If we throw an exception here then we are probably really low on memory
_current = null;
GC.Collect();
}
}
public bool IsDisposed { get; set; }
public void Dispose()
{
this.Clear();
HttpContext.Current.Cache.Remove("CacheTest");
this.IsDisposed = true;
}
}
In Global.asax
void context_Error(object sender, EventArgs e)
{
Exception ex = _context.Server.GetLastError();
if (ex.InnerException is OutOfMemoryException)
{
if (_NgageWebControls.classes.Caching.WebServiceCache.Current != null)
{
_NgageWebControls.classes.Caching.WebServiceCache.Current.ClearCache(100);
}
}
}
Thanks,
Joe
You can access the ASP.NET Cache from anywhere in your application as the static property:
HttpRuntime.Cache
You don't need to be in the context of a Request (i.e. don't need HttpContext.Current) to do this.
So you should be using it instead of rolling your own caching solution.

DevExpress GridControl Does not Update properly even I set up the NotifyPropertyChanged event correctly

I met a very strange Problem.
The basic idea is that I have a class to save data received from a trading api about forex price. Each property has been set with NotifyPropertyChanged method like below.
class RealTimeBar
{
public event PropertyChangedEventHandler PropertyChanged;
private const double EPSILON = 0.0000001;
private int _id;
private string _symbol;
private int _time;
private float _open;
private float _high;
private float _low;
private float _close;
int _volume;
public RealTimeBar(int id, string symbol)
{
_id = id;
_symbol = symbol;
}
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public int Id
{
get
{
return _id;
}
set
{
_id = value;
}
}
public string Symbol
{
get
{
return _symbol;
}
set
{
if (value != _symbol)
{
_symbol = value;
NotifyPropertyChanged("Symbol");
}
}
}
public int Time
{
get
{
return _time;
}
set
{
if (value != _time)
{
_time = value;
NotifyPropertyChanged("Time");
}
}
}
public float Open
{
get
{
return _open;
}
set
{
if (value != _open)
{
_open = value;
NotifyPropertyChanged("Open");
}
}
}
public float High
{
get
{
return _high;
}
set
{
if (value != _high)
{
_high = value;
NotifyPropertyChanged("High");
}
}
}
public float Low
{
get
{
return _low;
}
set
{
if (value != _low)
{
_low = value;
NotifyPropertyChanged("Low");
}
}
}
public float Close
{
get
{
return _close;
}
set
{
if (value != _close)
{
_close = value;
NotifyPropertyChanged("Close");
}
}
}
public int Volume
{
get
{
return _volume;
}
set
{
if (value != _volume)
{
_volume = value;
NotifyPropertyChanged("Volume");
}
}
}
}
It is quote a long class but with simple structure as you can see. Now I connected to api which fire event to me and I handle it by set the value from api to the class i defined.
BindingList<RealTimeBar> _realTimeBarList = new BindingList<RealTimeBar>();
public Hashtable _iForexHashtable = new Hashtable();
private void _UpdateForexQuote(int tickerId, int time, double open, double high, double low, double close, int volume,
double wap, int count)
{
///MessageBox.Show(tickerId.ToString());
((RealTimeBar)_iForexHashtable[tickerId]).Open = (float)open;
((RealTimeBar)_iForexHashtable[tickerId]).High = (float)high;
((RealTimeBar)_iForexHashtable[tickerId]).Low = (float)low;
((RealTimeBar)_iForexHashtable[tickerId]).Close = (float)close;
((RealTimeBar)_iForexHashtable[tickerId]).Volume = volume;
}
After some setting up, the method _UpdateForexQuote would distribute the coming info into properties of RealTimeBar class. Everything is fine.
When I start the program, it does not update. I thought that there is no data coming in. But when I randomly click somewhere in the A1cell of gridcontrol, then click another B1cell, the previous A1cell would update. Then if i click C1cell, then the B1cell would update. If you do not click one cell , it would never update. I show you the picture:
As you can see, that after clicking first three lines, the first three lines showed delayed data and since I never touch the fourth line, it shows zero. And the condition is that I just clicked the fifth line Low cell, that is why the Low does not update but other cells updated. It is very strange. I use same code before under devexpress 11 with vs 2010. But now with devexpress 12 with vs 2012, I met this problem which never occurred before.
UPDATE:
Below is the method I use to 1. define bindinglist and a hashtable, 2. put objects into the hashtable first and add the object from hashtable to bindinglist 3. bind the bindinglist to gridcontrol.
private void earningButtonItem_ItemClick(object sender, ItemClickEventArgs e)
{
_iTimer.AutoReset = false;
_iTimer.Enabled = false;
switchStockPool = "Earning Stock";
disconnectButtonItem.PerformClick();
connectButtonItem.PerformClick();
_iheitanshaoEarningDBConnect = new DBConnect("heitanshaoearning");
List<string>[] tempList;
int tempHash;
tempList = _iheitanshaoEarningDBConnect.SelectSymbolHighLow();
_quoteEarningOnGridList.Clear();
///tempList[0].Count
for (int i = 0; i < tempList[0].Count; i++)
{
tempHash = Convert.ToInt32(tempList[0][i].ToString().GetHashCode());
_iStockEarningHistHashtable[tempHash] = new QuoteOnGridHist(tempList[0][i], (float)Convert.ToSingle(tempList[1][i]), (float)Convert.ToSingle(tempList[2][i]), (float)Convert.ToSingle(tempList[3][i]));
_iStockEarningHashtable[tempHash] = new QuoteOnGrid(tempList[0][i], 0, 0);
_quoteEarningOnGridList.Add((QuoteOnGrid)_iStockEarningHashtable[tempHash]);
reqMktDataExStock(tempHash, tempList[0][i].ToString());
}
List<string>[] tempVolumeList;
tempVolumeList = _iheitanshaoEarningDBConnect.SelectAverageVolume();
for (int i = 0; i < tempList[0].Count; i++)
{
tempHash = Convert.ToInt32(tempVolumeList[0][i].ToString().GetHashCode());
((QuoteOnGrid)_iStockEarningHashtable[tempHash]).Average_Volume = ((float)Convert.ToSingle(tempVolumeList[1][i])) / volumeDenominator;
}
gridControl.DataSource = _quoteEarningOnGridList;
}
/////////////////////
Now when the price update event comes, the method below will update the object properties in hashtable. Since I defined Notifypropertychanged in object, it should update the object in bingdinglist and gridcontrol.
private void _UpdateStockMarketQuote(int tikcerId, int field, double price, int canAutoExecute)
{
////MessageBox.Show(tikcerId.ToString() + field.ToString() + price.ToString());
if (switchStockPool == "Selected Stock")
{
if (field == 4)
{
((QuoteOnGrid)_iStockHashtable[tikcerId]).Gap_From_High = ((float)price - ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).High) / ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Close;
((QuoteOnGrid)_iStockHashtable[tikcerId]).Gap_From_Low = ((float)price - ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Low) / ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Close;
((QuoteOnGrid)_iStockHashtable[tikcerId]).Last_Price = (float)price;
}
//else if (field == 1)
//{
// ((QuoteOnGrid)_iStockHashtable[tikcerId]).Gap_From_High = ((float)price - ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).High) / ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Close;
// ((QuoteOnGrid)_iStockHashtable[tikcerId]).Gap_From_Low = ((float)price - ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Low) / ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Close;
//}
}
else if (switchStockPool == "Earning Stock")
{
if (field == 4)
{
((QuoteOnGrid)_iStockEarningHashtable[tikcerId]).Gap_From_High = ((float)price - ((QuoteOnGridHist)_iStockEarningHistHashtable[tikcerId]).High) / ((QuoteOnGridHist)_iStockEarningHistHashtable[tikcerId]).Close;
((QuoteOnGrid)_iStockEarningHashtable[tikcerId]).Gap_From_Low = ((float)price - ((QuoteOnGridHist)_iStockEarningHistHashtable[tikcerId]).Low) / ((QuoteOnGridHist)_iStockEarningHistHashtable[tikcerId]).Close;
((QuoteOnGrid)_iStockEarningHashtable[tikcerId]).Last_Price = (float)price;
}
//else if (field == 1)
//{
// ((quoteongrid)_istockearninghashtable[tikcerid]).gap_from_high = ((float)price - ((quoteongridhist)_istockearninghisthashtable[tikcerid]).high) / ((quoteongridhist)_istockearninghisthashtable[tikcerid]).close;
// ((quoteongrid)_istockearninghashtable[tikcerid]).gap_from_low = ((float)price - ((quoteongridhist)_istockearninghisthashtable[tikcerid]).low) / ((quoteongridhist)_istockearninghisthashtable[tikcerid]).close;
//}
}
}
Not only you need to have PropertyChanged event in a class, you need to implement INotifyPropertyChanged. That's how the grid knows a class can inform of changes.

How can I get the value of a parameter passed to a method in a custom rule in FxCop?

Due to certain reasons, in our ASP.NET web application, it is not recommended to use Response.Redirect("something", True). It should be used with False for the endResponse parameter. We want to enforce this with a custom FxCop rule.
I've managed to find the usages of Response.Redirect, but now I want to find the value of the endResponse argument. How can I do this?
We're using the following code:
public override ProblemCollection Check(Member member)
{
var method = member as Method;
if (method != null)
{
foreach (var instruction in method.Instructions)
{
switch (instruction.OpCode)
{
case OpCode.Call:
case OpCode.Callvirt:
case OpCode.Newobj:
var call = (Method) instruction.Value;
if (call == null)
{
break;
}
if (call.Name.Name != "Redirect")
{
break;
}
if (call.Parameters.Count == 1)
{
//Redirect(url)
var resolution = GetResolution();
var problem = new Problem(resolution);
Problems.Add(problem);
}
if (call.Parameters.Count == 2)
{
VisitStatements(call.Body.Statements);
}
break;
default:
break;
}
}
}
return Problems;
}
public override void VisitExpression(Expression expression)
{
var methodCall = expression as MethodCall;
if (methodCall == null)
{
return;
}
foreach (var operand in methodCall.Operands)
{
if (operand.Type.Name.Name == "Int16" || operand.Type.Name.Name == "Int32" || operand.Type.Name.Name == "Int64")
{
var literal = operand as Literal;
if (literal != null && literal.Value is int)
{
var literalValue = (int)literal.Value;
if (literalValue == 1)
{
var resolution = GetResolution();
var problem = new Problem(resolution);
Problems.Add(problem);
}
}
}
}
}
I've used Introspector and thought the endResponse parameter was an integer behind the scenes, but I'm not so sure anymore. Anyway, there don't seem to be any booleans in the methodCall.Operands.
Has anyone ever had a similar situation, where you need to check the actual value of a parameter that's passed to a method?
While the parameter type is actually a System.Boolean, the FxCop IL parser is treating it as an integer. Here's a simplified version of the rule that should work (assuming you want non-literal endResponse values to trigger a rule violation):
public override ProblemCollection Check(Member member)
{
Method method = member as Method;
if (method != null)
{
this.Visit(method.Body);
}
return this.Problems;
}
public override void VisitMethodCall(MethodCall call)
{
base.VisitMethodCall(call);
Method targetMethod = (Method)((MemberBinding)call.Callee).BoundMember;
if (targetMethod.DeclaringType.FullName.Equals("System.Web.HttpResponse", StringComparison.Ordinal) &&
targetMethod.Name.Name.Equals("Redirect", StringComparison.Ordinal))
{
bool callIsAcceptable = false;
if (targetMethod.Parameters.Count == 2)
{
Expression endResponseOperand = call.Operands[1];
if (endResponseOperand.NodeType == NodeType.Literal)
{
if ((int)((Literal)endResponseOperand).Value == 1)
{
callIsAcceptable = true;
}
}
}
if (!callIsAcceptable)
{
this.Problems.Add(new Problem(this.GetResolution(), call));
}
}
}

Resources