returning a Tuple with a null item - c#

I have some code that looks like this:
public Tuple<bool, SomeObjectModel> CheckIfJsonIsValid(string IncomingJson)
{
SomeObjectModel TheObjectModel = new SomeObjectModel();
JavascriptSerializer TheSerializer = new JavascriptSerializer();
.....
try
{
TheObjectModel = TheSerializer.Deserialize<SomeObjectModel>(IncomingJson);
}
catch
{
return new Tuple<bool, SomeObjectModel>(false, null); //question here
}
.....
return new Tuple<bool, SomeObjectModel>(true, TheObjectModel);
}
The calling method first check the returning tuple's Item1, and if it's false, ends its process.
Is it better practice a) to return a null value in the Tuple or b) to return a new and fresh instance of SomeObjectModel? Are there any performance implications?
Thanks for your suggestions.

Let me suggest three alternative solutions:
ParseJsonIfValid: If deserializing works, TheObjectModel is always non-null. Thus, there is no need for the boolean:
public SomeObjectModel ParseJsonIfValid(string IncomingJson)
{
JavascriptSerializer TheSerializer = new JavascriptSerializer();
.....
try
{
return TheSerializer.Deserialize<SomeObjectModel>(IncomingJson);
}
catch
{
return null;
}
}
In the calling function simply check whether the return value is null or not.
ParseJson: If the JSON is usually valid, and invalid JSON is a sign of something gone terribly wrong, just throw an exception:
public SomeObjectModel ParseJson(string IncomingJson)
{
JavascriptSerializer TheSerializer = new JavascriptSerializer();
.....
try
{
return TheSerializer.Deserialize<SomeObjectModel>(IncomingJson);
}
catch (Exception e)
{
throw new TheServerSentRubbishException(e);
}
}
Be sure to include the inner ("real") exception, so that the calling function can log the real cause of the error for debugging purposes.
TryParseJson: If null can be a valid deserialization, you can use the following pattern, which has the advantage of being consistent with the TryParse methods of the .NET framework:
public bool TryParseJson(string IncomingJson, out SomeObjectModel theObjectModel)
{
JavascriptSerializer TheSerializer = new JavascriptSerializer();
.....
try
{
theObjectModel = TheSerializer.Deserialize<SomeObjectModel>(IncomingJson);
return true;
}
catch (Exception e)
{
return false;
}
}

Related

How write Unit test in Catch block in Xunit?

In the following function, I want to test the case where an exception is thrown using XUnit. The test should verify that the excpetion is correctly thrown.
public IDictionary<string, Label> Build(string content)
{
try
{
var settings = new JsonSerializerSettings
{
MissingMemberHandling = MissingMemberHandling.Ignore
};
var contentStudioResponse = JsonConvert.DeserializeObject<ContentStudioResponse<CmsLabel>>(content, settings);
if (contentStudioResponse?.Items == null)
{
_logger.Warning("No records found in content studio response for label:({#content})", content);
return new Dictionary<string, Label>();
}
return contentStudioResponse.Items.ToDictionary(x => x.Key,
x => new Label
{
Value = x.DynamicProperties.MicroContentValue
}
);
}
catch (Exception e)
{
_logger.Error(e, "Failed to deserialize or build contentstudio response for label");
return new Dictionary<string, Label>();
}
}
Below is my solution which is not working:
[Fact]
public void Builder_ThrowsException()
{
string json_responsive_labels = "abcd";
var builder = new LabelBuilder(_testLogger).Build(json_responsive_labels);
Assert.Throws<Exception>(() => builder);
//var sut = new LabelBuilder(_testLogger);
//Should.Throw<Exception>(() => sut.Build(json_responsive_labels));
}
Have a read through of this. This explains step by step on how to test for an exception being thrown.
However, based on what you have written, the code won't throw an exception since at this point you're only logging your exception and then returning a Dictionary.
catch (Exception e)
{
_logger.Error(e, "Failed to deserialize or build contentstudio response for label");
return new Dictionary<string, Label>();
}
What you actually want to do is explicitly throw an exception like so:
catch (Exception e)
{
throw new Exception();
}
In doing so, your code will throw an exception which you can catch and test against.

Cannot implicitly convert type from IOrderedQueryable<T> to List<T>

