You've already forked Sonarr
							
							
				mirror of
				https://github.com/Sonarr/Sonarr.git
				synced 2025-10-31 00:07:55 +02:00 
			
		
		
		
	MediaInfo added
New: Samples will only be skipped when under 70MB and under 8 minutes in length #ND-121 fixed
This commit is contained in:
		| @@ -324,7 +324,7 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void import_new_episode_no_existing_episode_file() | ||||
|         public void should_import_new_episode_no_existing_episode_file() | ||||
|         { | ||||
|             const string fileName = "WEEDS.S03E01E02.DUAL.bluray.x264.AC3.-HELLYWOOD.mkv"; | ||||
|  | ||||
| @@ -354,48 +354,6 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests | ||||
|             Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never()); | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void should_return_null_if_file_size_is_under_40MB() | ||||
|         { | ||||
|             var series = Builder<Series> | ||||
|                     .CreateNew() | ||||
|                     .Build(); | ||||
|  | ||||
|             const string path = @"C:\Test\TV\30.rock.s01e01.pilot.avi"; | ||||
|  | ||||
|             Mocker.GetMock<MediaFileProvider>() | ||||
|                     .Setup(m => m.Exists(path)) | ||||
|                     .Returns(false); | ||||
|  | ||||
|             Mocker.GetMock<DiskProvider>() | ||||
|                     .Setup(d => d.GetSize(path)) | ||||
|                     .Returns(20.Megabytes()); | ||||
|  | ||||
|             Mocker.Resolve<DiskScanProvider>().ImportFile(series, path).Should().BeNull(); | ||||
|         } | ||||
|  | ||||
|         private static void VerifyFileImport(EpisodeFile result, AutoMoqer Mocker, Episode fakeEpisode, long size) | ||||
|         { | ||||
|             result.Should().NotBeNull(); | ||||
|             result.SeriesId.Should().Be(fakeEpisode.SeriesId); | ||||
|             result.Size.Should().Be(size); | ||||
|             result.DateAdded.Should().HaveDay(DateTime.Now.Day); | ||||
|             Mocker.GetMock<MediaFileProvider>().Verify(p => p.Add(It.IsAny<EpisodeFile>()), Times.Once()); | ||||
|  | ||||
|             //Get the count of episodes linked | ||||
|             var count = Mocker.GetMock<EpisodeProvider>().Object.GetEpisodesByParseResult(null).Count; | ||||
|  | ||||
|             Mocker.GetMock<EpisodeProvider>().Verify(p => p.UpdateEpisode(It.Is<Episode>(e => e.EpisodeFileId == result.EpisodeFileId)), Times.Exactly(count)); | ||||
|         } | ||||
|  | ||||
|         private static void VerifySkipImport(EpisodeFile result, AutoMoqer Mocker) | ||||
|         { | ||||
|             result.Should().BeNull(); | ||||
|             Mocker.GetMock<MediaFileProvider>().Verify(p => p.Add(It.IsAny<EpisodeFile>()), Times.Never()); | ||||
|             Mocker.GetMock<EpisodeProvider>().Verify(p => p.UpdateEpisode(It.IsAny<Episode>()), Times.Never()); | ||||
|             Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never()); | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void should_set_parseResult_SceneSource_if_not_in_series_Path() | ||||
|         { | ||||
| @@ -441,5 +399,115 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests | ||||
|  | ||||
|             Mocker.Verify<EpisodeProvider>(s => s.GetEpisodesByParseResult(It.Is<EpisodeParseResult>(p => p.SceneSource == false)), Times.Once()); | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void should_return_null_if_file_size_is_under_70MB_and_runTime_under_8_minutes() | ||||
|         { | ||||
|             var series = Builder<Series> | ||||
|                     .CreateNew() | ||||
|                     .Build(); | ||||
|  | ||||
|             const string path = @"C:\Test\TV\30.rock.s01e01.pilot.avi"; | ||||
|  | ||||
|             Mocker.GetMock<MediaFileProvider>() | ||||
|                     .Setup(m => m.Exists(path)) | ||||
|                     .Returns(false); | ||||
|  | ||||
|             Mocker.GetMock<DiskProvider>() | ||||
|                     .Setup(d => d.GetSize(path)) | ||||
|                     .Returns(20.Megabytes()); | ||||
|  | ||||
|             Mocker.GetMock<MediaInfoProvider>() | ||||
|                   .Setup(s => s.GetRunTime(path)) | ||||
|                   .Returns(300); | ||||
|  | ||||
|             Mocker.Resolve<DiskScanProvider>().ImportFile(series, path).Should().BeNull(); | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void should_import_if_file_size_is_under_70MB_but_runTime_over_8_minutes() | ||||
|         { | ||||
|             var fakeSeries = Builder<Series>.CreateNew().Build(); | ||||
|  | ||||
|             var fakeEpisode = Builder<Episode>.CreateNew() | ||||
|                 .With(e => e.EpisodeFileId = 0) | ||||
|                 .With(e => e.EpisodeFile = null) | ||||
|                 .Build(); | ||||
|  | ||||
|             const string path = @"C:\Test\TV\30.rock.s01e01.pilot.avi"; | ||||
|  | ||||
|             Mocker.GetMock<MediaFileProvider>() | ||||
|                     .Setup(m => m.Exists(path)) | ||||
|                     .Returns(false); | ||||
|  | ||||
|             Mocker.GetMock<DiskProvider>() | ||||
|                     .Setup(d => d.GetSize(path)) | ||||
|                     .Returns(20.Megabytes()); | ||||
|  | ||||
|             Mocker.GetMock<MediaInfoProvider>() | ||||
|                   .Setup(s => s.GetRunTime(path)) | ||||
|                   .Returns(600); | ||||
|  | ||||
|             Mocker.GetMock<EpisodeProvider>() | ||||
|                 .Setup(e => e.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>())).Returns(new List<Episode> { fakeEpisode }); | ||||
|  | ||||
|             var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, path); | ||||
|  | ||||
|             VerifyFileImport(result, Mocker, fakeEpisode, 20.Megabytes()); | ||||
|             Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never()); | ||||
|         } | ||||
|  | ||||
|         [Test] | ||||
|         public void should_import_if_file_size_is_over_70MB_but_runTime_under_8_minutes() | ||||
|         { | ||||
|             With80MBFile(); | ||||
|  | ||||
|             var fakeSeries = Builder<Series>.CreateNew().Build(); | ||||
|  | ||||
|             var fakeEpisode = Builder<Episode>.CreateNew() | ||||
|                 .With(e => e.EpisodeFileId = 0) | ||||
|                 .With(e => e.EpisodeFile = null) | ||||
|                 .Build(); | ||||
|  | ||||
|             const string path = @"C:\Test\TV\30.rock.s01e01.pilot.avi"; | ||||
|  | ||||
|             Mocker.GetMock<MediaFileProvider>() | ||||
|                     .Setup(m => m.Exists(path)) | ||||
|                     .Returns(false); | ||||
|  | ||||
|             Mocker.GetMock<MediaInfoProvider>() | ||||
|                   .Setup(s => s.GetRunTime(path)) | ||||
|                   .Returns(600); | ||||
|  | ||||
|             Mocker.GetMock<EpisodeProvider>() | ||||
|                 .Setup(e => e.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>())).Returns(new List<Episode> { fakeEpisode }); | ||||
|  | ||||
|             var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, path); | ||||
|  | ||||
|             VerifyFileImport(result, Mocker, fakeEpisode, SIZE); | ||||
|             Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never()); | ||||
|         } | ||||
|  | ||||
|         private static void VerifyFileImport(EpisodeFile result, AutoMoqer Mocker, Episode fakeEpisode, long size) | ||||
|         { | ||||
|             result.Should().NotBeNull(); | ||||
|             result.SeriesId.Should().Be(fakeEpisode.SeriesId); | ||||
|             result.Size.Should().Be(size); | ||||
|             result.DateAdded.Should().HaveDay(DateTime.Now.Day); | ||||
|             Mocker.GetMock<MediaFileProvider>().Verify(p => p.Add(It.IsAny<EpisodeFile>()), Times.Once()); | ||||
|  | ||||
|             //Get the count of episodes linked | ||||
|             var count = Mocker.GetMock<EpisodeProvider>().Object.GetEpisodesByParseResult(null).Count; | ||||
|  | ||||
|             Mocker.GetMock<EpisodeProvider>().Verify(p => p.UpdateEpisode(It.Is<Episode>(e => e.EpisodeFileId == result.EpisodeFileId)), Times.Exactly(count)); | ||||
|         } | ||||
|  | ||||
|         private static void VerifySkipImport(EpisodeFile result, AutoMoqer Mocker) | ||||
|         { | ||||
|             result.Should().BeNull(); | ||||
|             Mocker.GetMock<MediaFileProvider>().Verify(p => p.Add(It.IsAny<EpisodeFile>()), Times.Never()); | ||||
|             Mocker.GetMock<EpisodeProvider>().Verify(p => p.UpdateEpisode(It.IsAny<Episode>()), Times.Never()); | ||||
|             Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								NzbDrone.Core/MediaInfo.dll
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								NzbDrone.Core/MediaInfo.dll
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										25
									
								
								NzbDrone.Core/Model/MediaInfoModel.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								NzbDrone.Core/Model/MediaInfoModel.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
|  | ||||
| namespace NzbDrone.Core.Model | ||||
| { | ||||
|     public class MediaInfoModel | ||||
|     { | ||||
|         public string VideoCodec { get; set; } | ||||
|         public int VideoBitrate { get; set; } | ||||
|         public int Width { get; set; } | ||||
|         public int Height { get; set; } | ||||
|         public string AudioFormat { get; set; } | ||||
|         public int AudioBitrate { get; set; } | ||||
|         public int RunTime { get; set; } | ||||
|         public int AudioStreamCount { get; set; } | ||||
|         public int AudioChannels { get; set; } | ||||
|         public string AudioProfile { get; set; } | ||||
|         public decimal VideoFps { get; set; } | ||||
|         public string AudioLanguages { get; set; } | ||||
|         public string Subtitles { get; set; } | ||||
|         public string ScanType { get; set; } | ||||
|     } | ||||
| } | ||||
| @@ -145,6 +145,9 @@ | ||||
|     <Reference Include="Ionic.Zip"> | ||||
|       <HintPath>..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll</HintPath> | ||||
|     </Reference> | ||||
|     <Reference Include="MediaInfoDotNet"> | ||||
|       <HintPath>..\packages\MediaInfoNet.0.3\lib\MediaInfoDotNet.dll</HintPath> | ||||
|     </Reference> | ||||
|     <Reference Include="Microsoft.CSharp" /> | ||||
|     <Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> | ||||
|       <Private>True</Private> | ||||
| @@ -277,6 +280,7 @@ | ||||
|     <Compile Include="Model\AtomicParsleyTitleType.cs" /> | ||||
|     <Compile Include="Model\ConnectionInfoModel.cs" /> | ||||
|     <Compile Include="Model\BacklogSettingType.cs" /> | ||||
|     <Compile Include="Model\MediaInfoModel.cs" /> | ||||
|     <Compile Include="Model\Nzbx\NzbxSearchItem.cs" /> | ||||
|     <Compile Include="Model\Nzbx\NzbxRecentItem.cs" /> | ||||
|     <Compile Include="Model\Nzbx\NzbxVotesModel.cs" /> | ||||
| @@ -314,6 +318,7 @@ | ||||
|     <Compile Include="AutofacSignalrDependencyResolver.cs" /> | ||||
|     <Compile Include="Providers\BannerProvider.cs" /> | ||||
|     <Compile Include="Providers\DecisionEngine\LanguageSpecification.cs" /> | ||||
|     <Compile Include="Providers\MediaInfoProvider.cs" /> | ||||
|     <Compile Include="Providers\SearchProvider2.cs" /> | ||||
|     <Compile Include="Providers\DecisionEngine\AllowedReleaseGroupSpecification.cs" /> | ||||
|     <Compile Include="Providers\DecisionEngine\CustomStartDateSpecification.cs" /> | ||||
| @@ -618,6 +623,9 @@ | ||||
|   <ItemGroup> | ||||
|     <Content Include="GettingStarted.txt" /> | ||||
|     <Content Include="Json.NET.license.txt" /> | ||||
|     <Content Include="MediaInfo.dll"> | ||||
|       <CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||||
|     </Content> | ||||
|     <Content Include="NzbDrone.ico" /> | ||||
|     <Content Include="license.txt" /> | ||||
|   </ItemGroup> | ||||
|   | ||||
| @@ -23,12 +23,13 @@ namespace NzbDrone.Core.Providers | ||||
|         private readonly SignalRProvider _signalRProvider; | ||||
|         private readonly ConfigProvider _configProvider; | ||||
|         private readonly RecycleBinProvider _recycleBinProvider; | ||||
|         private readonly MediaInfoProvider _mediaInfoProvider; | ||||
|  | ||||
|         public DiskScanProvider(DiskProvider diskProvider, EpisodeProvider episodeProvider, | ||||
|                                 SeriesProvider seriesProvider, MediaFileProvider mediaFileProvider, | ||||
|                                 ExternalNotificationProvider externalNotificationProvider, DownloadProvider downloadProvider, | ||||
|                                 SignalRProvider signalRProvider, ConfigProvider configProvider, | ||||
|                                 RecycleBinProvider recycleBinProvider) | ||||
|                                 RecycleBinProvider recycleBinProvider, MediaInfoProvider mediaInfoProvider) | ||||
|         { | ||||
|             _diskProvider = diskProvider; | ||||
|             _episodeProvider = episodeProvider; | ||||
| @@ -39,6 +40,7 @@ namespace NzbDrone.Core.Providers | ||||
|             _signalRProvider = signalRProvider; | ||||
|             _configProvider = configProvider; | ||||
|             _recycleBinProvider = recycleBinProvider; | ||||
|             _mediaInfoProvider = mediaInfoProvider; | ||||
|         } | ||||
|  | ||||
|         public DiskScanProvider() | ||||
| @@ -110,10 +112,9 @@ namespace NzbDrone.Core.Providers | ||||
|             } | ||||
|  | ||||
|             long size = _diskProvider.GetSize(filePath); | ||||
|              | ||||
|             //Todo: We shouldn't skip on file size alone, 64MB Family Guy episodes are skipped... | ||||
|             //Skip any file under 70MB - New samples don't even have sample in the name... | ||||
|             if (size < Constants.IgnoreFileSize) | ||||
|             var runTime = _mediaInfoProvider.GetRunTime(filePath); | ||||
|  | ||||
|             if(size < Constants.IgnoreFileSize && runTime < 480) | ||||
|             { | ||||
|                 Logger.Trace("[{0}] appears to be a sample. skipping.", filePath); | ||||
|                 return null; | ||||
|   | ||||
							
								
								
									
										141
									
								
								NzbDrone.Core/Providers/MediaInfoProvider.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								NzbDrone.Core/Providers/MediaInfoProvider.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,141 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using MediaInfoLib; | ||||
| using NLog; | ||||
| using NzbDrone.Common; | ||||
| using NzbDrone.Core.Model; | ||||
|  | ||||
| namespace NzbDrone.Core.Providers | ||||
| { | ||||
|     public class MediaInfoProvider | ||||
|     { | ||||
|         private readonly DiskProvider _diskProvider; | ||||
|  | ||||
|         private static readonly Logger logger = LogManager.GetCurrentClassLogger(); | ||||
|  | ||||
|         public MediaInfoProvider(DiskProvider diskProvider) | ||||
|         { | ||||
|             _diskProvider = diskProvider; | ||||
|         } | ||||
|  | ||||
|         public MediaInfoProvider() | ||||
|         { | ||||
|         } | ||||
|  | ||||
|         public virtual MediaInfoModel GetMediaInfo(string filename) | ||||
|         { | ||||
|             if (!_diskProvider.FileExists(filename)) | ||||
|                 throw new FileNotFoundException("Media file does not exist: " + filename); | ||||
|  | ||||
|             var mediaInfo = new MediaInfo(); | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 logger.Trace("Getting media info from {0}", filename); | ||||
|  | ||||
|                 mediaInfo.Option("ParseSpeed", "0.2"); | ||||
|                 int open = mediaInfo.Open(filename); | ||||
|  | ||||
|                 if (open != 0) | ||||
|                 { | ||||
|                     int width; | ||||
|                     int height; | ||||
|                     int videoBitRate; | ||||
|                     int audioBitRate; | ||||
|                     int runTime; | ||||
|                     int streamCount; | ||||
|                     int audioChannels; | ||||
|  | ||||
|                     string subtitles = mediaInfo.Get(StreamKind.General, 0, "Text_Language_List"); | ||||
|                     string scanType = mediaInfo.Get(StreamKind.Video, 0, "ScanType"); | ||||
|                     Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Width"), out width); | ||||
|                     Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Height"), out height); | ||||
|                     Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitRate"), out videoBitRate); | ||||
|  | ||||
|                     string aBitRate = mediaInfo.Get(StreamKind.Audio, 0, "BitRate"); | ||||
|                     int ABindex = aBitRate.IndexOf(" /"); | ||||
|                     if (ABindex > 0) | ||||
|                         aBitRate = aBitRate.Remove(ABindex); | ||||
|  | ||||
|                     Int32.TryParse(aBitRate, out audioBitRate); | ||||
|                     Int32.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out runTime); | ||||
|                     Int32.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "StreamCount"), out streamCount); | ||||
|  | ||||
|                     string audioChannelsStr = mediaInfo.Get(StreamKind.Audio, 0, "Channel(s)"); | ||||
|                     int ACindex = audioChannelsStr.IndexOf(" /"); | ||||
|                     if (ACindex > 0) | ||||
|                         audioChannelsStr = audioChannelsStr.Remove(ACindex); | ||||
|  | ||||
|                     string audioLanguages = mediaInfo.Get(StreamKind.General, 0, "Audio_Language_List"); | ||||
|                     decimal videoFrameRate = Decimal.Parse(mediaInfo.Get(StreamKind.Video, 0, "FrameRate")); | ||||
|                     string audioProfile = mediaInfo.Get(StreamKind.Audio, 0, "Format_Profile"); | ||||
|  | ||||
|                     int APindex = audioProfile.IndexOf(" /"); | ||||
|                     if (APindex > 0) | ||||
|                         audioProfile = audioProfile.Remove(APindex); | ||||
|  | ||||
|                     Int32.TryParse(audioChannelsStr, out audioChannels); | ||||
|                     var mediaInfoModel = new MediaInfoModel | ||||
|                                                 { | ||||
|                                                     VideoCodec = mediaInfo.Get(StreamKind.Video, 0, "Codec/String"), | ||||
|                                                     VideoBitrate = videoBitRate, | ||||
|                                                     Height = height, | ||||
|                                                     Width = width, | ||||
|                                                     AudioFormat = mediaInfo.Get(StreamKind.Audio, 0, "Format"), | ||||
|                                                     AudioBitrate = audioBitRate, | ||||
|                                                     RunTime = (runTime / 1000), //InSeconds | ||||
|                                                     AudioStreamCount = streamCount, | ||||
|                                                     AudioChannels = audioChannels, | ||||
|                                                     AudioProfile = audioProfile.Trim(), | ||||
|                                                     VideoFps = videoFrameRate, | ||||
|                                                     AudioLanguages = audioLanguages, | ||||
|                                                     Subtitles = subtitles, | ||||
|                                                     ScanType = scanType | ||||
|                                                 }; | ||||
|  | ||||
|                     mediaInfo.Close(); | ||||
|                     return mediaInfoModel; | ||||
|                 } | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 logger.ErrorException("Unable to parse media info from file: " + filename, ex); | ||||
|                 mediaInfo.Close(); | ||||
|             } | ||||
|  | ||||
|             return null; | ||||
|         } | ||||
|  | ||||
|         public virtual Int32 GetRunTime(string filename) | ||||
|         { | ||||
|             var mediaInfo = new MediaInfo(); | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 logger.Trace("Getting media info from {0}", filename); | ||||
|  | ||||
|                 mediaInfo.Option("ParseSpeed", "0.2"); | ||||
|                 int open = mediaInfo.Open(filename); | ||||
|  | ||||
|                 if (open != 0) | ||||
|                 { | ||||
|                     int runTime; | ||||
|                     Int32.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out runTime); | ||||
|  | ||||
|                     mediaInfo.Close(); | ||||
|                     return runTime / 1000; //Convert to seconds | ||||
|                 } | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 logger.ErrorException("Unable to parse media info from file: " + filename, ex); | ||||
|                 mediaInfo.Close(); | ||||
|             } | ||||
|  | ||||
|             return 0; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -4,6 +4,7 @@ | ||||
|   <package id="DataTables.Mvc.Core" version="0.1.0.85" /> | ||||
|   <package id="DotNetZip" version="1.9.1.8" /> | ||||
|   <package id="Growl" version="0.6" /> | ||||
|   <package id="MediaInfoNet" version="0.3" targetFramework="net40" /> | ||||
|   <package id="Microsoft.SqlServer.Compact" version="4.0.8876.1" targetFramework="net40" /> | ||||
|   <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" /> | ||||
|   <package id="MiniProfiler" version="2.0.2" /> | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
|     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> | ||||
|       <dependentAssembly> | ||||
|         <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /> | ||||
|         <bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="4.5.0.0" /> | ||||
|         <bindingRedirect oldVersion="0.0.0.0-4.0.8.0" newVersion="4.0.8.0" /> | ||||
|       </dependentAssembly> | ||||
|       <dependentAssembly> | ||||
|         <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" /> | ||||
|   | ||||
| @@ -72,7 +72,7 @@ | ||||
|       </dependentAssembly> | ||||
|       <dependentAssembly> | ||||
|         <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /> | ||||
|         <bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="4.5.0.0" /> | ||||
|         <bindingRedirect oldVersion="0.0.0.0-4.0.8.0" newVersion="4.0.8.0" /> | ||||
|       </dependentAssembly> | ||||
|     </assemblyBinding> | ||||
|   </runtime> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user