Извлечение параметров из запроса компонентов URL-адрес, используя регулярные выражения


Код не является эффективным, скажем URL-адрес сопоставляется в первом случае регулярное выражение, но я до сих пор оценки второе регулярное выражение для второго случая, зная, что это взаимоисключающие и только один из них будет верным. Эффективность будет еще ниже, если я добавить больше URL-адреса в матче против.

Также есть ли способ без введения еще одной переменной красноречиво обрабатывать такие ситуации?

public void service(ServiceRequest serviceRequest, ServiceProxy serviceProxy) {
    HttpRequest request = serviceRequest.HttpRequest;
    HttpResponse response = serviceRequest.HttpResponse;

    Match match;
    bool found = false;

    match = Regex.Match(request.Path.Value, @"/articles/(\d+)/thumbnail"); // case "/articles/:id/thumbnail":
    if(match.Success) {
        found = match.Success;
        if(request.Method.Equals(HttpMethod.Get.ToString())) {
            serviceRequest.Params.Add("id", match.Groups[1].Value);
            serviceRequest.ResultData = serviceProxy.GetArticleThumbnail(serviceRequest);
        } else {
            throw new HttpException(HttpStatusCode.MethodNotAllowed, "Method Not Allowed");
        }
    }

    match = Regex.Match(request.Path.Value, @"/leads/(\d+)/collections/(.*)"); // case "/leads/:id/collections/:entityName": // share
    if(match.Success) { 
        found = match.Success;
        if(request.Method.Equals(HttpMethod.Put.ToString())) {
            serviceRequest.Params.Add("id", match.Groups[1].Value);
            serviceRequest.Params.Add("entityName", match.Groups[2].Value);
            serviceRequest.ResultData = serviceProxy.ShareCollection(serviceRequest);
        } else {
            throw new HttpException(HttpStatusCode.MethodNotAllowed, "Method Not Allowed");
        }   
    }

    if(!found) throw new HttpException(HttpStatusCode.NotFound, "Not Found"); // default case
}


402
-2
задан 13 марта 2018 в 10:03 Источник Поделиться
Комментарии
2 ответа

Добавил, если еще разветвляющейся структуры с использованием, чтобы избежать повторения выражения по.

Match match = Regex.Match(request.Path.Value, @"/articles/(\d+)/thumbnail"); // case "/articles/:id/thumbnail":
if(match.Success) {
if(request.Method.Equals(HttpMethod.Get.ToString())) {
serviceRequest.Params.Add("id", match.Groups[1].Value);
serviceRequest.ResultData = serviceProxy.GetArticleThumbnail(serviceRequest);
} else {
throw new HttpException(HttpStatusCode.MethodNotAllowed, "Method Not Allowed");
}
} else if ((match = Regex.Match(request.Path.Value, @"/leads/(\d+)/collections/(.*)")) != null && match.Success) {
if(request.Method.Equals(HttpMethod.Put.ToString())) {
serviceRequest.Params.Add("id", match.Groups[1].Value);
serviceRequest.Params.Add("entityName", match.Groups[2].Value);
serviceRequest.ResultData = serviceProxy.ShareCollection(serviceRequest);
} else {
throw new HttpException(HttpStatusCode.MethodNotAllowed, "Method Not Allowed");
}
} else {
throw new HttpException(HttpStatusCode.NotFound, "Not Found"); // none of the cases above
}

-1
ответ дан 14 марта 2018 в 10:03 Источник Поделиться

В свой ответ вам уже предложили использовать if - else if - elseно я считаю, как вы написали условиях довольно трудно читать. Вместо этого я предлагаю сохранить спички в разные переменные, а не перезаписывать одну и ту же переменную.

Match matchThumbnail = Regex.Match(request.Path.Value, @"/articles/(\d+)/thumbnail");
Match matchCollections = Regex.Match(request.Path.Value, @"/leads/(\d+)/collections/(.*)");

Таким образом, вы можете использовать их в случае, если условия без риска путаете значения из-за их совместного использования одной и той же переменной имя:

if (matchThumbnail.Success)
{
// ...
}
else if (matchCollections.Success)
{
// ...
}
else
{
throw new HttpException(HttpStatusCode.NotFound, "Not Found");
}

Для условия исключения, теперь можно использовать в одном условии. В свой ответ, я думаю, вы могли бы ошибка, поскольку, когда первый матч проходит успешно, второй не проверил из-за другого-если. (Редактировать: вы отметили, что регулярные выражения являются взаимоисключающими, поэтому я изменил выше к if - else if - else.


Я рекомендую использовать в C#-типичные общеукрепляющие стиль:

if (something)
{
// Code
}

вместо

if (something) {
// Code
}

Также я предлагаю использовать фигурные скобки, даже для oneliner'ы, как в последней строке ваш код. Даже тогда я хотел бы использовать общеукрепляющие стиль, показанный выше, но если вы хотите, чтобы сделать один-лайнер, поставив брекеты на одной линии делает его еще более читаемым:

if (something) { // Code }

вместо

if (something) // Code


В C# предпочтительный способ проверки равенства строк использует == вместо myString.Equals("");.

if (request.Method == HttpMethod.Get.ToString())

обычно считаются более читабельными, чем

if(request.Method.Equals(HttpMethod.Get.ToString()))


// case "/articles/:id/thumbnail":

// default case

Эти замечания не следует добавлять много информации, что уже не в коде, так как они являются избыточными.

// case "/leads/:id/collections/:entityName": // share

То же самое относится и здесь, однако, что // share это даже сбивает с толку, Как это не очевидно для меня то, что он должен рассказать о код, и комментарий в комментарий тоже странно. Может быть, он был на другой линии, прежде чем.

В общем я рекомендую писать комментарии на простом английском языке на их собственной линии перед кодом, они имеют в виду.

-1
ответ дан 14 марта 2018 в 11:03 Источник Поделиться