I get the following error on the seminariolista = line:
Cannot implicitly convert type from IOrderedQueryable to List
public List<Seminario> Listarseminariomodal()
{
var seminariolista = new List<Seminario>();
try
{
using (var ctx = new ProyectoContext_())
{
seminariolista = ctx.Seminario.Where(x => x.modal == 1)
.OrderBy(x => x.orden);
}
}
catch (Exception)
{
throw;
}
return seminariolista;
}
Visual Studio Screenshot
Probably defining it as
IEnumerable<Seminario> seminariolista = null;
and returning it as
return seminariolista.ToList();
will work.
But in general it's not a good idea, in my opinion, to return a List object, unless you explicitly need it. I would return an IEnumeralble, to keep the method signature as general as possible.
So, the best solution for your code, in my opinion and WITHOUT KNOWING the requirement of your application and the rest of your code:
public IEnumerable<Seminario> Listarseminariomodal()
{
IEnumerable<Seminario> seminariolista = null;
try
{
using (var ctx = new ProyectoContext_())
{
seminariolista = ctx.Seminario.Where(x => x.modal == 1)
.OrderBy(x => x.orden);
}
}
catch (Exception)
{
throw;
}
return seminariolista.ToArray();
}
Note the ToArray() call at the end, to hide the LINQ stuff outside the method body.

Error: Not all code paths return a value [duplicate]

This question already has answers here:
C# compiler error: "not all code paths return a value"
(9 answers)
Closed 8 years ago.
Why it happens? Here is my code to read dictionary from bin file
public static object LoadObject()
{
try
{
if (File.Exists("D://my.bin"))
{
FileStream stream = File.OpenRead("D://my.bin");
BinaryFormatter formatter = new BinaryFormatter();
Dictionary<int, Question> deserializedObject = (Dictionary<int, Question>)formatter.Deserialize(stream);
stream.Close();
return deserializedObject;
}
}
catch
{
}
}
Your method is suppose to return an object of type object, but you are only returning inside the try block and that too from inside an if statement. So if your condition fails, your method will not return anything. Also if there is an exception in try block, before returning the object then your method would fail to return anything. That is why you are getting the error. You can fix that by returning null from outside of try / catch block.
public static object LoadObject()
{
try
{
if (File.Exists("D://my.bin"))
{
FileStream stream = File.OpenRead("D://my.bin");
BinaryFormatter formatter = new BinaryFormatter();
Dictionary<int, Question> deserializedObject = (Dictionary<int, Question>)formatter.Deserialize(stream);
stream.Close();
return deserializedObject;
}
}
catch(Exception ex)
{
//log exception
return null;
}
return null;
}
Although this will will fix your error, but you should look for other option like throwing an exception if the file is not found, or returning an error object.
You need a return also if your code raises an exception or if the condition File.Exists is not met
However, as is, there is no point in catching the exception. If you don't do anything with it, let it bubble at the upper level
public static object LoadObject()
{
if (File.Exists("D://my.bin"))
{
FileStream stream = File.OpenRead("D://my.bin");
BinaryFormatter formatter = new BinaryFormatter();
Dictionary<int, Question> deserializedObject = (Dictionary<int, Question>)formatter.Deserialize(stream);
stream.Close();
return deserializedObject;
}
else
throw FileNotFoundException("There is no file named", "D:\\my.bin");
}
As the error message suggests, all the code paths must return a value. You have two conditions where no value is returned:
If the file does not exist.
If an exception is thrown.
Change the code to:
try
{
if (File.Exists("D://my.bin"))
{
...
return deserializedObject;
}
}
catch
{
}
return null; // Or return an empty dictionary with:
// return new Dictionary<int, Question>();
You can try this
public static object LoadObject()
{
try
{
if (File.Exists("D://my.bin"))
{
FileStream stream = File.OpenRead("D://my.bin");
BinaryFormatter formatter = new BinaryFormatter();
Dictionary<int, Question> deserializedObject = (Dictionary<int, Question>)formatter.Deserialize(stream);
stream.Close();
return deserializedObject;
}
}
catch
{
return null;
}
return null;
}

reduce complexity of service class

