title: Unable to get the PublishAssetURL in azure media Service
body: <p>I am trying to upload the mp4 file from Controller into azure blob storage right after when i done uploading, i am creating asset from the same blob which i just uploaded every thing seems working fine but i don't know some how i am unable to get the publishAssetURL </p>
  
  <p><code>var manifestFile = asset.AssetFiles.Where(x =&gt; 
                   x.Name.EndsWith(".ism")).FirstOrDefault();</code></p>
  
  <p>This issue is on this line the <code>manifestFile</code> is coming null.</p>
  
  <pre><code>    public string CreateAssetFromExistingBlobs(CloudBlobContainer sourceBlobContainer, CloudStorageAccount _destinationStorageAccount, CloudMediaContext _context, AzureStorageMultipartFormDataStreamProvider provider )
      {
          CloudBlobClient destBlobStorage = _destinationStorageAccount.CreateCloudBlobClient();
  
          // Create a new asset. 
          IAsset asset = _context.Assets.Create("NewAsset_" + Guid.NewGuid(), AssetCreationOptions.None);
  
          IAccessPolicy writePolicy = _context.AccessPolicies.Create("writePolicy",
              TimeSpan.FromHours(24), AccessPermissions.Write);
  
          ILocator destinationLocator =
              _context.Locators.CreateLocator(LocatorType.Sas, asset, writePolicy);
  
          // Get the asset container URI and Blob copy from mediaContainer to assetContainer. 
          CloudBlobContainer destAssetContainer =
              destBlobStorage.GetContainerReference((new Uri(destinationLocator.Path)).Segments[1]);
  
          if (destAssetContainer.CreateIfNotExists())
          {
              destAssetContainer.SetPermissions(new BlobContainerPermissions
              {
                  PublicAccess = BlobContainerPublicAccessType.Blob
              });
          }
  
          var blob = sourceBlobContainer.GetBlockBlobReference(provider.FileData.FirstOrDefault().LocalFileName);
          blob.FetchAttributes();
  
          var assetFile = asset.AssetFiles.Create(blob.Name);
          CopyBlob(blob, destAssetContainer);
          assetFile.ContentFileSize = blob.Properties.Length;
          assetFile.Update();
          asset.Update();
  
          destinationLocator.Delete();
          writePolicy.Delete();
  
          // Set the primary asset file.
          // If, for example, we copied a set of Smooth Streaming files, 
          // set the .ism file to be the primary file. 
          // If we, for example, copied an .mp4, then the mp4 would be the primary file. 
          var ismAssetFile = asset.AssetFiles.ToList().
              Where(f =&gt; f.Name.EndsWith(".mp4", StringComparison.OrdinalIgnoreCase)).ToArray().FirstOrDefault();
  
          // The following code assigns the first .ism file as the primary file in the asset.
          // An asset should have one .ism file.  
          if (ismAssetFile != null)
          {
              ismAssetFile.IsPrimary = true;
              ismAssetFile.Update();
          }
  
          IAsset encodedAsset = EncodeToAdaptiveBitrateMP4Set(asset, _context);
  
         return PublishAssetGetURLs(encodedAsset, _context);
  
  
      }
  
      private void CopyBlob(ICloudBlob sourceBlob, CloudBlobContainer destinationContainer)
      {
          var signature = sourceBlob.GetSharedAccessSignature(new SharedAccessBlobPolicy
          {
              Permissions = SharedAccessBlobPermissions.Read,
              SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24)
          });
  
          var destinationBlob = destinationContainer.GetBlockBlobReference(sourceBlob.Name);
  
          if (destinationBlob.Exists())
          {
              Console.WriteLine(string.Format("Destination blob '{0}' already exists. Skipping.", destinationBlob.Uri));
          }
          else
          {
  
              // Display the size of the source blob.
              Console.WriteLine(sourceBlob.Properties.Length);
  
              Console.WriteLine(string.Format("Copy blob '{0}' to '{1}'", sourceBlob.Uri, destinationBlob.Uri));
              destinationBlob.StartCopy(new Uri(sourceBlob.Uri.AbsoluteUri + signature));
  
              while (true)
              {
                  // The StartCopyFromBlob is an async operation, 
                  // so we want to check if the copy operation is completed before proceeding. 
                  // To do that, we call FetchAttributes on the blob and check the CopyStatus. 
                  destinationBlob.FetchAttributes();
                  if (destinationBlob.CopyState.Status != CopyStatus.Pending)
                  {
                      break;
                  }
                  //It's still not completed. So wait for some time.
                  System.Threading.Thread.Sleep(1000);
              }
  
              // Display the size of the destination blob.
              Console.WriteLine(destinationBlob.Properties.Length);
  
          }
      }
  
      private IAsset EncodeToAdaptiveBitrateMP4Set(IAsset asset, CloudMediaContext _context)
      {
          // Declare a new job.
          IJob job = _context.Jobs.Create("Media Encoder Standard Job");
          // Get a media processor reference, and pass to it the name of the 
          // processor to use for the specific task.
          IMediaProcessor processor = GetLatestMediaProcessorByName("Media Encoder Standard",_context);
  
          // Create a task with the encoding details, using a string preset.
          // In this case "Adaptive Streaming" preset is used.
          ITask task = job.Tasks.AddNew("My encoding task",
              processor,
              "Adaptive Streaming",
              TaskOptions.None);
  
          // Specify the input asset to be encoded.
          task.InputAssets.Add(asset);
          // Add an output asset to contain the results of the job. 
          // This output is specified as AssetCreationOptions.None, which 
          // means the output asset is not encrypted. 
          task.OutputAssets.AddNew("Output asset",
              AssetCreationOptions.None);
  
          job.StateChanged += new EventHandler&lt;JobStateChangedEventArgs&gt;(JobStateChanged);
          job.Submit();
          job.GetExecutionProgressTask(CancellationToken.None).Wait();
  
          return job.OutputMediaAssets[0];
      }
  
  
      public void JobStateChanged(object sender, JobStateChangedEventArgs e)
      {
          //Console.WriteLine("Job state changed event:");
          //Console.WriteLine("  Previous state: " + e.PreviousState);
          //Console.WriteLine("  Current state: " + e.CurrentState);
          switch (e.CurrentState)
          {
              case JobState.Finished:
                  //Console.WriteLine();
                  //Console.WriteLine("Job is finished. Please wait while local tasks or downloads complete...");
                  break;
              case JobState.Canceling:
              case JobState.Queued:
              case JobState.Scheduled:
              case JobState.Processing:
                  //Console.WriteLine("Please wait...\n");
                  break;
              case JobState.Canceled:
              case JobState.Error:
  
                  // Cast sender as a job.
                  IJob job = (IJob)sender;
  
                  // Display or log error details as needed.
                  break;
              default:
                  break;
          }
      }
  
  
      private IMediaProcessor GetLatestMediaProcessorByName(string mediaProcessorName, CloudMediaContext _context)
      {
          var processor = _context.MediaProcessors.Where(p =&gt; p.Name == mediaProcessorName).
          ToList().OrderBy(p =&gt; new Version(p.Version)).LastOrDefault();
  
          if (processor == null)
              throw new ArgumentException(string.Format("Unknown media processor", mediaProcessorName));
  
          return processor;
      }
  
  
      private string PublishAssetGetURLs(IAsset asset, CloudMediaContext _context)
      {
  
  
  
          // Create a 30-day readonly access policy. 
          // You cannot create a streaming locator using an AccessPolicy that includes write or delete permissions.
          IAccessPolicy policy = _context.AccessPolicies.Create("Streaming policy",
              TimeSpan.FromDays(30),
              AccessPermissions.Read);
  
          // Create a locator to the streaming content on an origin. 
          ILocator originLocator = _context.Locators.CreateLocator(LocatorType.OnDemandOrigin, asset,
              policy,
              DateTime.UtcNow.AddMinutes(-5));
  
          // Display some useful values based on the locator.
          //Console.WriteLine("Streaming asset base path on origin: ");
          //Console.WriteLine(originLocator.Path);
          //Console.WriteLine();
  
          // Get a reference to the streaming manifest file from the  
          // collection of files in the asset. 
  
          var manifestFile = asset.AssetFiles.Where(x =&gt; x.Name.EndsWith(".ism")).FirstOrDefault();
  
  
  
  
  
          // Create a full URL to the manifest file. Use this for playback
          // in streaming media clients. 
          string urlForClientStreaming = originLocator.Path + manifestFile.Name + "/manifest";
         // Console.WriteLine("URL to manifest for client streaming using Smooth Streaming protocol: ");
         // Console.WriteLine(urlForClientStreaming);
         // Console.WriteLine("URL to manifest for client streaming using HLS protocol: ");
          return urlForClientStreaming + "(format=m3u8-aapl)";
         // Console.WriteLine("URL to manifest for client streaming using MPEG DASH protocol: ");
         // Console.WriteLine(urlForClientStreaming + "(format=mpd-time-csf)");
         // Console.WriteLine();
      }
  </code></pre>