尝试创建多个唯一的短 URL

Trying to create multiple unique short URLs

我想制作一个 post 方法,当给定一个包含 JSON 中多个 URL 的正文时,returns 是一个缩短的 URL 列表.

这是我的post方法:

public class MyServices : Service
{
    public object Post(CreateShortUrlRequest request) //Post an array/list of URLs to the database and get a respective list of short URL
    {
        using (Task4URLEntities db = new Task4URLEntities())
        {
            var urls = new List<string>();
            foreach (string LongUrl in request.LongUrl)
            {
                var item = new ShortURLs
                {
                    LongUrl = LongUrl,
                    ShortUrl = GetUrl(),
                    DateCreated = DateTime.Now
                };
                urls.Add($"http://localhost/{item.ShortUrl}");
                db.ShortURLs.Add(item);
            }

            var campaign = new Campaign
            {
                CampaignName = request.CampaignName,
                Enddate = request.Enddate,
                Startdate = request.Startdate
            };

            db.Campaign.Add(campaign);

            try
            {
                db.SaveChanges();
            }
            catch (DbEntityValidationException ex)
            {
                foreach (var entityValidationErrors in ex.EntityValidationErrors)
                {
                    foreach (var validationError in entityValidationErrors.ValidationErrors)
                    {
                        Response.WriteAsync("Property: " + validationError.PropertyName + " Error: " + validationError.ErrorMessage);
                    }
                }
            }

            return new CreateShortUrlResponse
            {
                Response = urls,
                CampaignId = campaign.CampaignId
            };
        }
    }

    public string GetUrl()
    {
        var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        var stringChars = new char[5];
        var random = new Random();
        for (int i = 0; i < stringChars.Length; i++)
        {
            stringChars[i] = chars[random.Next(chars.Length)];
        }
        var finalString = new String(stringChars);
        return finalString;
    }

 }

我的问题是,当我向 Postman 发送 post 请求以获取 JSON 中的 URL 列表时,我将得到唯一的 URL 作为响应对于第一个 post 如果我再次点击发送然后我会得到一个响应,其中每个返回的短 URL 都是相同的。

我该如何纠正这个问题?

我猜当你说“每个返回的短 URL 都是相同的”时,你的意思是 CreateShortUrlResponse.Response 属性 包含完全相同的 URL n 次,其中 n 是您请求的 URL 的次数。基于这种行为,我还假设这是一个 .NET Framework 项目,而不是 .NET Core 项目。

如果是这样,那么问题是在如此紧密的循环中创建 Random 的新实例会导致每个实例都使用完全相同的种子值创建。当您在 .NET Framework 中使用空构造函数创建 Random 的实例时,它使用 Environment.TickCount 作为种子。因此,如果您快速连续创建两个 Random 实例,它们将具有相同的种子,因此生成相同的值。

documentation on Random speaks to this.

On the .NET Framework, initializing two random number generators in a tight loop or in rapid succession creates two random number generators that can produce identical sequences of random numbers. In most cases, this is not the developer's intent and can lead to performance issues, because instantiating and initializing a random number generator is a relatively expensive process.

Both to improve performance and to avoid inadvertently creating separate random number generators that generate identical numeric sequences, we recommend that you create one Random object to generate many random numbers over time, instead of creating new Random objects to generate one random number.

However, the Random class isn't thread safe. If you call Random methods from multiple threads, follow the guidelines discussed in the next section.

因此,您可以使 Random 实例成为 MyServices class 的成员,而不是每次调用 GetUrl.[=24 时都创建一个新实例=]

public class MyServices : Service
{
    public object Post(CreateShortUrlRequest request) //Post an array/list of URLs to the database and get a respective list of short URL
    {
        using (Task4URLEntities db = new Task4URLEntities())
        {
            var urls = new List<string>();
            foreach (string LongUrl in request.LongUrl)
            {
                var item = new ShortURLs
                {
                    LongUrl = LongUrl,
                    ShortUrl = GetUrl(),
                    DateCreated = DateTime.Now
                };
                urls.Add($"http://localhost/{item.ShortUrl}");
                db.ShortURLs.Add(item);
            }

            var campaign = new Campaign
            {
                CampaignName = request.CampaignName,
                Enddate = request.Enddate,
                Startdate = request.Startdate
            };

            db.Campaign.Add(campaign);

            try
            {
                db.SaveChanges();
            }
            catch (DbEntityValidationException ex)
            {
                foreach (var entityValidationErrors in ex.EntityValidationErrors)
                {
                    foreach (var validationError in entityValidationErrors.ValidationErrors)
                    {
                        Response.WriteAsync("Property: " + validationError.PropertyName + " Error: " + validationError.ErrorMessage);
                    }
                }
            }

            return new CreateShortUrlResponse
            {
                Response = urls,
                CampaignId = campaign.CampaignId
            };
        }
    }

    public string GetUrl()
    {
        var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        var stringChars = new char[5];
        for (int i = 0; i < stringChars.Length; i++)
        {
            stringChars[i] = chars[_rng.Next(chars.Length)];
        }
        var finalString = new String(stringChars);
        return finalString;
    }
    private Random _rng = new Random();
 }