Reputation: 5341
Im displaying an image on my page like so
<img src="data:image;base64,@System.Convert.ToBase64String(Model.PhotoDisplay)" />
my model
public byte[] PhotoDisplay { get; set; }
However PhotoDisplay may not have an image so may returns null so im getting an error
An exception of type 'System.ArgumentNullException' occurred in mscorlib.dll but was not handled in user code
Additional information: Value cannot be null."
How what the best way to handle this, example would be great.
Upvotes: 2
Views: 1079
Reputation: 12606
If you are looking to keep your markup as simple as possible, you can do this:
<img src="data:image;base64,@System.Convert.ToBase64String(Model.PhotoDisplay ?? new byte[0])" onerror="this.src='';" />
What this essentially does is if your Mode.PhotoDisplay
proeprty is null, it passes in an empty byte
array to the System.Convert.ToBase64String
method. The method will then return an empty string.
At this point, the browser will display some sort of "broken image" icon since the src
attribute will no longer be valid. Because it is no longer valid, the onerror
handler will be invoked. I am simply setting the src
attribute to an empty string. You can handle it differently if you'd like (e.g. set the src
to a URL, hide the tag completely, etc.).
Upvotes: 0
Reputation: 10756
You could use shared templates to do this.
You could annotate your byte array with something like
[UIHint("BytePhoto")]
public byte[] PhotoDisplay { get; set; }
and create a new file called BytePhoto.cstml
in /Views/Shared/DisplayTemplates/
That file contents should look something like this
@model byte[]
@if (Model != null)
{
<img src="data:image;base64,@System.Convert.ToBase64String(Model)" />
} else {
<b>No image to display</b>
}
Then you could call this display template using @Html.DisplayFor(model => model.PhotoDisplay)
in your Razor files rather than <img src="data:image; base64, @System.Convert.ToBase64String(Model.PhotoDisplay)" />
.
If this is something you might do a lot you could go one step further and create a class that would encapsulate the byte array called something like BytePhoto
. Then you would not need the UIHint at all and the Razor markup would just work using the Display Templates.
Upvotes: 1
Reputation: 4443
Thanks, any better way to handle it controller side?
There is only one option, if you're passing from controller byte[] PhotoDisplay
, you have to validate that field on front side - as Stephen Muecke wrote in comment:
@if(Model.PhotoDisplay != null)
{
<img src="data:image;base64,@System.Convert.ToBase64String(Model.PhotoDisplay)" />
}
else
{
// some message
}
Otherwise, you can also do something like this at controller side:
private byte[] _photoDisplay
public byte[] PhotoDisplay {
get{
return _photoDisplay!=null?_photoDisplay:new byte[1];
}
set
{
_photoDisplay = value;
}
}
Upvotes: 0
Reputation: 11741
I guess putting nullable might help you as shown below :-
public byte[]? PhotoDisplay { get; set; }
or you can even code as below :-
[Column(TypeName = "image")]
public byte[] PhotoDisplay { get; set; }
Upvotes: 0