How to refactor this? ^^ - c#

Hi I have a "dumb" question. Here is my problem:
string ct=ctx.Request.ContentType;
if (!string.IsNullOrEmpty(ct))
{
ct=new ContentType(ct).MediaType;
if (!ct.Equals(KnownMimeType.Json, StringComparison.InvariantCultureIgnoreCase) || !ct.Equals(KnownMimeType.Xml, StringComparison.InvariantCultureIgnoreCase))
{
RespondWith(Status.BadRequest, "!json or xml");
return;
}
}
With the conditional Operator when an XML is sent the if body is executed which shouldn't be the case.
This is my current solution but the code with the empty method bodies is horrible. :/
string ct=ctx.Request.ContentType;
if (!string.IsNullOrEmpty(ct))
{
ct=new ContentType(ct).MediaType;
if (ct.Equals(KnownMimeType.Json, StringComparison.InvariantCultureIgnoreCase)) { }
else if (ct.Equals(KnownMimeType.Xml, StringComparison.InvariantCultureIgnoreCase)) { }
else
{
RespondWith(Status.BadRequest, "!json or xml");
return;
}
}
The goal is that every Content Type except JSON and XML should be responded with Status.BadReqeust
What can I do to refactor this?
Thanks from a newbie.

Use this.
if (!(ct.Equals(KnownMimeType.Json, StringComparison.InvariantCultureIgnoreCase) || ct.Equals(KnownMimeType.Xml, StringComparison.InvariantCultureIgnoreCase))) { RespondWith(Status.BadRequest, "!json or xml");

//For the sake of brevity and readable code.This may be your solution
string ct=ctx.Request.ContentType;
if (!string.IsNullOrEmpty(ct))
{
ct=new ContentType(ct).MediaType;
var isJson = ct.Equals(KnownMimeType.Json, StringComparison.InvariantCultureIgnoreCase);
var isXml =ct.Equals(KnownMimeType.Xml, StringComparison.InvariantCultureIgnoreCase);
if(isJson || isXml)
continue;
else
return RespondWith(Status.BadRequest, "!json or xml");
}
else
return RespondWith(Status.BadRequest, "Invalid content type");
//Maybe you can change status code instead of BadRequest for invalid content type
private Result RespondWith(Status status,string message)
{
}
//I assume that you return a dto like this
public class Result
{
public Status Status;
public string Message;
}

Related

Is there any more efficient way to code this?

Start:
if(fileName.Contains("$track"))
if(musicInfo.Tag.Track.ToString() != "") {
fileName.Replace("$track", musicInfo.Tag.Track.ToString());
}
else {
switch(System.Windows.Forms.MessageBox.Show("Error: Track # missing from tag info", "Error", System.Windows.Forms.MessageBoxButtons.AbortRetryIgnore, System.Windows.Forms.MessageBoxIcon.Error)) {
case System.Windows.Forms.DialogResult.Abort:
fileName = "ABORTED";
return fileName;
case System.Windows.Forms.DialogResult.Retry:
goto Start;
case System.Windows.Forms.DialogResult.Ignore:
fileName.Replace("$track", "");
}
}
I can't think of any better way to write this, there would be 7 more blocks of this code.
How about this?
public string GetFileName(string fileName)
{
if(fileName.Contains("$track") &&
!String.IsNullOrEmpty(musicInfo.Tag.Track.ToString())
{
return fileName.Replace("$track", musicInfo.Tag.Track.ToString());
}
var userOption = System.Windows.Forms.MessageBox.Show(
"Error: Track # missing from tag info", "Error",
System.Windows.Forms.MessageBoxButtons.AbortRetryIgnore,
System.Windows.Forms.MessageBoxIcon.Error)
switch(userOption)
{
case System.Windows.Forms.DialogResult.Abort:
return "ABORTED";
case System.Windows.Forms.DialogResult.Retry:
return GetFileName(fileName);
case System.Windows.Forms.DialogResult.Ignore:
return fileName.Replace("$track", "");
}
}

pass string array values as return type string when condition is met

I've a module which returns string array "string[]". It contains success code and author name.
var get_author = SetBookInfo(Id, Name);
this function SetBookInfo returns response code and author name.
my condition is ::
if response code is "sucess" return author name "william". ["success", "william"]
if response code is "failed" return "failed"
public string GetAuthorName()
{
var get_author = SetBookInfo(Id, Name); // returns string[]
if (get_author != null && get_author.Length > 0)
{
// how to write the above logic
}
else
return "problem in accessing the function";
}
How can I do this? Please verify if my approach is correct or not.Is there any other way? Please help.
public string GetAuthorName()
{
string []get_author = SetBookInfo(Id, Name); // returns string[]
if (get_author != null && get_author.Length > 0)
{
if(get_author[0].ToLower().Equals("success"))
return get_author[1];
else
return "failed";
}
else
return "problem in accessing the function";
}
And if you want to return multiple string than you can return List of strings.
public List<string> GetAuthorName()
{
string []get_author = SetBookInfo(Id, Name); // returns string[]
List<string> list=new List<string>();
if (get_author != null && get_author.Length > 0)
{
if(get_author[0].ToLower().Equals("success"))
{
list.Add("success");
list.Add(get_author[1]);
}
else
list.Add("failed");
}
else
list.Add("problem in accessing the function");
return list;
}
Perhaps this is what you want:
public string GetAuthorName()
{
var get_author = SetBookInfo(Id, Name); // returns string[]
if (get_author != null && get_author.Length > 0)
{
if(get_author[0] == "success") return get_author[1]; //e.g. ["success", "william"], "william" will be returned
else if (get_author[0] == "failed") return "failed";
}
else
return "problem in accessing the function";
}
providing that index of response code is 0 and that of author is 1.

Callback URL matching logic

I am working on an OAuth type module. In this i have a collection of URLs which are called as Whitelist URLs. I have to check whether the callback URL specified matches with any of these URLs in the collection.
I've written the following code. Please let me know whether i've done it correctly or am i missing some steps. Also, please let me know if i need any kind of refactoring if i want to unit test these methods.
The code is:
public class ValidateURLs
{
public bool MatchRedirectUrl(string requestUrl, IList<string> urlCollection)
{
var requestUri = new Uri(requestUrl);
foreach (var url in urlCollection)
{
var matchUri = new Uri(url);
if (IsDomainMatching(requestUri, matchUri))
{
if (IsPortMatch(requestUri, matchUri))
{
if (IsPathMatch(requestUri, matchUri))
return true;
else
return false;
}
}
}
return false;
}
private bool IsDomainMatching(Uri url1, Uri url2)
{
var result = String.Compare(url1.Host, url2.Host);
if (result == 0)
return true;
else
return false;
}
private bool IsPortMatch(Uri url1, Uri url2)
{
if (url1.Port == url2.Port)
return true;
return false;
}
private bool IsPathMatch(Uri url1, Uri url2)
{
return (url1.PathAndQuery.StartsWith(url2.PathAndQuery) || url2.PathAndQuery.StartsWith(url1.PathAndQuery));
}
}
Thanks in advance.
Regards,
Suyog
Instead of writing all this code, you should look at Uri.Compare
But you also want path.startswith to be part of the comparison. Notice it takes a bitwise enum UriComponents to define which components of the url to compare. So you could replace much of the code with Uri.Compare not comparing path and then have a startsWith path ANDed.
So all your code could be replaced with something like:
Uri.Compare(uri1, uri2, UriComponents.HostAndPort, ...) == 0 &&
(url1.PathAndQueryStartsWith(url2.PathAndQuery) || url.PathAndQueryStartsWith(...));
On a side note, code in this form:
var result = String.Compare(url1.Host, url2.Host);
if (result == 0)
return true;
else
return false;
Can simply be written as:
return String.Compare(url1.Host, url2.Host) == 0;
You should also do case insensitive compares with: StringComparison.OrdinalIgnoreCase

C# short if statement

Is there a way to do this in C# without making a new method to overload for every var type there is?
$box = !empty($toy) : $toy ? "";
The only ways I can think of to do it is either:
if (toy != null)
{
box += toy;
}
or this:
public string emptyFilter(string s) ...
public int emptyFilter(int i) ...
public bool emptyFilter(bool b) ...
public object emptyFilter(object o)
{
try
{
if (o != null)
{
return o.ToString();
}
else
{
return "";
}
}
catch (Exception ex)
{
return "exception thrown":
}
}
box += this.emptyFilter(toy);
I basically wanna check to make sure that the variable/property is set/not empty/exists/has value/etc... and return it or "" without some ridiculous about of code like above.
You could use the conditional operator (?:):
string box = (toy != null) ? toy.ToString() : "";
return variable ?? default_value;
That what you're going for? I'm a little confused considering you're showing PHP code and tag this with C#.
There's also the Nullable<T> type you can use.
How bout an extender class?
public static class ToStringExtender
{
public static String ToStringExt(this Object myObj)
{
return myObj != null ? myObj.ToString() : String.Empty;
}
}
var myobject = foo.ToStringExt()
DEMO
I'm not sure of what he wants, BUT:
string str = String.Empty;
str += true;
str += 5;
str += new object();
str += null;
This is perfectly legal. For each one adition the ToString() will be called. For null, simply nothing will be added.
The value of str at the end: True5System.Object
or,
var s = (toy?? "").ToString();
or
var s = (toy?? string.Empty).ToString();
i think there may be a slight misunderstanding about how var is used; but that's a separate topic.
maybe this below will help:
box += (toy ?? "").ToString();

Nested try-catches or is there a better way?

In the method below there are numerous case statements (many have been removed) that make calls to Manager classes. For example, the first one calls ApplicationManager.GetByGUID. Any time a "manager" class is used, security checks occur.
Problem: I have entities that may be permitted to some of these but not all. So when this method gets run, if one of them craps out it'll throw a security exception and crash the whole report.
Someone has suggested to me that I could just throw try-catch blocks around each case but the more I read the more I feel like that might be sloppy. I admittedly am not very knowledged about exceptions...I was hoping someone could suggest a way to do this with more finesse...I need to be able to get back good data and ignore the ones that throw security exceptions....or maybe try-catches are ok in this case?
Hope that makes sense...thanks
private string GetLookup(string value, string type)
{
MySqlConnection mconn = new MySqlConnection(ConfigurationSettings.AppSettings["UnicornConnectionString_SELECT"]);
try
{
mconn.Open();
lock (reportLookups)
{
if (reportLookups.ContainsKey(type+value))
return reportLookups[type+value].ToString();
else if (reportLookups.ContainsKey(value))
return reportLookups[value].ToString();
else
{
switch (type)
{
case "ATTR_APPLICATIONNAME":
if (value != Guid.Empty.ToString())
{
reportLookups.Add(type + value, applicationManager.GetByGUID(value).Name);
}
else
{
reportLookups.Add(type + value, "Unknown");
}
mconn.Close();
return reportLookups[type + value].ToString();
break;
case "ATTR_CITYNAME":
reportLookups.Add(type + value, UMConstantProvider.UMConstantProvider.GetConstant<UMString64>(int.Parse(value), UMMetricsResourceLibrary.Enumerations.ConstantType.CITY_NAME, ref mconn));
mconn.Close();
return reportLookups[type + value].ToString();
break;
case "ATTR_COUNTRYNAME":
reportLookups.Add(type + value, UMConstantProvider.UMConstantProvider.GetConstant<UMString2>(int.Parse(value), UMMetricsResourceLibrary.Enumerations.ConstantType.COUNTRY_NAME, ref mconn));
mconn.Close();
return reportLookups[type + value].ToString();
break;
case "ATTR_ITEMDURATION":
MediaItem mi = mediaItemManager.GetMediaItemByGUID(value);
if (mi.MediaItemTypeID == (int)MediaItemType.ExternalVideo || mi.MediaItemTypeID == (int)MediaItemType.ExternalAudio)
{
reportLookups.Add(type + value, mediaItemManager.GetMediaItemByGUID(value).ExternalDuration);
mconn.Close();
return reportLookups[type + value].ToString();
}
else
{
List<BinaryAsset> bins = fileSystemManager.GetBinaryAssetsByMediaItemGuid(value, mi.DraftVersion);
var durationasset = from d in bins
where d.Duration != 0
select d.Duration;
if (durationasset.Count() > 0)
{
reportLookups.Add(type + value, durationasset.ToList()[0]);
}
else
{
reportLookups.Add(type + value, 0);
mconn.Close();
return reportLookups[type + value].ToString();
}
}
break;
}
}
return string.Empty;
}
}
finally
{
mconn.Close();
}
}
As a rule, Exceptions should indicate that something went wrong. If you're expecting exceptions during the course of a typical run through this method, you should change your APIs to allow you to avoid that exception:
if (mediaItemManager.CanAccessMediaItem(value))
{
MediaItem mi = mediaItemManager.GetMediaItemByGUID(value);
....
}
Here's a quick attempt on my part to refactor this code into something more reasonable:
private string GetLookup(string value, string type)
{
var lookupKey = type + value;
using (MySqlConnection mconn = new MySqlConnection(ConfigurationSettings.AppSettings["UnicornConnectionString_SELECT"]))
{
mconn.Open();
lock (reportLookups)
{
if (reportLookups.ContainsKey(lookupKey))
{
return reportLookups[lookupKey].ToString();
}
var value = GetLookupValue(type, value);
reportLookups[lookupKey] = value;
return value;
}
}
}
private string GetLookupValue(string type, string value)
{
switch (type)
{
case "ATTR_APPLICATIONNAME":
return value == Guid.Empty.ToString()
? "Unknown"
: applicationManager.CanGetByGUID(value)
? applicationManager.GetByGUID(value).Name
: string.Empty;
case "ATTR_CITYNAME":
return UMConstantProvider.UMConstantProvider.GetConstant<UMString64>(int.Parse(value), UMMetricsResourceLibrary.Enumerations.ConstantType.CITY_NAME, ref mconn);
case "ATTR_COUNTRYNAME":
return UMConstantProvider.UMConstantProvider.GetConstant<UMString2>(int.Parse(value), UMMetricsResourceLibrary.Enumerations.ConstantType.COUNTRY_NAME, ref mconn);
case "ATTR_ITEMDURATION":
if(mediaItemManager.CanGetMediaItemByGUID(value)) {
MediaItem mi = mediaItemManager.GetMediaItemByGUID(value);
if (mi.MediaItemTypeID == (int)MediaItemType.ExternalVideo || mi.MediaItemTypeID == (int)MediaItemType.ExternalAudio)
{
return mediaItemManager.GetMediaItemByGUID(value).ExternalDuration;
}
else
{
List<BinaryAsset> bins = fileSystemManager.GetBinaryAssetsByMediaItemGuid(value, mi.DraftVersion);
var durationasset = from d in bins
where d.Duration != 0
select d.Duration;
return durationasset.FirstOrDefault() ?? "0";
}
}
else
{
return string.Empty;
}
default:
return string.Empty;
}
}
Since I don't understand the full scope of this code, I probably oversimplified some aspects of it, but you can see that there is a lot of refactoring to be done here. In the future, you might want to run some code by http://refactormycode.com/, until you get accustomed to using best practices.
Somewhere you will have some code like:
foreach(Request req in allRequests)
{
Reply result = MakeReply(req);
WriteReply(result);
}
Turn this into:
foreach(Request req in allRequests)
{
Reply result;
try
{
result = CreateReply(req);
}
catch(SecurityException ex)
{
result = CreateReplyUnauthorized();
}
catch(Exception ex) // always the last
{
LogException(ex); // for bug hunting
// Don't show the exception to the user - that's a security risk
result = CreateReplySystemError();
}
WriteReply(result);
}
You might want to put the try-catch into a separate function as the body of your foreach loop is getting large once you catch several types of exceptions.
StriplingWarrior is also right in his reply: "Exceptions should indicate that something went wrong." Let them propagate to the main loop and show them there.

Categories

Resources