I am developing a web api using WCF Web Api preview 5. At the moment I have a resource class fully functional, how ever I noticed my methods inside this resouce are getting complex.
For example:
[WebInvoke(UriTemplate = "{EhrID}/PhysicalTest",Method="POST")]
public HttpResponseMessage<DTO.PhysicalTest> PostPhysicalTest(int EhrID, DTO.PhysicalTest PhysicalTestDTO)
{
var EHR = repository.FindById(EhrID);
var PhysicalTest = Mapper.Map<DTO.PhysicalTest, PhysicalTest>(PhysicalTestDTO);
if (PhysicalTest == null)
{
var response = CreateResponseForException("No object to store", HttpStatusCode.BadRequest);
throw new HttpResponseException(response);
}
try
{
if (EHR.PhysicalTests == null)
{
EHR.PhysicalTests = new List<PhysicalTest>();
}
PhysicalTest.CreationDate = DateTime.Now;
EHR.PhysicalTests.Add(PhysicalTest);
_unitOfWork.Commit();
return new HttpResponseMessage<DTO.PhysicalTest>(PhysicalTestDTO, HttpStatusCode.Created);
}
catch (Exception ex) {
var response = CreateResponseForException("Cannot create Physical Test", HttpStatusCode.InternalServerError);
throw new HttpResponseException(response);
}
}
As you may notice this method has the task of posting a new Physical Test, but it's actually validating my model too (I'm missing lots of validations still, property validations), which should not be this class concern. If there any approachable way to reduce the complexity of the methods inside de resource?
I would split it up into smaller more focused methods. I might also start using instance variables instead of passing all these arguments around, but for the sake of this post I've rewritten it without pushing stuff to instance variables.
[WebInvoke(UriTemplate = "{EhrID}/PhysicalTest",Method="POST")]
public HttpResponseMessage<DTO.PhysicalTest> PostPhysicalTest(int EhrID, DTO.PhysicalTest PhysicalTestDTO)
{
var EHR = repository.FindById(EhrID);
var PhysicalTest = Mapper.Map<DTO.PhysicalTest, PhysicalTest>(PhysicalTestDTO);
if (PhysicalTest == null)
{
var response = CreateResponseForException("No object to store", HttpStatusCode.BadRequest);
throw new HttpResponseException(response);
}
PostPhysicalTest(EHR, PhysicalTest);
return new HttpResponseMessage<DTO.PhysicalTest>(PhysicalTestDTO, HttpStatusCode.Created);
}
private void PostPhysicalTest(EHR ehr, PhysicalTest physicalTest)
{
try
{
CreatePhysicalTest(ehr, physicalTest);
}
catch (Exception ex) {
var response = CreateResponseForException("Cannot create Physical Test", HttpStatusCode.InternalServerError);
throw new HttpResponseException(response);
}
}
private void CreatePhysicalTest(EHR ehr, PhysicalTest physicalTest)
{
if (ehr.PhysicalTests == null)
{
ehr.PhysicalTests = new List<PhysicalTest>();
}
physicalTest.CreationDate = DateTime.Now;
ehr.PhysicalTests.Add(physicalTest);
_unitOfWork.Commit();
}

How to refactor sequential ifs?

I wrote this code. It's really ugly. I would like to refactor it. I MUST return a object[]. I was thinking maybe using a bool value to check if I have to move forward calling other methods and just having the final object[] creation.
private object[] TrasferisciSingoloFile(some parameters...)
{
Result result = new Result;
result = FTPRename(some parameters...);
if (result.error)
{
result.SetError("Some Problem 1");
object tip = new object[] { par as ThreadCounterManager, result };
return (object[])tip;
}
result = FTPDownloadAndCopy(some parameters...);
if (result.error)
{
result.SetError("Some Problem 2");
object tip = new object[] { par as ThreadCounterManager, result };
return (object[])tip;
}
result = FTPMove(some parameters...);
if (result.error)
{
result.SetError("Some Problem 3");
object tip = new object[] { par as ThreadCounterManager, result };
return (object[])tip;
}
result = FTPDelete(some parameters...);
if (result.error)
{
result.SetError("Some Problem 4");
object tip = new object[] { par as ThreadCounterManager, result };
return (object[])tip;
}
object tip1 = new object[] { par as ThreadCounterManager, result };
return (object[])tip1;
}
Let all the function of the suite FTPXXXX throw an exception when they found an error, so you can catch and return the error once in the catch(){} block. The "some problem xxxx message" can be decorated with a message you provide in raising the exception.
Assuming your FTP functions are somewhere else in code, consider having them throw exceptions, and use a try/catch clause in this function.
Result result = new Result();
try
{
result = FTPRename(some parameters...);
result = FTPDownloadAndCopy(some parameters...);
result = FTPMove(some parameters...);
result = FTPDelete(some parameters...);
}
catch (SomeException e)
{
return (object[])new object[] { par as ThreadCounterManager, result.SetError(e.Message) };
}
return return (object[])new object[] { par as ThreadCounterManager, result };
If you can modify the FTP methods, you could perhaps have them each assign the error message themselves, and make a helper method for creating the tip object. That way, you don't need to concern yourself with anything but checking to see if an error happened.
something like
private Object[] makeTip(arg1, arg2) {
return Object[] {arg1, arg2};
}
Result result = new Result;
result = FTPRename(some parameters...);
if(result.error)
return makeTip(par as ThreadCounterManager, result);
result = FTPDownloadAndCopy(some parameters...);
if(result.error)
return makeTip(par as ThreadCounterManager, result);
...
return makeTip(par as ThreadCounterManager, result);

Categories