We are getting false positives while using rule S2538 in the following code
EventLogLevel[] eventLevels = null;
bool reachedEnd = false;
while(!reachedEnd && jsonReader.Read())
{
switch(jsonReader.TokenType)
{
case JsonToken.PropertyName:
string propertyName = jsonReader.Value.ToString();
switch(propertyName)
{
case nameof(EventLevels):
eventLevels = EventSettingsJson.ParseEventLogLevelsArray(nameof(EventLevels), jsonReader);
break;
default:
throw new JsonParserException($"Invalid property: {propertyName}");
}
break;
case JsonToken.EndObject:
reachedEnd = true;
break;
default:
throw new JsonParserException($"Unexpected Token Type while parsing json properties. TokenType: {jsonReader.TokenType}");
}
}
if(eventLevels != null)
{
return new EventLogCollectionSettings(eventLogName, eventLevels);
}
The last if (eventLevels != null) shows the warning with the message:
[Change this condition so that it does not always evaluate to
"false"].
I couldn't create a testcase to reproduce it.
We know about this limitation in our data flow analysis engine. It's related to this ticket: https://jira.sonarsource.com/browse/SLVS-1091. We have no fix for it yet.
Related
I have followed the code shown on this site: "https://www.veonconsulting.com/integrating-sap-using-nco/",
I'm trying to get data from the function BAPI_PRODORD_GET_DETAIL, I tested <bapi_prodord_get_detail><number>1000262</number><struct><order_objects><header>X</header><operations>X</operations><components>X</components></order_objects></struct></bapi_prodord_get_detail>, on SAP GUI, I can see data for Header, Components & Operations, but in the code, I 'm not getting the same response, could you please help.
Code:
public bool testConnection()
{
bool state = false;
string rfcRequest = "<RFC_READ_TABLE><QUERY_TABLE>MARD</QUERY_TABLE><DELIMITER>*"
+ "</DELIMITER><ROWSKIPS>0</ROWSKIPS><ROWCOUNT>0</ROWCOUNT><TABLE><OPTIONS><ROW>"
+ "<TEXT>MATNR IN (</TEXT></ROW><ROW><TEXT>'testConnection'</TEXT></ROW><ROW>"
+ "<TEXT>)</TEXT></ROW></OPTIONS></TABLE></RFC_READ_TABLE>";
Utils.RfcClient client = new Utils.RfcClient();
try
{
XElement response = client.PullRequestToSAPrfc(rfcRequest);
state = true;
}
catch (RfcLogonException ex)
{
Console.Write("Logon Failed");
}
catch (RfcInvalidStateException ex)
{
Console.Write("RFC Failed");
}
catch (RfcBaseException ex)
{
Console.WriteLine("communication error" + ex.Message);
}
catch (Exception ex)
{
Console.Write("Connection error");
}
finally
{
//client.disconnectDestination();
}
return state;
}
public bool testConnection()
{
bool state = false;
string rfcRequest = "<bapi_prodord_get_detail><number>1000262</number><struct>"
+ "<order_objects><header>X</header><operations>X</operations><components>X"
+ "</components></order_objects></struct></bapi_prodord_get_detail>";
Utils.RfcClient client = new Utils.RfcClient();
try
{
XElement response = client.PullRequestToSAPrfc(rfcRequest);
state = true;
}
catch (RfcLogonException ex)
{
Console.Write("Logon Failed");
}
catch (RfcInvalidStateException ex)
{
Console.Write("RFC Failed");
}
catch (RfcBaseException ex)
{
Console.WriteLine("communication error" + ex.Message);
}
catch (Exception ex)
{
Console.Write("Connection error");
}
finally
{
//client.disconnectDestination();
}
return state;
}
public XElement PullRequestToSAPrfc(string XMLRequest)
{
IRfcFunction requestFn;
requestFn = PrepareRfcFunctionFromXML(XElement.Parse(XMLRequest));
RfcSessionManager.BeginContext(_ECCsystem);
requestFn.Invoke(_ECCsystem);
RfcSessionManager.EndContext(_ECCsystem);
XElement XMLResponse = PrepareXMLFromrfc(requestFn);
return XMLResponse;
}
public IRfcFunction PrepareRfcFunctionFromXML(XElement xmlFunction)
{
RfcRepository repo = _ECCsystem.Repository;
IRfcFunction RfcFunction = repo.CreateFunction(xmlFunction.Name.ToString());
foreach (XElement xelement in xmlFunction.Elements())
{
if (xelement.Name.ToString().Equals("TABLE"))
{
if (NotProcessSpecialTable(xelement))
continue;
IRfcTable options = RfcFunction.GetTable(xelement.Descendants().First().Name.ToString());
foreach (XElement row in xelement.Elements().First().Elements())
{
options.Append();
foreach (XElement rowElement in row.Elements())
{
string elementName = rowElement.Name.ToString();
RfcElementMetadata elementMeta = options.GetElementMetadata(elementName);
var elementValue = getValueAsMetadata(ref elementMeta, rowElement.Value);
if (elementValue is string && string.IsNullOrEmpty((string)elementValue)) { continue; }
options.SetValue(elementName, elementValue);
}
}
}
else if (xelement.Name.ToString().Equals("STRUCT"))
{
IRfcStructure options = RfcFunction.GetStructure(xelement.Descendants().First().Name.ToString());
foreach (XElement structElement in xelement.Elements().First().Elements())
{
string elementName = structElement.Name.ToString();
RfcElementMetadata elementMeta = options.GetElementMetadata(elementName);
var elementValue = getValueAsMetadata(ref elementMeta, structElement.Value);
if (elementValue is string && string.IsNullOrEmpty((string)elementValue)) { continue; }
options.SetValue(elementName, elementValue);
}
}
else
{
string elementName = xelement.Name.ToString();
RfcElementMetadata elementMeta = RfcFunction.GetElementMetadata(elementName);
var elementValue = getValueAsMetadata(ref elementMeta, xelement.Value);
if (elementValue is string && string.IsNullOrEmpty((string)elementValue)) { continue; }
RfcFunction.SetValue(elementName, elementValue);
}
}
return RfcFunction;
}
public XElement PrepareXMLFromrfc(IRfcFunction rfcFunction)
{
var XMLRoot = new XElement(rfcFunction.Metadata.Name);
for (int functionIndex = 0; functionIndex < rfcFunction.ElementCount; functionIndex++)
{
var functionMatadata = rfcFunction.GetElementMetadata(functionIndex);
if (functionMatadata.DataType == RfcDataType.TABLE)
{
var rfcTable = rfcFunction.GetTable(functionMatadata.Name);
var XMLTable = new XElement(functionMatadata.Name);
foreach (IRfcStructure rfcStracture in rfcTable)
{
XElement XMLRow = new XElement("ROW");
for (int i = 0; i < rfcStracture.ElementCount; i++)
{
RfcElementMetadata rfcElementMetadata = rfcStracture.GetElementMetadata(i);
if (rfcElementMetadata.DataType == RfcDataType.BCD)
{ XMLRow.Add(new XElement(rfcElementMetadata.Name, rfcStracture.GetString(rfcElementMetadata.Name))); }
else
{
XMLRow.Add(new XElement(rfcElementMetadata.Name, rfcStracture.GetString(rfcElementMetadata.Name)));
}
}
XMLTable.Add(XMLRow);
}
XMLRoot.Add(XMLTable);
}
else if (functionMatadata.DataType == RfcDataType.STRUCTURE)
{
var rfcStructure = rfcFunction.GetStructure(functionMatadata.Name);
XElement XMLRow = new XElement(functionMatadata.Name);
for (int elementIndex = 0; elementIndex < rfcStructure.ElementCount; elementIndex++)
{
RfcElementMetadata eleMeta = rfcStructure.GetElementMetadata(elementIndex);
XMLRow.Add(new XElement(eleMeta.Name, rfcStructure.GetString(eleMeta.Name)));
}
XMLRoot.Add(XMLRow);
}
else
{
RfcElementMetadata rfcElement = rfcFunction.GetElementMetadata(functionIndex);
XMLRoot.Add(new XElement(rfcElement.Name, rfcFunction.GetString(rfcElement.Name)));
}
}
return XMLRoot;
}
# Below function is used for the data types.
private object getValueAsMetadata(ref RfcElementMetadata elementMeta, string value)
{
switch (elementMeta.DataType)
{
case RfcDataType.BCD:
return value;
case RfcDataType.NUM:
if (value.Contains("."))
{
int elementValue;
int.TryParse(value, out elementValue);
return elementValue;
}
else
{
return Convert.ToInt32(value);
}
case RfcDataType.INT1:
return Convert.ToInt32(value);
case RfcDataType.INT2:
return Convert.ToInt32(value);
case RfcDataType.INT4:
return Convert.ToInt32(value);
case RfcDataType.INT8:
return Convert.ToInt64(value);
case RfcDataType.CHAR:
return value;
case RfcDataType.DATE:
return DateTime.ParseExact(value, "yyyy-MM-dd", CultureInfo.InvariantCulture);
default:
return string.Empty;
}
}
You are confronted to the classic issue of external and internal values in SAP.
Your screenshot shows the ABAP Function Module Test screen in SAP system. When you enter a value in the screen, it may be transformed internally before calling the function module.
These are called the external and internal formats. "External" is what is shown in the User Interface (typed or displayed), "internal" is the value written to the database.
For instance, imagine a database object whose primary key is a GUID, this is the object key in internal format, but in the user interface this object is always referred or shown by its name (candidate key).
In your precise case, when a Production Order is a number, the internal format always contains leading zeroes on 12 digits, and the external format does not display them. In the Function Module Test screen, if you enter this external value:
1000262
it's converted to the following internal value and the BAPI is called with it:
000001000262
Generally speaking, when you call any function module from another program, you must indicate the internal value, because there's no user interface implied between the two.
i.e., use this XML in your method testConnection:
string rfcRequest = "<bapi_prodord_get_detail><number>000001000262</number><struct>"
+ "<order_objects><header>X</header><operations>X</operations><components>X"
+ "</components></order_objects></struct></bapi_prodord_get_detail>";
See also this answer about external and internal formats: Converting MATNR via conversion exit fails for custom table
If you would like to do the required field conversions programmatically, which are explained in Sandra Rossi's answer, you may use the RFMs BAPI_CONVERSION_EXT2INT, BAPI_CONVERSION_EXT2INT1, BAPI_CONVERSION_INT2EXT and BAPI_CONVERSION_INT2EXT1 for doing so.
However, every additional RFC call has of course a negative impact on the performance.
Besides, SAP Note 206068 is a good resource for an explanation of some RFC BAPI pitfalls which you also stepped in.
Trying to return a badrequest if the cardMethod.ID doesn't match the payment ID, but currently it returns a 500 internal server error "Object reference not set to an instance of an object" Where or how would I go about returning an error based off the logic below. I wasn't sure if it should be handled in the controller or should be handed in the service layer.
As currently the service layer handles mostly stripe exceptions.
Or should I try implement a try catch in my controller?
service class
public async Task<VersionResponse> DeletePaymentMethod(string paymentID, string userId)
{
try
{
StripeConfiguration.ApiKey = _appSettings.StripeSecretKey;
var profile = await _userManager.FindByIdAsync(userId);
var stripeId = profile.StripeAccountId;
if (stripeId == null)
throw new ArgumentException("No associated Stripe account found.");
var service = new PaymentMethodService();
//list the payment methods
var cardPaymentMethods = service.ListAutoPaging(new PaymentMethodListOptions
{
Customer = stripeId,
Type = "card"
});
//Detach card which matches with list of payment methods
var cardMethod = cardPaymentMethods.Where(m => m.Id == paymentID).FirstOrDefault();
if(cardMethod.Id != paymentID)
throw new ArgumentException("Payment method not found for specified id.");
await service.DetachAsync(cardMethod.Id, new PaymentMethodDetachOptions());
return new VersionResponse
{
Data = cardPaymentMethods
};
}
catch (Exception ex)
{
throw HandleStripeExceptions(ex);
}
}
PaymentMethodController
[HttpDelete]
[ProducesResponseType(typeof(FluentValidation.Results.ValidationResult), 400)]
public async Task<IActionResult> DeletePaymentMethod(string paymentID)
{
var userId = User.Claims.FirstOrDefault(x => x.Type == "UserID").Value;
var result = new SuccessResponse()
{
success = true
};
await _paymentService.DeletePaymentMethod(paymentID, userId);
if (string.IsNullOrEmpty(paymentID))
return BadRequest("Payment method not found for specified id.");
return Ok(result);
}
private Exception HandleStripeExceptions(Exception ex)
{
if (ex is StripeException e)
{
switch (e.StripeError.ErrorType)
{
case "card_error":
Console.WriteLine("Code: " + e.StripeError.Code);
Console.WriteLine("Message: " + e.StripeError.Message);
break;
case "api_connection_error":
break;
case "api_error":
break;
case "missing_parameter":
break;
case "authentication_error":
break;
case "rate_limit_error":
break;
case "validation_error":
break;
default:
// Unknown Error Type
break;
}
return ex;
}
else
{
return ex;
}
}
I believe the 500 error is a result of
if(cardMethod.Id != paymentID)
throw new ArgumentException("Payment method not found for specified id.");
The cardMethod could be null, you should check null in the if statement like
if(cardMethod == null)
There will no case where cardMethod.Id != paymentID is true.
I am building a WCF client to access a vendor web service. The service uses IssuedTokenOverTransport, SymmetricKey, and expects SAML. I have the request working, but the response back from the service includes a SignatureConfirmation element in the WS-Security header. My C# client chokes on this "signature confirmation is not expected in the security header" and I don't see a way to either ignore or process this element. It seems the only way to get near the handling of SignatureConfirmation in WCF is to abandon the IssuedTokenOverTransport binding and use something else, but this doesn't seem to be an option because the service requires this binding type. Is this a bug in WCF?
I solved this by using a custom Message Encoder. See this article from Carlos Figueroa for background:
http://blogs.msdn.com/b/carlosfigueira/archive/2011/11/09/wcf-extensibility-message-encoders.aspx
Essentially, the encoder can look for the SignatureConfirmation element in the incoming message and remove it from the header. The key piece of code is this private method that is called from the ReadMessage overrides:
private MemoryStream ProcessMemoryStream(Stream inputStream, bool dispose)
{
StreamWriter xmlStream = null;
var outputStream = new MemoryStream();
bool continueFilter = false;
try
{
xmlStream = new StreamWriter(outputStream);
using (var reader = XmlReader.Create(inputStream))
{
using (
var writer = XmlWriter.Create(xmlStream,
new XmlWriterSettings() {ConformanceLevel = ConformanceLevel.Auto}))
{
while (reader.Read())
{
if (reader.LocalName.Equals("SignatureConfirmation") &&
reader.NamespaceURI.Equals(
"http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"))
{
if (!reader.IsEmptyElement) continueFilter = reader.IsStartElement();
}
else if (reader.LocalName.Equals("Signature") &&
reader.NamespaceURI.Equals("http://www.w3.org/2000/09/xmldsig#"))
{
if (!reader.IsEmptyElement) continueFilter = reader.IsStartElement();
}
else if (continueFilter)
{
// continue to next node
}
else
XmlHelper.WriteShallowNode(reader, writer);
}
writer.Flush();
}
reader.Close();
}
outputStream.Position = 0;
return outputStream;
}
catch (Exception ex)
{
// handle error
throw;
}
finally
{
if (xmlStream != null && dispose) xmlStream.Dispose();
}
}
The Xml Helper:
internal static class XmlHelper
{
internal static void WriteShallowNode(XmlReader reader, XmlWriter writer)
{
if (reader == null)
{
throw new ArgumentNullException("reader");
}
if (writer == null)
{
throw new ArgumentNullException("writer");
}
switch (reader.NodeType)
{
case XmlNodeType.Element:
writer.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI);
writer.WriteAttributes(reader, true);
if (reader.IsEmptyElement)
{
writer.WriteEndElement();
}
break;
case XmlNodeType.Text:
writer.WriteString(reader.Value);
break;
case XmlNodeType.Whitespace:
case XmlNodeType.SignificantWhitespace:
writer.WriteWhitespace(reader.Value);
break;
case XmlNodeType.CDATA:
writer.WriteCData(reader.Value);
break;
case XmlNodeType.EntityReference:
writer.WriteEntityRef(reader.Name);
break;
case XmlNodeType.XmlDeclaration:
case XmlNodeType.ProcessingInstruction:
writer.WriteProcessingInstruction(reader.Name, reader.Value);
break;
case XmlNodeType.DocumentType:
writer.WriteDocType(reader.Name, reader.GetAttribute("PUBLIC"), reader.GetAttribute("SYSTEM"),
reader.Value);
break;
case XmlNodeType.Comment:
writer.WriteComment(reader.Value);
break;
case XmlNodeType.EndElement:
writer.WriteFullEndElement();
break;
}
}
}
I am trying to build a regex parser for a single XML block.
I know people will say that Regex is not a good plan for xml, but I am working with stream data and I just need to know if a complete xml block has been broadcast and is sitting in the buffer.
I am trying to handle for anything between the Opening and closing blocks of the XML and any data in parameters of the main block header.
My example code is below the broken down Regular Expression, if anyone has any input on how to make this as comprehensive as possible I would greatly appreciate it.
Here is my regular expression formatted for visual aid.
I am balancing the group, as well as the group and validating that they do not exist at the end of the expression segments.
/*
^(?<TAG>[<]
(?![?])
(?<TAGNAME>[^\s/>]*)
)
(?<ParamData>
(
(\"
(?>
\\\"|
[^"]|
\"(?<quote>)|
\"(?<-quote>)
)*
(?(quote)(?!))
\"
)|
[^/>]
)*?
)
(?:
(?<HASCONTENT>[>])|
(?<-TAG>
(?<TAGEND>/[>])
)
)
(?(HASCONTENT)
(
(?<CONTENT>
(
(?<inTAG>[<]\<TAGNAME>)(?<-inTAG>/[>])?|
(?<-inTAG>[<]/\<TAGNAME>[>])|
([^<]+|[<](?![/]?\<TAGNAME>))
)*?
(?(inTAG)(?!))
)
)
(?<TAGEND>(?<-TAG>)[<]/\<TAGNAME>[>])
)
(?(TAG)(?!))
*/
Within my class, I expect that any Null object returned means there was no xml block on the queue.
Here is the class I am using.
(I used a literal string (#"") to limit the escape requirements, All " characters were replaced with "" to format properly.
public class XmlDataParser
{
// xmlObjectExpression defined below to limit code highlight errors
private Regex _xmlRegex;
private Regex xmlRegex
{
get
{
if (_xmlRegex == null)
{
_xmlRegex = new Regex(xmlObjectExpression);
}
return _xmlRegex;
}
}
private string backingStore = "";
public bool HasObject()
{
return (backingStore != null) && xmlRegex.IsMatch(backingStore);
}
public string GetObject()
{
string result = null;
if (HasObject())
{
lock (this)
{
Match obj = xmlRegex.Match(backingStore);
result = obj.Value;
backingStore = backingStore.Substring(result.Length);
}
}
return result;
}
public void AddData(byte[] bytes)
{
lock (this)
{
backingStore += System.Text.Encoding.Default.GetString(bytes);
}
}
private static string xmlObjectExpression = #"^(?<TAG>[<](?![?])(?<TAGNAME>[^\s/>]*))(?<ParamData>((\""(?>\\\""|[^""]|\""(?<quote>)|\""(?<-quote>))*(?(quote)(?!))\"")|[^/>])*?)(?:(?<HASCONTENT>[>])|(?<-TAG>(?<TAGEND>/[>])))(?(HASCONTENT)((?<CONTENT>((?<inTAG>[<]\<TAGNAME>)(?<-inTAG>/[>])?|(?<-inTAG>[<]/\<TAGNAME>[>])|([^<]+|[<](?![/]?\<TAGNAME>)))*?(?(inTAG)(?!))))(?<TAGEND>(?<-TAG>)[<]/\<TAGNAME>[>]))(?(TAG)(?!))";
}
Just use XmlReader and feed it a TextReader. To read streams, you want to change the ConformanceLevel to Fragment.
XmlReaderSettings settings = new XmlReaderSettings();
settings.ConformanceLevel = ConformanceLevel.Fragment;
using (XmlReader reader = XmlReader.Create(tr,settings))
{
while (reader.Read())
{
switch (reader.NodeType)
{
// this is from my code. You'll rewrite this part :
case XmlNodeType.Element:
if (t != null)
{
t.SetName(reader.Name);
}
else if (reader.Name == "event")
{
t = new Event1();
t.Name = reader.Name;
}
else if (reader.Name == "data")
{
t = new Data1();
t.Name = reader.Name;
}
else
{
throw new Exception("");
}
break;
case XmlNodeType.Text:
if (t != null)
{
t.SetValue(reader.Value);
}
break;
case XmlNodeType.XmlDeclaration:
case XmlNodeType.ProcessingInstruction:
break;
case XmlNodeType.Comment:
break;
case XmlNodeType.EndElement:
if (t != null)
{
if (t.Name == reader.Name)
{
t.Close();
t.Write(output);
t = null;
}
}
break;
case XmlNodeType.Whitespace:
break;
}
}
}
I'm trying to debug my c# application that check MIPS syntax. But its not allowing be to debug it. No matter where I enter my break point it gets ignored, including the first line of the Main() function. Its also throwing me this error.
'add a b c' works fine if i don't call HasValidParams()
'add a b' throws exception in the same situation
neither works when calling HasValidParams()
program.cs
private static void Main(string[] args)
{
var validator = new MipsValidator();
Console.Write("Please enter a MIPS statement: ");
string input = Console.ReadLine();
List<string> arguments = input.Split(new char[0]).ToList();
Response status = validator.IsSyntaxValid(arguments);
//Check syntax
if (status.Success.Equals(true))
{
Response stat = validator.HasValidParams(arguments);
//Check parameters
if (stat.Success.Equals(true))
{
Console.WriteLine(string.Format("'{0}' is a valid mips instruction ", input));
}
else
{
foreach (var reason in stat.Reasons)
{
Console.WriteLine(reason);
}
}
}
else
{
foreach (string reason in status.Reasons)
{
Console.WriteLine(reason);
}
}
}
mips-validator.cs
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace mips_validator.utils
{
public class MipsValidator : IMipsValidator
{
#region Implementation of IMipsValidator
public Response IsSyntaxValid(List<string> args)
{
var response = new Response {Success = true};
var op = (Operator) Enum.Parse(typeof (Operator), args[0]);
switch (op)
{
case Operator.addi:
case Operator.add:
case Operator.beq:
if (args.Count != 4)
{
response.Reasons.Add(string.Format("4 operands required for {0}, {1} parameters provided.",
op, args.Count));
response.Success = false;
}
break;
case Operator.j:
if (args.Count != 2)
{
response.Reasons.Add(string.Format("1 operands required for {1}, {0} parameters provided.",
args.Count, op));
response.Success = false;
}
break;
default:
response.Reasons.Add(string.Format("{0} is an unknown mips operation", op));
response.Success = false;
break;
}
return response;
}
public Response HasValidParams(List<string> parameters)
{
string op1, op2, op3;
var temporary = new Regex(#"/\$t\d+/");
var store = new Regex(#"/\$s\d+/");
var zero = new Regex(#"/\$zero/");
var osReserved = new Regex(#"/\$k0|1/");
var memory = new Regex(#"");
var constant = new Regex(#"/-?\d*/");
var label = new Regex(#"/.*\:/");
Operator operation;
var response = new Response {Success = true};
string opString = parameters[0];
Enum.TryParse(opString.Replace("$", string.Empty), true, out operation);
switch (operation)
{
case Operator.add:
{
op1 = parameters[1];
op2 = parameters[2];
if (!temporary.IsMatch(op1) && !store.IsMatch(op1) && !zero.IsMatch(op1))
{
response.Reasons.Add(string.Format("{0}: error register expected", op1));
response.Success = false;
}
if (!temporary.IsMatch(op2) && !store.IsMatch(op2) && !zero.IsMatch(op2))
{
response.Reasons.Add(string.Format("{0}: error register expected", op2));
response.Success = false;
}
}
break;
case Operator.addi:
{
op1 = parameters[1];
op2 = parameters[2];
if (!temporary.IsMatch(op1) && !store.IsMatch(op1) && !zero.IsMatch(op1))
{
response.Reasons.Add(string.Format("{0}: error register expected", op1));
response.Success = false;
}
if (!constant.IsMatch(op2) && !zero.IsMatch(op2))
{
response.Reasons.Add(string.Format("{0}: error constant expected", op2));
response.Success = false;
}
}
break;
case Operator.beq:
{
op1 = parameters[1];
op2 = parameters[2];
op3 = parameters[3];
if (!temporary.IsMatch(op1) && !store.IsMatch(op1) && !zero.IsMatch(op1))
{
response.Reasons.Add(string.Format("{0}: error register expected", op1));
response.Success = false;
}
if (!temporary.IsMatch(op2) && !store.IsMatch(op2) && !zero.IsMatch(op2))
{
response.Reasons.Add(string.Format("{0}: error register expected", op2));
response.Success = false;
}
if (!label.IsMatch(op3) && !constant.IsMatch(op3))
{
response.Reasons.Add(string.Format("{0}: error label or constant expected", op3));
response.Success = false;
}
}
break;
}
return response;
}
#endregion
}
}
SOLUTION-------
Response.cs(old)
public class Response
{
public List<string> Reasons;
public bool Success = true;
}
Response.cs(current)
public class Response
{
public Response()
{
Reasons = new List<string>();
Success = true;
}
public List<string> Reasons;
public bool Success = true;
}
I can't tell if you're looking for a way to be able to debug your project or if you'd prefer to be told potential issues in your code.
For the latter:
Make sure Response.Reasons is initialized by the constructor of Response (or a field initializer).
You're not showing the Response class, so make sure Reasons is actually set to a collection you can add to and not left to the default, null.
Edit: The below possible cause for a crash was pointed put by #nodakai not to be one at all; turns out an empty char array is a special case to split on whitespace.
*You calculate arguments by doing
List arguments = input.Split(new char[0]).ToList();
...which as far as I can tell does absolutely nothing except put the original string inside a List. You probably want to split on new char[] {' '} instead to split on spaces.*
Check if your breakpoint looks like this:
If it does, your source code differs from the code the assembly was actually compiled with. Make sure your project is built properly (right click on the solution and select "Rebuild") and check your current configuration:
Hope this helps...