ASP.NET MVC中如何将JSON中的Base64字符串转为byte[]?
I see the core issue here: your front-end sends a JSON with a Base64-encoded image string, but your Models.Item class has a byte[] picture property. Newtonsoft.Json can't automatically convert a string to byte[] during deserialization unless you explicitly handle that conversion—this is why your current approach isn't working. Let's walk through a clear, robust fix:
Step 1: Create a DTO to Match the Request Structure
Instead of deserializing directly into your database-bound Models.Item, use a Data Transfer Object (DTO) that mirrors the JSON your front-end sends. This lets you safely handle the Base64 string before mapping to your entity:
public class ItemAddRequest { public string itemName { get; set; } public int itemQuantityStored { get; set; } public decimal itemPrice { get; set; } public int purchaseCount { get; set; } public string picture { get; set; } // Holds the Base64 string from the request public int isDeleted { get; set; } }
Note: I omitted itemID because it's likely an auto-generated primary key—your front-end shouldn't need to send this value.
Step 2: Update Your POST Action to Handle Conversion
Modify your addItem method to deserialize into the DTO, convert the Base64 string to byte[], then map values to your Models.Item entity:
[System.Web.Mvc.HttpPost] public ActionResult addItem() { try { // Retrieve the incoming JSON string var jsonString = Request.Form[0]; var itemRequest = Newtonsoft.Json.JsonConvert.DeserializeObject<ItemAddRequest>(jsonString); // Convert Base64 string to byte[] (handle common data URI prefixes) byte[] imageBytes = null; if (!string.IsNullOrEmpty(itemRequest.picture)) { // Remove prefix like "data:image/png;base64," if present var pureBase64 = itemRequest.picture.Split(',').Last(); imageBytes = Convert.FromBase64String(pureBase64); } // Map DTO values to your database entity using (var ctx = new Models.CangsODEntities4()) { Models.Item item = new Models.Item { itemName = itemRequest.itemName, itemQuantityStored = itemRequest.itemQuantityStored, itemPrice = itemRequest.itemPrice, purchaseCount = itemRequest.purchaseCount, picture = imageBytes, isDeleted = itemRequest.isDeleted }; ctx.Items.Add(item); ctx.SaveChanges(); Response.StatusCode = 200; return Content(item.itemID.ToString()); } } catch (FormatException ex) { // Handle invalid Base64 format errors Response.StatusCode = 400; return Content("Invalid image format: " + ex.Message); } catch (Exception ex) { // Catch other unexpected issues (database errors, etc.) Response.StatusCode = 500; return Content("Error adding item: " + ex.Message); } }
Key Details to Note:
- Base64 Prefix Handling: Many front-ends send Base64 strings with a
data:image/xxx;base64,prefix. The code splits this string and uses only the pure Base64 data, which is required forConvert.FromBase64Stringto work correctly. - Error Handling: Added try/catch blocks to gracefully handle invalid image data and other unexpected errors, making your API more reliable.
- Using
usingfor Context: Wrapped your database context in ausingstatement to ensure it's disposed properly, preventing resource leaks.
Alternative: Custom JsonConverter (Direct Deserialization)
If you prefer to skip the DTO and deserialize directly into Models.Item, create a custom converter to handle the Base64-to-byte[] conversion automatically:
public class Base64ByteArrayConverter : Newtonsoft.Json.JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(byte[]); } public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) { var base64String = reader.Value as string; if (string.IsNullOrEmpty(base64String)) return null; // Strip data URI prefix if present var pureBase64 = base64String.Split(',').Last(); return Convert.FromBase64String(pureBase64); } public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) { // Optional: Serialize byte[] back to Base64 if needed var bytes = value as byte[]; writer.WriteValue(bytes != null ? Convert.ToBase64String(bytes) : null); } }
Then apply the converter to your picture property in Models.Item:
public class Item { public int itemID { get; set; } public string itemName { get; set; } public int itemQuantityStored { get; set; } public decimal itemPrice { get; set; } public int purchaseCount { get; set; } [Newtonsoft.Json.JsonConverter(typeof(Base64ByteArrayConverter))] public byte[] picture { get; set; } public int isDeleted { get; set; } }
With this converter in place, your original deserialization code will work—Newtonsoft.Json will automatically convert the Base64 string to byte[] during deserialization.
内容的提问来源于stack exchange,提问作者tad00

