Из документации Python:
Операторы присваивания в Python не копируют объекты, они создают привязки между целью и объектом. Для коллекций, которые являются изменяемыми или содержат изменяемые элементы, иногда требуется копия, чтобы можно было изменить одну копию, не изменяя другую.
blockquote>Для копирования объектов существует специальный модуль, который может выполнить работу. Python копия модуль
Используйте Uri.TryCreate для создания нового объекта Uri, только если ваша строка url является допустимым URL. Если строка не является допустимым URL, TryCreate возвращает false.
string myString = "http://someUrl";
Uri myUri;
if (Uri.TryCreate(myString, UriKind.RelativeOrAbsolute, out myUri))
{
//use the uri here
}
UPDATE
TryCreate или конструктор Uri с радостью примет строки, которые могут показаться недопустимыми, например, "Host: www.stackoverflow.com", "Host:%20www.stackoverflow.com" или "chrome:about". На самом деле, это совершенно правильные URI, в которых вместо "http" указывается пользовательская схема.
В документации к свойству Uri.Scheme приведено больше примеров, таких как "gopher:" (кто-нибудь помнит это?), "news", "mailto", "uuid".
Приложение может зарегистрировать себя как обработчик пользовательского протокола, как описано в MSDN или в других вопросах SO, например Как зарегистрировать пользовательский протокол URL в Windows?
TryCreate не предоставляет способа ограничить себя определенными схемами. Код должен проверить свойство Uri.Scheme, чтобы убедиться, что оно содержит приемлемое значение
UPDATE 2
Передача странной строки типа ">
вернет true
и создаст относительный объект Uri. Однако вызов Uri.IsWellFormedOriginalString вернет false. Поэтому вам, вероятно, нужно вызвать IsWellFormedOriginalString
, если вы хотите убедиться, что относительные Uri правильно сформированы.
С другой стороны, вызов TryCreate
с UriKind.Absolute
вернет false в этом случае.
Интересно, что Uri.IsWellFormedUriString внутренне вызывает TryCreate и затем возвращает значение IsWellFormedOriginalString
, если был создан относительный Uri.
Я столкнулся с очень похожим случаем, таким образом, я записал статический класс, который может легко использоваться наряду с тестами xUnit, чтобы проверить, что логика передала несколько случаев.
Использование (возвраты ValidationModel
):
var message = UrlValidator.Validate(input).ValidationMessage;
или
var result = UrlValidator.Validate(input).IsValid;
public class ValidationModel
{
public const string InvalidScheme = "Invalid URI scheme.";
public const string EmptyInputValue = "Empty input value.";
public const string InvalidUriFormat = "Invalid URI format.";
public const string PassedValidation = "Passed validation";
public const string HttpScheme = "http://";
public const string HttpsScheme = "https://";
public bool IsValid { get; set; }
public string ValidationMessage { get; set; }
}
public static class UrlValidator
{
public static ValidationModel Validate(string input)
{
var validation = new ValidationModel();
if (input == string.Empty)
{
validation.IsValid = false;
validation.ValidationMessage = ValidationModel.EmptyInputValue;
return validation;
}
try
{
var uri = new Uri(input);
var leftPart = uri.GetLeftPart(UriPartial.Scheme);
if (leftPart.Equals(ValidationModel.HttpScheme) || leftPart.Equals(ValidationModel.HttpsScheme))
{
validation.IsValid = true;
validation.ValidationMessage = ValidationModel.PassedValidation;
return validation;
}
validation.IsValid = false;
validation.ValidationMessage = ValidationModel.InvalidScheme;
}
catch (UriFormatException)
{
validation.IsValid = false;
validation.ValidationMessage = ValidationModel.InvalidUriFormat;
}
return validation;
}
}
public class UrlValidatorTests
{
[Theory]
[InlineData("http://intel.com", true, ValidationModel.PassedValidation)]
[InlineData("https://intel.com", true, ValidationModel.PassedValidation)]
[InlineData("https://intel.com/index.html", true, ValidationModel.PassedValidation)]
[InlineData("", false, ValidationModel.EmptyInputValue)]
[InlineData("http://", false, ValidationModel.InvalidUriFormat)]
[InlineData("//intel.com", false, ValidationModel.InvalidScheme)]
[InlineData("://intel.com", false, ValidationModel.InvalidUriFormat)]
[InlineData("f://intel.com", false, ValidationModel.InvalidScheme)]
[InlineData("htttp://intel.com", false, ValidationModel.InvalidScheme)]
[InlineData("intel.com", false, ValidationModel.InvalidUriFormat)]
[InlineData("ftp://intel.com", false, ValidationModel.InvalidScheme)]
[InlineData("http:intel.com", false, ValidationModel.InvalidUriFormat)]
public void Validate_Input_ExpectedResult(string input, bool expectedResult, string expectedInvalidMessage)
{
//Act
var result = UrlValidator.Validate(input);
//Assert
Assert.Equal(expectedResult, result.IsValid);
Assert.Equal(expectedInvalidMessage, result.ValidationMessage);
}
}